1 /*
2 * e-mail-config-provider-page.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
18 #include "evolution-config.h"
19
20 #include <string.h>
21 #include <glib/gi18n-lib.h>
22
23 #include <libebackend/libebackend.h>
24
25 #include "e-mail-config-provider-page.h"
26
27 #define E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE(obj) \
28 (G_TYPE_INSTANCE_GET_PRIVATE \
29 ((obj), E_TYPE_MAIL_CONFIG_PROVIDER_PAGE, EMailConfigProviderPagePrivate))
30
31 #define STANDARD_MARGIN 12
32 #define DEPENDENCY_MARGIN 24
33
34 struct _EMailConfigProviderPagePrivate {
35 EMailConfigServiceBackend *backend;
36 gboolean is_empty;
37 };
38
39 enum {
40 PROP_0,
41 PROP_BACKEND
42 };
43
44 /* Forward Declarations */
45 static void e_mail_config_provider_page_interface_init
46 (EMailConfigPageInterface *iface);
47
G_DEFINE_TYPE_WITH_CODE(EMailConfigProviderPage,e_mail_config_provider_page,E_TYPE_MAIL_CONFIG_ACTIVITY_PAGE,G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE,NULL)G_IMPLEMENT_INTERFACE (E_TYPE_MAIL_CONFIG_PAGE,e_mail_config_provider_page_interface_init))48 G_DEFINE_TYPE_WITH_CODE (
49 EMailConfigProviderPage,
50 e_mail_config_provider_page,
51 E_TYPE_MAIL_CONFIG_ACTIVITY_PAGE,
52 G_IMPLEMENT_INTERFACE (
53 E_TYPE_EXTENSIBLE, NULL)
54 G_IMPLEMENT_INTERFACE (
55 E_TYPE_MAIL_CONFIG_PAGE,
56 e_mail_config_provider_page_interface_init))
57
58 static void
59 mail_config_provider_page_handle_dependency (EMailConfigProviderPage *page,
60 CamelProviderConfEntry *entry,
61 GtkWidget *widget)
62 {
63 EMailConfigServiceBackend *backend;
64 CamelSettings *settings;
65 GBindingFlags binding_flags = G_BINDING_SYNC_CREATE;
66 const gchar *depname = entry->depname;
67 gint margin;
68
69 if (depname == NULL)
70 return;
71
72 if (*depname == '!') {
73 binding_flags |= G_BINDING_INVERT_BOOLEAN;
74 depname++;
75 }
76
77 backend = e_mail_config_provider_page_get_backend (page);
78 settings = e_mail_config_service_backend_get_settings (backend);
79
80 e_binding_bind_property (
81 settings, depname,
82 widget, "sensitive",
83 binding_flags);
84
85 /* Further indent the widget to show its dependency. */
86 margin = gtk_widget_get_margin_left (widget);
87 gtk_widget_set_margin_left (widget, margin + DEPENDENCY_MARGIN);
88 }
89
90 static void
mail_config_provider_page_add_section(EMailConfigProviderPage * page,GtkBox * main_box,CamelProviderConfEntry * entry)91 mail_config_provider_page_add_section (EMailConfigProviderPage *page,
92 GtkBox *main_box,
93 CamelProviderConfEntry *entry)
94 {
95 EMailConfigServiceBackend *backend;
96 CamelProvider *provider;
97 GtkWidget *widget;
98 gchar *markup;
99
100 g_return_if_fail (entry->text != NULL);
101
102 backend = e_mail_config_provider_page_get_backend (page);
103 provider = e_mail_config_service_backend_get_provider (backend);
104
105 markup = g_markup_printf_escaped ("<b>%s</b>", entry->text);
106
107 widget = gtk_label_new (markup);
108 gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
109 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
110 gtk_box_pack_start (main_box, widget, FALSE, FALSE, 0);
111 gtk_widget_show (widget);
112
113 /* Skip the top margin if this is the first entry. */
114 if (entry != provider->extra_conf)
115 gtk_widget_set_margin_top (widget, 6);
116
117 g_free (markup);
118 }
119
120 static void
mail_config_provider_page_add_checkbox(EMailConfigProviderPage * page,GtkBox * main_box,CamelProviderConfEntry * entry)121 mail_config_provider_page_add_checkbox (EMailConfigProviderPage *page,
122 GtkBox *main_box,
123 CamelProviderConfEntry *entry)
124 {
125 EMailConfigServiceBackend *backend;
126 CamelSettings *settings;
127 GtkWidget *widget;
128
129 g_return_if_fail (entry->text != NULL);
130
131 backend = e_mail_config_provider_page_get_backend (page);
132 settings = e_mail_config_service_backend_get_settings (backend);
133
134 widget = gtk_check_button_new_with_mnemonic (entry->text);
135 gtk_widget_set_margin_left (widget, STANDARD_MARGIN);
136 gtk_box_pack_start (main_box, widget, FALSE, FALSE, 0);
137 gtk_widget_show (widget);
138
139 e_binding_bind_property (
140 settings, entry->name,
141 widget, "active",
142 G_BINDING_BIDIRECTIONAL |
143 G_BINDING_SYNC_CREATE);
144
145 mail_config_provider_page_handle_dependency (page, entry, widget);
146 }
147
148 static void
mail_config_provider_page_add_checkspin(EMailConfigProviderPage * page,GtkBox * main_box,CamelProviderConfEntry * entry)149 mail_config_provider_page_add_checkspin (EMailConfigProviderPage *page,
150 GtkBox *main_box,
151 CamelProviderConfEntry *entry)
152 {
153 EMailConfigServiceBackend *backend;
154 CamelSettings *settings;
155 GObjectClass *class;
156 GParamSpec *pspec;
157 GParamSpec *use_pspec;
158 GtkAdjustment *adjustment;
159 GtkWidget *hbox, *spin;
160 GtkWidget *prefix;
161 gchar *use_property_name;
162 gchar *pre, *post;
163
164 g_return_if_fail (entry->text != NULL);
165
166 backend = e_mail_config_provider_page_get_backend (page);
167 settings = e_mail_config_service_backend_get_settings (backend);
168
169 /* The entry->name property (e.g. "foo") should be numeric for the
170 * spin button. If a "use" boolean property exists (e.g. "use-foo")
171 * then a checkbox is also shown. */
172
173 class = G_OBJECT_GET_CLASS (settings);
174 pspec = g_object_class_find_property (class, entry->name);
175 g_return_if_fail (pspec != NULL);
176
177 use_property_name = g_strconcat ("use-", entry->name, NULL);
178 use_pspec = g_object_class_find_property (class, use_property_name);
179 if (use_pspec != NULL && use_pspec->value_type != G_TYPE_BOOLEAN)
180 use_pspec = NULL;
181 g_free (use_property_name);
182
183 /* Make sure we can convert to and from doubles. */
184 g_return_if_fail (
185 g_value_type_transformable (
186 pspec->value_type, G_TYPE_DOUBLE));
187 g_return_if_fail (
188 g_value_type_transformable (
189 G_TYPE_DOUBLE, pspec->value_type));
190
191 if (G_IS_PARAM_SPEC_CHAR (pspec)) {
192 GParamSpecChar *pspec_char;
193 pspec_char = G_PARAM_SPEC_CHAR (pspec);
194 adjustment = gtk_adjustment_new (
195 (gdouble) pspec_char->default_value,
196 (gdouble) pspec_char->minimum,
197 (gdouble) pspec_char->maximum,
198 1.0, 1.0, 0.0);
199
200 } else if (G_IS_PARAM_SPEC_UCHAR (pspec)) {
201 GParamSpecUChar *pspec_uchar;
202 pspec_uchar = G_PARAM_SPEC_UCHAR (pspec);
203 adjustment = gtk_adjustment_new (
204 (gdouble) pspec_uchar->default_value,
205 (gdouble) pspec_uchar->minimum,
206 (gdouble) pspec_uchar->maximum,
207 1.0, 1.0, 0.0);
208
209 } else if (G_IS_PARAM_SPEC_INT (pspec)) {
210 GParamSpecInt *pspec_int;
211 pspec_int = G_PARAM_SPEC_INT (pspec);
212 adjustment = gtk_adjustment_new (
213 (gdouble) pspec_int->default_value,
214 (gdouble) pspec_int->minimum,
215 (gdouble) pspec_int->maximum,
216 1.0, 1.0, 0.0);
217
218 } else if (G_IS_PARAM_SPEC_UINT (pspec)) {
219 GParamSpecUInt *pspec_uint;
220 pspec_uint = G_PARAM_SPEC_UINT (pspec);
221 adjustment = gtk_adjustment_new (
222 (gdouble) pspec_uint->default_value,
223 (gdouble) pspec_uint->minimum,
224 (gdouble) pspec_uint->maximum,
225 1.0, 1.0, 0.0);
226
227 } else if (G_IS_PARAM_SPEC_LONG (pspec)) {
228 GParamSpecLong *pspec_long;
229 pspec_long = G_PARAM_SPEC_LONG (pspec);
230 adjustment = gtk_adjustment_new (
231 (gdouble) pspec_long->default_value,
232 (gdouble) pspec_long->minimum,
233 (gdouble) pspec_long->maximum,
234 1.0, 1.0, 0.0);
235
236 } else if (G_IS_PARAM_SPEC_ULONG (pspec)) {
237 GParamSpecULong *pspec_ulong;
238 pspec_ulong = G_PARAM_SPEC_ULONG (pspec);
239 adjustment = gtk_adjustment_new (
240 (gdouble) pspec_ulong->default_value,
241 (gdouble) pspec_ulong->minimum,
242 (gdouble) pspec_ulong->maximum,
243 1.0, 1.0, 0.0);
244
245 } else if (G_IS_PARAM_SPEC_FLOAT (pspec)) {
246 GParamSpecFloat *pspec_float;
247 pspec_float = G_PARAM_SPEC_FLOAT (pspec);
248 adjustment = gtk_adjustment_new (
249 (gdouble) pspec_float->default_value,
250 (gdouble) pspec_float->minimum,
251 (gdouble) pspec_float->maximum,
252 1.0, 1.0, 0.0);
253
254 } else if (G_IS_PARAM_SPEC_DOUBLE (pspec)) {
255 GParamSpecDouble *pspec_double;
256 pspec_double = G_PARAM_SPEC_DOUBLE (pspec);
257 adjustment = gtk_adjustment_new (
258 (gdouble) pspec_double->default_value,
259 (gdouble) pspec_double->minimum,
260 (gdouble) pspec_double->maximum,
261 1.0, 1.0, 0.0);
262
263 } else
264 g_return_if_reached ();
265
266 pre = g_alloca (strlen (entry->text) + 1);
267 strcpy (pre, entry->text);
268 post = strstr (pre, "%s");
269 if (post != NULL) {
270 *post = '\0';
271 post += 2;
272 }
273
274 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
275 gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
276 gtk_box_pack_start (main_box, hbox, FALSE, FALSE, 0);
277 gtk_widget_show (hbox);
278
279 if (use_pspec != NULL) {
280 prefix = gtk_check_button_new_with_mnemonic (pre);
281
282 e_binding_bind_property (
283 settings, use_pspec->name,
284 prefix, "active",
285 G_BINDING_BIDIRECTIONAL |
286 G_BINDING_SYNC_CREATE);
287 } else {
288 prefix = gtk_label_new_with_mnemonic (pre);
289 }
290 gtk_box_pack_start (GTK_BOX (hbox), prefix, FALSE, TRUE, 0);
291 gtk_widget_show (prefix);
292
293 spin = gtk_spin_button_new (adjustment, 1.0, 0);
294 gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, TRUE, 0);
295 gtk_widget_show (spin);
296
297 if (!use_pspec)
298 gtk_label_set_mnemonic_widget (GTK_LABEL (prefix), spin);
299
300 e_binding_bind_property (
301 settings, entry->name,
302 spin, "value",
303 G_BINDING_BIDIRECTIONAL |
304 G_BINDING_SYNC_CREATE);
305
306 if (use_pspec != NULL)
307 e_binding_bind_property (
308 prefix, "active",
309 spin, "sensitive",
310 G_BINDING_SYNC_CREATE);
311
312 if (post != NULL) {
313 GtkWidget *label = gtk_label_new_with_mnemonic (post);
314 gtk_label_set_mnemonic_widget (GTK_LABEL (label), use_pspec ? prefix : spin);
315 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
316 gtk_widget_show (label);
317 }
318
319 mail_config_provider_page_handle_dependency (page, entry, hbox);
320 }
321
322 static void
mail_config_provider_page_add_entry(EMailConfigProviderPage * page,GtkBox * main_box,CamelProviderConfEntry * entry)323 mail_config_provider_page_add_entry (EMailConfigProviderPage *page,
324 GtkBox *main_box,
325 CamelProviderConfEntry *entry)
326 {
327 EMailConfigServiceBackend *backend;
328 CamelSettings *settings;
329 GtkWidget *hbox;
330 GtkWidget *input;
331 GtkWidget *label;
332
333 g_return_if_fail (entry->text != NULL);
334
335 backend = e_mail_config_provider_page_get_backend (page);
336 settings = e_mail_config_service_backend_get_settings (backend);
337
338 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
339 gtk_box_set_spacing (GTK_BOX (hbox), 6);
340 gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
341 gtk_box_pack_start (main_box, hbox, FALSE, FALSE, 0);
342 gtk_widget_show (hbox);
343
344 label = gtk_label_new_with_mnemonic (entry->text);
345 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
346 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
347 gtk_widget_show (label);
348
349 input = gtk_entry_new ();
350 gtk_label_set_mnemonic_widget (GTK_LABEL (label), input);
351 gtk_box_pack_start (GTK_BOX (hbox), input, TRUE, TRUE, 0);
352 gtk_widget_show (input);
353
354 e_binding_bind_object_text_property (
355 settings, entry->name,
356 input, "text",
357 G_BINDING_BIDIRECTIONAL |
358 G_BINDING_SYNC_CREATE);
359
360 e_binding_bind_property (
361 input, "sensitive",
362 label, "sensitive",
363 G_BINDING_SYNC_CREATE);
364
365 mail_config_provider_page_handle_dependency (page, entry, hbox);
366 }
367
368 static void
mail_config_provider_page_add_label(EMailConfigProviderPage * page,GtkBox * main_box,CamelProviderConfEntry * entry)369 mail_config_provider_page_add_label (EMailConfigProviderPage *page,
370 GtkBox *main_box,
371 CamelProviderConfEntry *entry)
372 {
373 GtkWidget *hbox;
374 GtkWidget *label;
375
376 g_return_if_fail (entry->text != NULL);
377
378 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
379 gtk_box_set_spacing (GTK_BOX (hbox), 6);
380 gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
381 gtk_box_pack_start (main_box, hbox, FALSE, FALSE, 0);
382 gtk_widget_show (hbox);
383
384 label = gtk_label_new (entry->text);
385 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
386 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
387 gtk_widget_show (label);
388
389 mail_config_provider_page_handle_dependency (page, entry, hbox);
390 }
391
392 static void
mail_config_provider_page_add_options(EMailConfigProviderPage * page,GtkBox * main_box,CamelProviderConfEntry * entry)393 mail_config_provider_page_add_options (EMailConfigProviderPage *page,
394 GtkBox *main_box,
395 CamelProviderConfEntry *entry)
396 {
397 EMailConfigServiceBackend *backend;
398 CamelProvider *provider;
399 CamelSettings *settings;
400 GtkCellRenderer *renderer;
401 GtkListStore *store;
402 GtkWidget *hbox;
403 GtkWidget *combo;
404 GtkWidget *label;
405 gchar **tokens;
406 guint length, ii;
407
408 /* The 'value' string is of the format:
409 *
410 * 'nick0:caption0:nick1:caption1:...nickN:captionN'
411 *
412 * where 'nick' is the nickname a GEnumValue and 'caption'
413 * is the localized combo box item displayed to the user. */
414
415 g_return_if_fail (entry->text != NULL);
416 g_return_if_fail (entry->value != NULL);
417
418 backend = e_mail_config_provider_page_get_backend (page);
419 provider = e_mail_config_service_backend_get_provider (backend);
420 settings = e_mail_config_service_backend_get_settings (backend);
421
422 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
423 gtk_box_set_spacing (GTK_BOX (hbox), 6);
424 gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
425 gtk_box_pack_start (main_box, hbox, FALSE, FALSE, 0);
426 gtk_widget_show (hbox);
427
428 label = gtk_label_new_with_mnemonic (entry->text);
429 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
430 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
431 gtk_widget_show (label);
432
433 /* 0: 'nick', 1: caption */
434 store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
435
436 tokens = g_strsplit (entry->value, ":", -1);
437 length = g_strv_length (tokens);
438
439 /* Take the strings two at a time. */
440 for (ii = 0; ii + 1 < length; ii += 2) {
441 GtkTreeIter iter;
442 const gchar *nick;
443 const gchar *caption;
444
445 nick = tokens[ii + 0];
446 caption = tokens[ii + 1];
447
448 /* Localize the caption. */
449 caption = dgettext (provider->translation_domain, caption);
450
451 gtk_list_store_append (store, &iter);
452 gtk_list_store_set (store, &iter, 0, nick, 1, caption, -1);
453 }
454
455 g_strfreev (tokens);
456
457 combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
458 gtk_combo_box_set_id_column (GTK_COMBO_BOX (combo), 0);
459 gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
460 gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
461 gtk_widget_show (combo);
462 g_object_unref (store);
463
464 e_binding_bind_property_full (
465 settings, entry->name,
466 combo, "active-id",
467 G_BINDING_BIDIRECTIONAL |
468 G_BINDING_SYNC_CREATE,
469 e_binding_transform_enum_value_to_nick,
470 e_binding_transform_enum_nick_to_value,
471 NULL, (GDestroyNotify) NULL);
472
473 renderer = gtk_cell_renderer_text_new ();
474 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
475 gtk_cell_layout_set_attributes (
476 GTK_CELL_LAYOUT (combo), renderer, "text", 1, NULL);
477
478 mail_config_provider_page_handle_dependency (page, entry, hbox);
479 }
480
481 static void
mail_config_provider_page_add_placeholder(EMailConfigProviderPage * page,GtkBox * main_box,CamelProviderConfEntry * entry)482 mail_config_provider_page_add_placeholder (EMailConfigProviderPage *page,
483 GtkBox *main_box,
484 CamelProviderConfEntry *entry)
485 {
486 GtkWidget *hbox;
487
488 /* The entry->name is used as an identifier of the placeholder,
489 which is used with e_mail_config_provider_page_get_placeholder(). */
490
491 g_return_if_fail (entry->name && *(entry->name));
492
493 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
494 gtk_widget_set_name (hbox, entry->name);
495 gtk_box_set_spacing (GTK_BOX (hbox), 6);
496 gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
497 gtk_box_pack_start (main_box, hbox, FALSE, FALSE, 0);
498 gtk_widget_show (hbox);
499
500 mail_config_provider_page_handle_dependency (page, entry, hbox);
501 }
502
503 static void
mail_config_provider_page_add_widgets(EMailConfigProviderPage * page,GtkBox * main_box)504 mail_config_provider_page_add_widgets (EMailConfigProviderPage *page,
505 GtkBox *main_box)
506 {
507 EMailConfigServiceBackend *backend;
508 CamelProviderConfEntry *entries;
509 CamelProvider *provider;
510 GtkWidget *container;
511 GtkWidget *widget;
512 ESource *source;
513 ESourceExtension *extension;
514 gboolean first_section = TRUE;
515 const gchar *extension_name;
516 const gchar *text;
517 gchar *markup;
518 gint ii;
519
520 /* XXX We begin the page with our own section header and refresh
521 * interval setting, and then skip the CamelProvider's first
522 * CAMEL_PROVIDER_CONF_SECTION_START entry.
523 *
524 * This is all very brittle. I'm convinced that generating
525 * a user interface from an array of records like this is a
526 * bad idea. We already have EMailConfigServiceBackend for
527 * building provider-specific "Receving Email" and "Sending
528 * EMail" pages by hand. We should do similarly here. */
529
530 backend = e_mail_config_provider_page_get_backend (page);
531 source = e_mail_config_service_backend_get_source (backend);
532 provider = e_mail_config_service_backend_get_provider (backend);
533 g_return_if_fail (provider != NULL);
534
535 /* XXX I guess refresh options go in the mail account source,
536 * even if the source is part of a collection. I did not
537 * think about it too hard, so hopefully this is right. */
538 extension_name = E_SOURCE_EXTENSION_REFRESH;
539 extension = e_source_get_extension (source, extension_name);
540
541 text = _("Checking for New Mail");
542 markup = g_markup_printf_escaped ("<b>%s</b>", text);
543 widget = gtk_label_new (markup);
544 gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
545 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
546 gtk_box_pack_start (main_box, widget, FALSE, FALSE, 0);
547 gtk_widget_show (widget);
548 g_free (markup);
549
550 widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
551 gtk_widget_set_margin_left (widget, STANDARD_MARGIN);
552 gtk_box_pack_start (main_box, widget, FALSE, FALSE, 0);
553 gtk_widget_show (widget);
554
555 container = widget;
556
557 text = _("Check for _new messages every");
558 widget = gtk_check_button_new_with_mnemonic (text);
559 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
560 gtk_widget_show (widget);
561
562 e_binding_bind_property (
563 extension, "enabled",
564 widget, "active",
565 G_BINDING_BIDIRECTIONAL |
566 G_BINDING_SYNC_CREATE);
567
568 widget = gtk_spin_button_new_with_range (1.0, 1440.0, 1.0);
569 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
570 gtk_widget_show (widget);
571
572 e_binding_bind_property (
573 extension, "enabled",
574 widget, "sensitive",
575 G_BINDING_SYNC_CREATE);
576
577 e_binding_bind_property (
578 extension, "interval-minutes",
579 widget, "value",
580 G_BINDING_BIDIRECTIONAL |
581 G_BINDING_SYNC_CREATE);
582
583 widget = gtk_label_new (_("minutes"));
584 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
585 gtk_widget_show (widget);
586
587 /* Note the "text" member of each CamelProviderConfEntry is
588 * already localized, so we can use it directly in widgets. */
589
590 entries = provider->extra_conf;
591
592 /* Loop until we see CAMEL_PROVIDER_CONF_END. */
593 for (ii = 0; entries[ii].type != CAMEL_PROVIDER_CONF_END; ii++) {
594
595 /* Skip entries with no name. */
596 if (entries[ii].name == NULL)
597 continue;
598
599 switch (entries[ii].type) {
600 case CAMEL_PROVIDER_CONF_SECTION_START:
601 /* Skip the first section start. */
602 if (first_section) {
603 first_section = FALSE;
604 continue;
605 }
606 mail_config_provider_page_add_section (
607 page, main_box, &entries[ii]);
608 break;
609
610 case CAMEL_PROVIDER_CONF_CHECKBOX:
611 mail_config_provider_page_add_checkbox (
612 page, main_box, &entries[ii]);
613 break;
614
615 case CAMEL_PROVIDER_CONF_CHECKSPIN:
616 mail_config_provider_page_add_checkspin (
617 page, main_box, &entries[ii]);
618 break;
619
620 case CAMEL_PROVIDER_CONF_ENTRY:
621 mail_config_provider_page_add_entry (
622 page, main_box, &entries[ii]);
623 break;
624
625 case CAMEL_PROVIDER_CONF_LABEL:
626 mail_config_provider_page_add_label (
627 page, main_box, &entries[ii]);
628 break;
629
630 case CAMEL_PROVIDER_CONF_OPTIONS:
631 mail_config_provider_page_add_options (
632 page, main_box, &entries[ii]);
633 break;
634
635 case CAMEL_PROVIDER_CONF_PLACEHOLDER:
636 mail_config_provider_page_add_placeholder (
637 page, main_box, &entries[ii]);
638 break;
639
640 default:
641 break; /* skip it */
642 }
643 }
644 }
645
646 static void
mail_config_provider_page_set_backend(EMailConfigProviderPage * page,EMailConfigServiceBackend * backend)647 mail_config_provider_page_set_backend (EMailConfigProviderPage *page,
648 EMailConfigServiceBackend *backend)
649 {
650 g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
651 g_return_if_fail (page->priv->backend == NULL);
652
653 page->priv->backend = g_object_ref (backend);
654 }
655
656 static void
mail_config_provider_page_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)657 mail_config_provider_page_set_property (GObject *object,
658 guint property_id,
659 const GValue *value,
660 GParamSpec *pspec)
661 {
662 switch (property_id) {
663 case PROP_BACKEND:
664 mail_config_provider_page_set_backend (
665 E_MAIL_CONFIG_PROVIDER_PAGE (object),
666 g_value_get_object (value));
667 return;
668 }
669
670 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
671 }
672
673 static void
mail_config_provider_page_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)674 mail_config_provider_page_get_property (GObject *object,
675 guint property_id,
676 GValue *value,
677 GParamSpec *pspec)
678 {
679 switch (property_id) {
680 case PROP_BACKEND:
681 g_value_set_object (
682 value,
683 e_mail_config_provider_page_get_backend (
684 E_MAIL_CONFIG_PROVIDER_PAGE (object)));
685 return;
686 }
687
688 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
689 }
690
691 static void
mail_config_provider_page_dispose(GObject * object)692 mail_config_provider_page_dispose (GObject *object)
693 {
694 EMailConfigProviderPagePrivate *priv;
695
696 priv = E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE (object);
697 g_clear_object (&priv->backend);
698
699 /* Chain up parent's dispose() method. */
700 G_OBJECT_CLASS (e_mail_config_provider_page_parent_class)->
701 dispose (object);
702 }
703
704 static void
mail_config_provider_page_constructed(GObject * object)705 mail_config_provider_page_constructed (GObject *object)
706 {
707 EMailConfigProviderPage *page;
708 EMailConfigServiceBackend *backend;
709 CamelProvider *provider;
710 GtkWidget *main_box;
711
712 page = E_MAIL_CONFIG_PROVIDER_PAGE (object);
713
714 /* Chain up parent's constructed() method. */
715 G_OBJECT_CLASS (e_mail_config_provider_page_parent_class)->constructed (object);
716
717 main_box = e_mail_config_activity_page_get_internal_box (E_MAIL_CONFIG_ACTIVITY_PAGE (page));
718
719 gtk_box_set_spacing (GTK_BOX (main_box), 6);
720
721 backend = e_mail_config_provider_page_get_backend (page);
722 provider = e_mail_config_service_backend_get_provider (backend);
723
724 if (provider != NULL && provider->extra_conf != NULL)
725 mail_config_provider_page_add_widgets (page, GTK_BOX (main_box));
726 else
727 page->priv->is_empty = TRUE;
728
729 e_mail_config_page_set_content (E_MAIL_CONFIG_PAGE (page), main_box);
730
731 e_extensible_load_extensions (E_EXTENSIBLE (page));
732 }
733
734 static void
e_mail_config_provider_page_class_init(EMailConfigProviderPageClass * class)735 e_mail_config_provider_page_class_init (EMailConfigProviderPageClass *class)
736 {
737 GObjectClass *object_class;
738
739 g_type_class_add_private (class, sizeof (EMailConfigProviderPagePrivate));
740
741 object_class = G_OBJECT_CLASS (class);
742 object_class->set_property = mail_config_provider_page_set_property;
743 object_class->get_property = mail_config_provider_page_get_property;
744 object_class->dispose = mail_config_provider_page_dispose;
745 object_class->constructed = mail_config_provider_page_constructed;
746
747 g_object_class_install_property (
748 object_class,
749 PROP_BACKEND,
750 g_param_spec_object (
751 "backend",
752 "Backend",
753 "Service backend to generate options from",
754 E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
755 G_PARAM_READWRITE |
756 G_PARAM_CONSTRUCT_ONLY |
757 G_PARAM_STATIC_STRINGS));
758 }
759
760 static void
e_mail_config_provider_page_interface_init(EMailConfigPageInterface * iface)761 e_mail_config_provider_page_interface_init (EMailConfigPageInterface *iface)
762 {
763 iface->title = _("Receiving Options");
764 iface->sort_order = E_MAIL_CONFIG_PROVIDER_PAGE_SORT_ORDER;
765 }
766
767 static void
e_mail_config_provider_page_init(EMailConfigProviderPage * page)768 e_mail_config_provider_page_init (EMailConfigProviderPage *page)
769 {
770 page->priv = E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE (page);
771 }
772
773 EMailConfigPage *
e_mail_config_provider_page_new(EMailConfigServiceBackend * backend)774 e_mail_config_provider_page_new (EMailConfigServiceBackend *backend)
775 {
776 g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
777
778 return g_object_new (
779 E_TYPE_MAIL_CONFIG_PROVIDER_PAGE,
780 "backend", backend, NULL);
781 }
782
783 gboolean
e_mail_config_provider_page_is_empty(EMailConfigProviderPage * page)784 e_mail_config_provider_page_is_empty (EMailConfigProviderPage *page)
785 {
786 g_return_val_if_fail (E_IS_MAIL_CONFIG_PROVIDER_PAGE (page), TRUE);
787
788 return page->priv->is_empty;
789 }
790
791 EMailConfigServiceBackend *
e_mail_config_provider_page_get_backend(EMailConfigProviderPage * page)792 e_mail_config_provider_page_get_backend (EMailConfigProviderPage *page)
793 {
794 g_return_val_if_fail (E_IS_MAIL_CONFIG_PROVIDER_PAGE (page), NULL);
795
796 return page->priv->backend;
797 }
798
799 typedef struct _FindPlaceholderData {
800 const gchar *name;
801 GtkBox *box;
802 } FindPlaceholderData;
803
804 static void
mail_config_provider_page_find_placeholder(GtkWidget * widget,gpointer user_data)805 mail_config_provider_page_find_placeholder (GtkWidget *widget,
806 gpointer user_data)
807 {
808 FindPlaceholderData *fpd = user_data;
809
810 g_return_if_fail (fpd != NULL);
811
812 if (g_strcmp0 (fpd->name, gtk_widget_get_name (widget)) == 0) {
813 if (fpd->box) {
814 g_warning ("%s: Found multiple placeholders named '%s'", G_STRFUNC, fpd->name);
815 } else {
816 g_return_if_fail (GTK_IS_BOX (widget));
817
818 fpd->box = GTK_BOX (widget);
819 }
820 }
821 }
822
823 GtkBox *
e_mail_config_provider_page_get_placeholder(EMailConfigProviderPage * page,const gchar * name)824 e_mail_config_provider_page_get_placeholder (EMailConfigProviderPage *page,
825 const gchar *name)
826 {
827 FindPlaceholderData fpd;
828 GtkWidget *widget;
829
830 g_return_val_if_fail (E_IS_MAIL_CONFIG_PROVIDER_PAGE (page), NULL);
831 g_return_val_if_fail (name && *name, NULL);
832
833 fpd.name = name;
834 fpd.box = NULL;
835
836 widget = gtk_bin_get_child (GTK_BIN (page));
837 if (GTK_IS_VIEWPORT (widget))
838 widget = gtk_bin_get_child (GTK_BIN (widget));
839
840 if (!GTK_IS_CONTAINER (widget))
841 return NULL;
842
843 gtk_container_foreach (GTK_CONTAINER (widget), mail_config_provider_page_find_placeholder, &fpd);
844
845 return fpd.box;
846 }
847