1 /*
2  * e-mail-label-manager.c
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  *
16  *
17  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
18  *
19  */
20 
21 #include "evolution-config.h"
22 
23 #include "e-mail-label-manager.h"
24 
25 #include <glib/gi18n.h>
26 #include <e-util/e-util.h>
27 
28 #include "e-mail-label-dialog.h"
29 #include "e-mail-label-tree-view.h"
30 
31 #define E_MAIL_LABEL_MANAGER_GET_PRIVATE(obj) \
32 	(G_TYPE_INSTANCE_GET_PRIVATE \
33 	((obj), E_TYPE_MAIL_LABEL_MANAGER, EMailLabelManagerPrivate))
34 
35 struct _EMailLabelManagerPrivate {
36 	GtkWidget *tree_view;
37 	GtkWidget *add_button;
38 	GtkWidget *edit_button;
39 	GtkWidget *remove_button;
40 };
41 
42 enum {
43 	PROP_0,
44 	PROP_LIST_STORE
45 };
46 
47 enum {
48 	ADD_LABEL,
49 	EDIT_LABEL,
50 	REMOVE_LABEL,
51 	LAST_SIGNAL
52 };
53 
54 static guint signals[LAST_SIGNAL];
55 
G_DEFINE_TYPE(EMailLabelManager,e_mail_label_manager,GTK_TYPE_TABLE)56 G_DEFINE_TYPE (EMailLabelManager, e_mail_label_manager, GTK_TYPE_TABLE)
57 
58 static void
59 mail_label_manager_selection_changed_cb (EMailLabelManager *manager,
60                                          GtkTreeSelection *selection)
61 {
62 	GtkWidget *edit_button;
63 	GtkWidget *remove_button;
64 	GtkTreeModel *model;
65 	GtkTreeIter iter;
66 
67 	edit_button = manager->priv->edit_button;
68 	remove_button = manager->priv->remove_button;
69 
70 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
71 		EMailLabelListStore *store;
72 		gboolean sensitive;
73 		gchar *label_tag;
74 
75 		store = E_MAIL_LABEL_LIST_STORE (model);
76 		label_tag = e_mail_label_list_store_get_tag (store, &iter);
77 		sensitive = !e_mail_label_tag_is_default (label_tag);
78 		g_free (label_tag);
79 
80 		/* Disallow removing default labels. */
81 		gtk_widget_set_sensitive (edit_button, TRUE);
82 		gtk_widget_set_sensitive (remove_button, sensitive);
83 	} else {
84 		gtk_widget_set_sensitive (edit_button, FALSE);
85 		gtk_widget_set_sensitive (remove_button, FALSE);
86 	}
87 }
88 
89 static void
mail_label_manager_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)90 mail_label_manager_set_property (GObject *object,
91                                  guint property_id,
92                                  const GValue *value,
93                                  GParamSpec *pspec)
94 {
95 	switch (property_id) {
96 		case PROP_LIST_STORE:
97 			e_mail_label_manager_set_list_store (
98 				E_MAIL_LABEL_MANAGER (object),
99 				g_value_get_object (value));
100 			return;
101 	}
102 
103 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
104 }
105 
106 static void
mail_label_manager_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)107 mail_label_manager_get_property (GObject *object,
108                                  guint property_id,
109                                  GValue *value,
110                                  GParamSpec *pspec)
111 {
112 	switch (property_id) {
113 		case PROP_LIST_STORE:
114 			g_value_set_object (
115 				value, e_mail_label_manager_get_list_store (
116 				E_MAIL_LABEL_MANAGER (object)));
117 			return;
118 	}
119 
120 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
121 }
122 
123 static void
mail_label_manager_dispose(GObject * object)124 mail_label_manager_dispose (GObject *object)
125 {
126 	EMailLabelManagerPrivate *priv;
127 
128 	priv = E_MAIL_LABEL_MANAGER_GET_PRIVATE (object);
129 	g_clear_object (&priv->tree_view);
130 	g_clear_object (&priv->add_button);
131 	g_clear_object (&priv->edit_button);
132 	g_clear_object (&priv->remove_button);
133 
134 	/* Chain up to parent's dispose() method. */
135 	G_OBJECT_CLASS (e_mail_label_manager_parent_class)->dispose (object);
136 }
137 
138 static void
mail_label_manager_add_label(EMailLabelManager * manager)139 mail_label_manager_add_label (EMailLabelManager *manager)
140 {
141 	EMailLabelDialog *label_dialog;
142 	GtkTreeView *tree_view;
143 	GtkTreeModel *model;
144 	GtkWidget *dialog;
145 	gpointer parent;
146 	GdkColor label_color;
147 	const gchar *label_name;
148 
149 	parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
150 	parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
151 	dialog = e_mail_label_dialog_new (parent);
152 
153 	gtk_window_set_title (GTK_WINDOW (dialog), _("Add Label"));
154 
155 	if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
156 		goto exit;
157 
158 	label_dialog = E_MAIL_LABEL_DIALOG (dialog);
159 	label_name = e_mail_label_dialog_get_label_name (label_dialog);
160 	e_mail_label_dialog_get_label_color (label_dialog, &label_color);
161 
162 	tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
163 	model = gtk_tree_view_get_model (tree_view);
164 
165 	e_mail_label_list_store_set (
166 		E_MAIL_LABEL_LIST_STORE (model),
167 		NULL, label_name, &label_color);
168 
169 exit:
170 	gtk_widget_destroy (dialog);
171 }
172 
173 static void
mail_label_manager_edit_label(EMailLabelManager * manager)174 mail_label_manager_edit_label (EMailLabelManager *manager)
175 {
176 	EMailLabelDialog *label_dialog;
177 	EMailLabelListStore *label_store;
178 	GtkTreeSelection *selection;
179 	GtkTreeView *tree_view;
180 	GtkTreeModel *model;
181 	GtkTreeIter iter;
182 	GtkWidget *dialog;
183 	GtkWidget *parent;
184 	GdkColor label_color;
185 	const gchar *new_name;
186 	gchar *label_name;
187 
188 	tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
189 	selection = gtk_tree_view_get_selection (tree_view);
190 
191 	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
192 		return;
193 
194 	label_store = E_MAIL_LABEL_LIST_STORE (model);
195 	label_name = e_mail_label_list_store_get_name (label_store, &iter);
196 	e_mail_label_list_store_get_color (label_store, &iter, &label_color);
197 
198 	parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
199 	dialog = e_mail_label_dialog_new (GTK_WINDOW (parent));
200 	label_dialog = E_MAIL_LABEL_DIALOG (dialog);
201 
202 	e_mail_label_dialog_set_label_name (label_dialog, label_name);
203 	e_mail_label_dialog_set_label_color (label_dialog, &label_color);
204 	gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Label"));
205 
206 	if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
207 		goto exit;
208 
209 	new_name = e_mail_label_dialog_get_label_name (label_dialog);
210 	e_mail_label_dialog_get_label_color (label_dialog, &label_color);
211 
212 	e_mail_label_list_store_set (
213 		label_store, &iter, new_name, &label_color);
214 
215 exit:
216 	gtk_widget_destroy (dialog);
217 
218 	g_free (label_name);
219 }
220 
221 static void
mail_label_manager_remove_label(EMailLabelManager * manager)222 mail_label_manager_remove_label (EMailLabelManager *manager)
223 {
224 	GtkTreeSelection *selection;
225 	GtkTreeView *tree_view;
226 	GtkTreeModel *model;
227 	GtkTreeIter iter;
228 
229 	tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
230 	selection = gtk_tree_view_get_selection (tree_view);
231 
232 	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
233 		return;
234 
235 	gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
236 }
237 
238 static void
e_mail_label_manager_class_init(EMailLabelManagerClass * class)239 e_mail_label_manager_class_init (EMailLabelManagerClass *class)
240 {
241 	GObjectClass *object_class;
242 
243 	g_type_class_add_private (class, sizeof (EMailLabelManagerPrivate));
244 
245 	object_class = G_OBJECT_CLASS (class);
246 	object_class->set_property = mail_label_manager_set_property;
247 	object_class->get_property = mail_label_manager_get_property;
248 	object_class->dispose = mail_label_manager_dispose;
249 
250 	class->add_label = mail_label_manager_add_label;
251 	class->edit_label = mail_label_manager_edit_label;
252 	class->remove_label = mail_label_manager_remove_label;
253 
254 	g_object_class_install_property (
255 		object_class,
256 		PROP_LIST_STORE,
257 		g_param_spec_object (
258 			"list-store",
259 			"List Store",
260 			NULL,
261 			E_TYPE_MAIL_LABEL_LIST_STORE,
262 			G_PARAM_READWRITE));
263 
264 	signals[ADD_LABEL] = g_signal_new (
265 		"add-label",
266 		G_OBJECT_CLASS_TYPE (class),
267 		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
268 		G_STRUCT_OFFSET (EMailLabelManagerClass, add_label),
269 		NULL, NULL,
270 		g_cclosure_marshal_VOID__VOID,
271 		G_TYPE_NONE, 0);
272 
273 	signals[EDIT_LABEL] = g_signal_new (
274 		"edit-label",
275 		G_OBJECT_CLASS_TYPE (class),
276 		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
277 		G_STRUCT_OFFSET (EMailLabelManagerClass, edit_label),
278 		NULL, NULL,
279 		g_cclosure_marshal_VOID__VOID,
280 		G_TYPE_NONE, 0);
281 
282 	signals[REMOVE_LABEL] = g_signal_new (
283 		"remove-label",
284 		G_OBJECT_CLASS_TYPE (class),
285 		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
286 		G_STRUCT_OFFSET (EMailLabelManagerClass, remove_label),
287 		NULL, NULL,
288 		g_cclosure_marshal_VOID__VOID,
289 		G_TYPE_NONE, 0);
290 }
291 
292 static void
e_mail_label_manager_init(EMailLabelManager * manager)293 e_mail_label_manager_init (EMailLabelManager *manager)
294 {
295 	GtkTreeSelection *selection;
296 	GtkWidget *container;
297 	GtkWidget *widget;
298 
299 	manager->priv = E_MAIL_LABEL_MANAGER_GET_PRIVATE (manager);
300 
301 	gtk_table_resize (GTK_TABLE (manager), 2, 2);
302 	gtk_table_set_col_spacings (GTK_TABLE (manager), 6);
303 	gtk_table_set_row_spacings (GTK_TABLE (manager), 12);
304 
305 	container = GTK_WIDGET (manager);
306 
307 	widget = gtk_scrolled_window_new (NULL, NULL);
308 	gtk_scrolled_window_set_policy (
309 		GTK_SCROLLED_WINDOW (widget),
310 		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
311 	gtk_scrolled_window_set_shadow_type (
312 		GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
313 	gtk_table_attach (
314 		GTK_TABLE (container), widget, 0, 1, 0, 1,
315 		GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
316 	gtk_widget_show (widget);
317 
318 	container = widget;
319 
320 	widget = e_mail_label_tree_view_new ();
321 	gtk_container_add (GTK_CONTAINER (container), widget);
322 	manager->priv->tree_view = g_object_ref (widget);
323 	gtk_widget_show (widget);
324 
325 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
326 
327 	g_signal_connect_swapped (
328 		selection, "changed",
329 		G_CALLBACK (mail_label_manager_selection_changed_cb),
330 		manager);
331 
332 	container = GTK_WIDGET (manager);
333 
334 	/* FIXME Clarify this.  What menu? */
335 	widget = gtk_label_new (
336 		_("Note: Underscore in the label name is used\n"
337 		"as mnemonic identifier in menu."));
338 	gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_CENTER);
339 	gtk_table_attach (
340 		GTK_TABLE (container), widget,
341 		0, 1, 1, 2, 0, 0, 0, 0);
342 	gtk_widget_show (widget);
343 
344 	widget = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
345 	gtk_button_box_set_layout (
346 		GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
347 	gtk_box_set_spacing (GTK_BOX (widget), 6);
348 	gtk_table_attach (
349 		GTK_TABLE (container), widget,
350 		1, 2, 0, 2, 0, GTK_FILL, 0, 0);
351 	gtk_widget_show (widget);
352 
353 	container = widget;
354 
355 	widget = e_dialog_button_new_with_icon ("list-add", _("_Add"));
356 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
357 	manager->priv->add_button = g_object_ref (widget);
358 	gtk_widget_show (widget);
359 
360 	g_signal_connect_swapped (
361 		widget, "clicked",
362 		G_CALLBACK (e_mail_label_manager_add_label), manager);
363 
364 	widget = gtk_button_new_with_mnemonic (_("_Edit"));
365 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
366 	manager->priv->edit_button = g_object_ref (widget);
367 	gtk_widget_show (widget);
368 
369 	g_signal_connect_swapped (
370 		widget, "clicked",
371 		G_CALLBACK (e_mail_label_manager_edit_label), manager);
372 
373 	widget = e_dialog_button_new_with_icon ("list-remove", _("_Remove"));
374 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
375 	manager->priv->remove_button = g_object_ref (widget);
376 	gtk_widget_show (widget);
377 
378 	g_signal_connect_swapped (
379 		widget, "clicked",
380 		G_CALLBACK (e_mail_label_manager_remove_label), manager);
381 }
382 
383 GtkWidget *
e_mail_label_manager_new(void)384 e_mail_label_manager_new (void)
385 {
386 	return g_object_new (E_TYPE_MAIL_LABEL_MANAGER, NULL);
387 }
388 
389 void
e_mail_label_manager_add_label(EMailLabelManager * manager)390 e_mail_label_manager_add_label (EMailLabelManager *manager)
391 {
392 	g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
393 
394 	g_signal_emit (manager, signals[ADD_LABEL], 0);
395 }
396 
397 void
e_mail_label_manager_edit_label(EMailLabelManager * manager)398 e_mail_label_manager_edit_label (EMailLabelManager *manager)
399 {
400 	g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
401 
402 	g_signal_emit (manager, signals[EDIT_LABEL], 0);
403 }
404 
405 void
e_mail_label_manager_remove_label(EMailLabelManager * manager)406 e_mail_label_manager_remove_label (EMailLabelManager *manager)
407 {
408 	g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
409 
410 	g_signal_emit (manager, signals[REMOVE_LABEL], 0);
411 }
412 
413 EMailLabelListStore *
e_mail_label_manager_get_list_store(EMailLabelManager * manager)414 e_mail_label_manager_get_list_store (EMailLabelManager *manager)
415 {
416 	GtkTreeView *tree_view;
417 	GtkTreeModel *model;
418 
419 	g_return_val_if_fail (E_IS_MAIL_LABEL_MANAGER (manager), NULL);
420 
421 	tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
422 	model = gtk_tree_view_get_model (tree_view);
423 
424 	return E_MAIL_LABEL_LIST_STORE (model);
425 }
426 
427 void
e_mail_label_manager_set_list_store(EMailLabelManager * manager,EMailLabelListStore * list_store)428 e_mail_label_manager_set_list_store (EMailLabelManager *manager,
429                                      EMailLabelListStore *list_store)
430 {
431 	GtkTreeView *tree_view;
432 
433 	g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
434 	g_return_if_fail (E_IS_MAIL_LABEL_LIST_STORE (list_store));
435 
436 	tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
437 	gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store));
438 
439 	g_object_notify (G_OBJECT (manager), "list-store");
440 }
441