No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Jeffrey Stedfast <fejj@ximian.com>
18 *
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <string.h>
28 #include <glib/gi18n.h>
29 #include <e-util/e-util.h>
30
31 #include <libemail-engine/e-mail-folder-utils.h>
32
33 #include "em-folder-tree.h"
34 #include "em-folder-selector.h"
35 #include "em-utils.h"
36
37 #include "em-folder-selection-button.h"
38
39 #define EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE(obj) \
40 (G_TYPE_INSTANCE_GET_PRIVATE \
41 ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButtonPrivate))
42
43 struct _EMFolderSelectionButtonPrivate {
44 EMailSession *session;
45 GtkWidget *icon;
46 GtkWidget *label;
47 CamelStore *store;
48
49 gchar *title;
50 gchar *caption;
51 gchar *folder_uri;
52 };
53
54 enum {
55 PROP_0,
56 PROP_CAPTION,
57 PROP_FOLDER_URI,
58 PROP_SESSION,
59 PROP_STORE,
60 PROP_TITLE
61 };
62
63 enum {
64 SELECTED,
65 LAST_SIGNAL
66 };
67
68 static guint signals[LAST_SIGNAL];
69
70 G_DEFINE_TYPE (
71 EMFolderSelectionButton,
72 em_folder_selection_button,
73 GTK_TYPE_BUTTON)
74
75 static void
76 folder_selection_button_unselected (EMFolderSelectionButton *button)
77 {
78 const gchar *text;
79
80 text = _("<click here to select a folder>");
81 gtk_image_set_from_pixbuf (GTK_IMAGE (button->priv->icon), NULL);
82 gtk_label_set_text (GTK_LABEL (button->priv->label), text);
83 }
84
85 static void
86 folder_selection_button_set_contents (EMFolderSelectionButton *button)
87 {
88 EMailSession *session;
89 CamelStore *store = NULL;
90 CamelService *service;
91 GtkLabel *label;
92 const gchar *display_name;
93 gchar *folder_name = NULL;
94
95 label = GTK_LABEL (button->priv->label);
96 session = em_folder_selection_button_get_session (button);
97
98 if (session != NULL && button->priv->folder_uri != NULL)
99 e_mail_folder_uri_parse (
100 CAMEL_SESSION (session),
101 button->priv->folder_uri,
102 &store, &folder_name, NULL);
103
104 if (store == NULL || folder_name == NULL) {
105 folder_selection_button_unselected (button);
106 return;
107 }
108
109 service = CAMEL_SERVICE (store);
110 display_name = camel_service_get_display_name (service);
111
112 if (display_name != NULL) {
113 gchar *text;
114
115 text = g_strdup_printf (
116 "%s/%s", display_name, _(folder_name));
117 gtk_label_set_text (label, text);
118 g_free (text);
119 } else
120 gtk_label_set_text (label, _(folder_name));
121
122 g_object_unref (store);
123 g_free (folder_name);
124 }
125
126 static void
127 folder_selection_button_set_property (GObject *object,
128 guint property_id,
129 const GValue *value,
130 GParamSpec *pspec)
131 {
132 switch (property_id) {
133 case PROP_CAPTION:
134 em_folder_selection_button_set_caption (
135 EM_FOLDER_SELECTION_BUTTON (object),
136 g_value_get_string (value));
137 return;
138
139 case PROP_FOLDER_URI:
140 em_folder_selection_button_set_folder_uri (
141 EM_FOLDER_SELECTION_BUTTON (object),
142 g_value_get_string (value));
143 return;
144
145 case PROP_SESSION:
146 em_folder_selection_button_set_session (
147 EM_FOLDER_SELECTION_BUTTON (object),
148 g_value_get_object (value));
149 return;
150
151 case PROP_STORE:
152 em_folder_selection_button_set_store (
153 EM_FOLDER_SELECTION_BUTTON (object),
154 g_value_get_object (value));
155 return;
156
157 case PROP_TITLE:
158 em_folder_selection_button_set_title (
159 EM_FOLDER_SELECTION_BUTTON (object),
160 g_value_get_string (value));
161 return;
162 }
163
164 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
165 }
166
167 static void
168 folder_selection_button_get_property (GObject *object,
169 guint property_id,
170 GValue *value,
171 GParamSpec *pspec)
172 {
173 switch (property_id) {
174 case PROP_CAPTION:
175 g_value_set_string (
176 value,
177 em_folder_selection_button_get_caption (
178 EM_FOLDER_SELECTION_BUTTON (object)));
179 return;
180
181 case PROP_FOLDER_URI:
182 g_value_set_string (
183 value,
184 em_folder_selection_button_get_folder_uri (
185 EM_FOLDER_SELECTION_BUTTON (object)));
186 return;
187
188 case PROP_SESSION:
189 g_value_set_object (
190 value,
191 em_folder_selection_button_get_session (
192 EM_FOLDER_SELECTION_BUTTON (object)));
193 return;
194
195 case PROP_STORE:
196 g_value_set_object (
197 value,
198 em_folder_selection_button_get_store (
199 EM_FOLDER_SELECTION_BUTTON (object)));
200 return;
201
202 case PROP_TITLE:
203 g_value_set_string (
204 value,
205 em_folder_selection_button_get_title (
206 EM_FOLDER_SELECTION_BUTTON (object)));
207 return;
208 }
209
210 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
211 }
212
213 static void
214 folder_selection_button_dispose (GObject *object)
215 {
216 EMFolderSelectionButtonPrivate *priv;
217
218 priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (object);
219
220 if (priv->session != NULL) {
221 g_object_unref (priv->session);
222 priv->session = NULL;
223 }
224
225 if (priv->store != NULL) {
226 g_object_unref (priv->store);
227 priv->store = NULL;
228 }
229
230 /* Chain up to parent's dispose() method. */
231 G_OBJECT_CLASS (em_folder_selection_button_parent_class)->
232 dispose (object);
233 }
234
235 static void
236 folder_selection_button_finalize (GObject *object)
237 {
238 EMFolderSelectionButtonPrivate *priv;
239
240 priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (object);
241
242 g_free (priv->title);
243 g_free (priv->caption);
244 g_free (priv->folder_uri);
245
246 /* Chain up to parent's finalize() method. */
247 G_OBJECT_CLASS (em_folder_selection_button_parent_class)->
248 finalize (object);
249 }
250
251 static void
252 folder_selection_button_clicked (GtkButton *button)
253 {
254 EMFolderSelectionButtonPrivate *priv;
255 EMFolderSelector *selector;
256 EMFolderTree *folder_tree;
257 EMFolderTreeModel *model = NULL;
258 GtkWidget *dialog;
259 GtkTreeSelection *selection;
260 gpointer parent;
261
262 priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (button);
263
264 parent = gtk_widget_get_toplevel (GTK_WIDGET (button));
265 parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
266
267 if (priv->store != NULL) {
268 model = em_folder_tree_model_new ();
269 em_folder_tree_model_set_session (model, priv->session);
270 em_folder_tree_model_add_store (model, priv->store);
271 }
272
273 if (model == NULL)
274 model = g_object_ref (em_folder_tree_model_get_default ());
275
276 dialog = em_folder_selector_new (
277 parent, model,
278 EM_FOLDER_SELECTOR_CAN_CREATE,
279 priv->title, priv->caption, NULL);
280
281 g_object_unref (model);
282
283 selector = EM_FOLDER_SELECTOR (dialog);
284 folder_tree = em_folder_selector_get_folder_tree (selector);
285
286 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree));
287 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
288
289 em_folder_tree_set_excluded (
290 folder_tree,
291 EMFT_EXCLUDE_NOSELECT |
292 EMFT_EXCLUDE_VIRTUAL |
293 EMFT_EXCLUDE_VTRASH);
294
295 em_folder_tree_set_selected (folder_tree, priv->folder_uri, FALSE);
296
297 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
298 const gchar *uri;
299
300 uri = em_folder_selector_get_selected_uri (selector);
301 em_folder_selection_button_set_folder_uri (
302 EM_FOLDER_SELECTION_BUTTON (button), uri);
303
304 g_signal_emit (button, signals[SELECTED], 0);
305 }
306
307 gtk_widget_destroy (dialog);
308 }
309
310 static void
311 em_folder_selection_button_class_init (EMFolderSelectionButtonClass *class)
312 {
313 GObjectClass *object_class;
314 GtkButtonClass *button_class;
315
316 g_type_class_add_private (class, sizeof (EMFolderSelectionButtonPrivate));
317
318 object_class = G_OBJECT_CLASS (class);
319 object_class->set_property = folder_selection_button_set_property;
320 object_class->get_property = folder_selection_button_get_property;
321 object_class->dispose = folder_selection_button_dispose;
322 object_class->finalize = folder_selection_button_finalize;
323
324 button_class = GTK_BUTTON_CLASS (class);
325 button_class->clicked = folder_selection_button_clicked;
326
327 g_object_class_install_property (
328 object_class,
329 PROP_CAPTION,
330 g_param_spec_string (
331 "caption",
332 NULL,
333 NULL,
334 NULL,
335 G_PARAM_READWRITE |
336 G_PARAM_CONSTRUCT));
337
338 g_object_class_install_property (
339 object_class,
340 PROP_FOLDER_URI,
341 g_param_spec_string (
342 "folder-uri",
343 NULL,
344 NULL,
345 NULL,
346 G_PARAM_READWRITE |
347 G_PARAM_CONSTRUCT));
348
349 g_object_class_install_property (
350 object_class,
351 PROP_SESSION,
352 g_param_spec_object (
353 "session",
354 NULL,
355 NULL,
356 E_TYPE_MAIL_SESSION,
357 G_PARAM_READWRITE |
358 G_PARAM_CONSTRUCT));
359
360 g_object_class_install_property (
361 object_class,
362 PROP_STORE,
363 g_param_spec_object (
364 "store",
365 NULL,
366 NULL,
367 CAMEL_TYPE_STORE,
368 G_PARAM_READWRITE));
369
370 g_object_class_install_property (
371 object_class,
372 PROP_TITLE,
373 g_param_spec_string (
374 "title",
375 NULL,
376 NULL,
377 NULL,
378 G_PARAM_READWRITE |
379 G_PARAM_CONSTRUCT));
380
381 signals[SELECTED] = g_signal_new (
382 "selected",
383 G_OBJECT_CLASS_TYPE (object_class),
384 G_SIGNAL_RUN_FIRST,
385 G_STRUCT_OFFSET (EMFolderSelectionButtonClass, selected),
386 NULL, NULL,
387 g_cclosure_marshal_VOID__VOID,
388 G_TYPE_NONE, 0);
389 }
390
391 static void
392 em_folder_selection_button_init (EMFolderSelectionButton *emfsb)
393 {
394 GtkWidget *box;
395
396 emfsb->priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (emfsb);
397
398 box = gtk_hbox_new (FALSE, 4);
399 gtk_container_add (GTK_CONTAINER (emfsb), box);
400 gtk_widget_show (box);
401
402 emfsb->priv->icon = gtk_image_new ();
403 gtk_box_pack_start (GTK_BOX (box), emfsb->priv->icon, FALSE, TRUE, 0);
404 gtk_widget_show (emfsb->priv->icon);
405
406 emfsb->priv->label = gtk_label_new ("");
407 gtk_label_set_justify (GTK_LABEL (emfsb->priv->label), GTK_JUSTIFY_LEFT);
408 gtk_misc_set_alignment (GTK_MISC (emfsb->priv->label), 0.0, 0.5);
409 gtk_box_pack_start (GTK_BOX (box), emfsb->priv->label, TRUE, TRUE, 0);
410 gtk_widget_show (emfsb->priv->label);
411
412 folder_selection_button_set_contents (emfsb);
413 }
414
415 GtkWidget *
416 em_folder_selection_button_new (EMailSession *session,
417 const gchar *title,
418 const gchar *caption)
419 {
420 g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
421
422 return g_object_new (
423 EM_TYPE_FOLDER_SELECTION_BUTTON,
424 "session", session, "title", title,
425 "caption", caption, NULL);
426 }
427
428 EMailSession *
429 em_folder_selection_button_get_session (EMFolderSelectionButton *button)
430 {
431 g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
432
433 return button->priv->session;
434 }
435
436 void
437 em_folder_selection_button_set_session (EMFolderSelectionButton *button,
438 EMailSession *session)
439 {
440 g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
441
442 if (button->priv->session == session)
443 return;
444
445 if (session != NULL) {
446 g_return_if_fail (E_IS_MAIL_SESSION (session));
447 g_object_ref (session);
448 }
449
450 if (button->priv->session != NULL)
451 g_object_unref (button->priv->session);
452
453 button->priv->session = session;
454
455 g_object_notify (G_OBJECT (button), "session");
456 }
457
458 const gchar *
459 em_folder_selection_button_get_caption (EMFolderSelectionButton *button)
460 {
461 g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
462
463 return button->priv->caption;
464 }
465
466 void
467 em_folder_selection_button_set_caption (EMFolderSelectionButton *button,
468 const gchar *caption)
469 {
470 g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
471
472 if (g_strcmp0 (button->priv->caption, caption) == 0)
473 return;
474
475 g_free (button->priv->caption);
476 button->priv->caption = g_strdup (caption);
477
478 g_object_notify (G_OBJECT (button), "caption");
479 }
480
481 const gchar *
482 em_folder_selection_button_get_folder_uri (EMFolderSelectionButton *button)
483 {
484 g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
485
486 return button->priv->folder_uri;
487 }
488
489 void
490 em_folder_selection_button_set_folder_uri (EMFolderSelectionButton *button,
491 const gchar *folder_uri)
492 {
493 g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
494
495 /* An empty string is equivalent to NULL. */
496 if (folder_uri != NULL && *folder_uri == '\0')
497 folder_uri = NULL;
498
499 if (g_strcmp0 (button->priv->folder_uri, folder_uri) == 0)
500 return;
501
502 g_free (button->priv->folder_uri);
503 button->priv->folder_uri = g_strdup (folder_uri);
504
505 folder_selection_button_set_contents (button);
506
507 g_object_notify (G_OBJECT (button), "folder-uri");
508 }
509
510 CamelStore *
511 em_folder_selection_button_get_store (EMFolderSelectionButton *button)
512 {
513 g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
514
515 return button->priv->store;
516 }
517
518 void
519 em_folder_selection_button_set_store (EMFolderSelectionButton *button,
520 CamelStore *store)
521 {
522 g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
523
524 if (button->priv->store == store)
525 return;
526
527 if (store != NULL) {
528 g_return_if_fail (CAMEL_IS_STORE (store));
529 g_object_ref (store);
530 }
531
532 if (button->priv->store != NULL)
533 g_object_unref (button->priv->store);
534
535 button->priv->store = store;
536
537 g_object_notify (G_OBJECT (button), "store");
538 }
539
540 const gchar *
541 em_folder_selection_button_get_title (EMFolderSelectionButton *button)
542 {
543 g_return_val_if_fail (EM_FOLDER_SELECTION_BUTTON (button), NULL);
544
545 return button->priv->title;
546 }
547
548 void
549 em_folder_selection_button_set_title (EMFolderSelectionButton *button,
550 const gchar *title)
551 {
552 g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
553
554 if (g_strcmp0 (button->priv->title, title) == 0)
555 return;
556
557 g_free (button->priv->title);
558 button->priv->title = g_strdup (title);
559
560 g_object_notify (G_OBJECT (button), "title");
561 }