Bug 793125 - Crash due to popup menus left attached too long
[evolution.git] / src / modules / calendar / e-calendar-preferences.c
blob3f409298a04c4c101e1f407a8cd4e060b887ba0e
1 /*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published by
4 * the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful, but
7 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9 * for more details.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Authors:
16 * Damon Chaplin <damon@ximian.com>
17 * Ettore Perazzoli <ettore@ximian.com>
18 * David Trowbridge <trowbrds cs colorado edu>
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
24 #include "evolution-config.h"
26 #include "e-calendar-preferences.h"
28 #include <string.h>
29 #include <glib/gi18n.h>
31 #include "calendar/gui/e-cal-config.h"
32 #include "calendar/gui/e-timezone-entry.h"
33 #include "calendar/gui/calendar-config.h"
34 #include "shell/e-shell-utils.h"
36 #define ITIP_FORMATTER_CONF_KEY_DELETE "delete-processed"
38 struct _ECalendarPreferencesPrivate {
39 GtkBuilder *builder;
40 ESourceRegistry *registry;
42 /* General tab */
43 GtkWidget *day_second_zone;
44 GtkWidget *start_of_day;
45 GtkWidget *end_of_day;
47 /* Reminders tab */
48 GtkWidget *reminder_calendars_scrolled_window;
49 GtkWidget *reminder_memos_scrolled_window;
50 GtkWidget *reminder_tasks_scrolled_window;
53 G_DEFINE_DYNAMIC_TYPE (
54 ECalendarPreferences,
55 e_calendar_preferences,
56 GTK_TYPE_BOX)
58 static gboolean
59 calendar_preferences_map_string_to_integer (GValue *value,
60 GVariant *variant,
61 gpointer user_data)
63 GEnumClass *enum_class = G_ENUM_CLASS (user_data);
64 GEnumValue *enum_value;
65 const gchar *nick;
67 /* XXX GSettings should know how to bind enum settings to
68 * integer properties. I filed a bug asking for this:
69 * https://bugzilla.gnome.org/show_bug.cgi?id=695217 */
71 nick = g_variant_get_string (variant, NULL);
72 enum_value = g_enum_get_value_by_nick (enum_class, nick);
73 g_return_val_if_fail (enum_value != NULL, FALSE);
74 g_value_set_int (value, enum_value->value);
76 return TRUE;
79 static GVariant *
80 calendar_preferences_map_integer_to_string (const GValue *value,
81 const GVariantType *expected_type,
82 gpointer user_data)
84 GEnumClass *enum_class = G_ENUM_CLASS (user_data);
85 GEnumValue *enum_value;
87 /* XXX GSettings should know how to bind enum settings to
88 * integer properties. I filed a bug asking for this:
89 * https://bugzilla.gnome.org/show_bug.cgi?id=695217 */
91 enum_value = g_enum_get_value (enum_class, g_value_get_int (value));
92 g_return_val_if_fail (enum_value != NULL, NULL);
94 return g_variant_new_string (enum_value->value_nick);
97 static gboolean
98 calendar_preferences_map_string_to_icaltimezone (GValue *value,
99 GVariant *variant,
100 gpointer user_data)
102 GSettings *settings;
103 const gchar *location = NULL;
104 icaltimezone *timezone = NULL;
106 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
108 if (g_settings_get_boolean (settings, "use-system-timezone"))
109 timezone = e_cal_util_get_system_timezone ();
110 else
111 location = g_variant_get_string (variant, NULL);
113 if (location != NULL && *location != '\0')
114 timezone = icaltimezone_get_builtin_timezone (location);
116 if (timezone == NULL)
117 timezone = icaltimezone_get_utc_timezone ();
119 g_value_set_pointer (value, timezone);
121 g_object_unref (settings);
123 return TRUE;
126 static GVariant *
127 calendar_preferences_map_icaltimezone_to_string (const GValue *value,
128 const GVariantType *expected_type,
129 gpointer user_data)
131 GVariant *variant;
132 GSettings *settings;
133 const gchar *location = NULL;
134 gchar *location_str = NULL;
135 icaltimezone *timezone;
137 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
139 if (g_settings_get_boolean (settings, "use-system-timezone")) {
140 location_str = g_settings_get_string (settings, "timezone");
141 location = location_str;
142 } else {
143 timezone = g_value_get_pointer (value);
145 if (timezone != NULL)
146 location = icaltimezone_get_location (timezone);
149 if (location == NULL)
150 location = "UTC";
152 variant = g_variant_new_string (location);
154 g_free (location_str);
156 g_object_unref (settings);
158 return variant;
161 static gboolean
162 calendar_preferences_map_time_divisions_to_index (GValue *value,
163 GVariant *variant,
164 gpointer user_data)
166 gboolean success = TRUE;
168 switch (g_variant_get_int32 (variant)) {
169 case 60:
170 g_value_set_int (value, 0);
171 break;
172 case 30:
173 g_value_set_int (value, 1);
174 break;
175 case 15:
176 g_value_set_int (value, 2);
177 break;
178 case 10:
179 g_value_set_int (value, 3);
180 break;
181 case 5:
182 g_value_set_int (value, 4);
183 break;
184 default:
185 success = FALSE;
188 return success;
191 static GVariant *
192 calendar_preferences_map_index_to_time_divisions (const GValue *value,
193 const GVariantType *expected_type,
194 gpointer user_data)
196 switch (g_value_get_int (value)) {
197 case 0:
198 return g_variant_new_int32 (60);
199 case 1:
200 return g_variant_new_int32 (30);
201 case 2:
202 return g_variant_new_int32 (15);
203 case 3:
204 return g_variant_new_int32 (10);
205 case 4:
206 return g_variant_new_int32 (5);
207 default:
208 break;
211 return NULL;
214 static gboolean
215 calendar_preferences_map_string_to_gdk_color (GValue *value,
216 GVariant *variant,
217 gpointer user_data)
219 GdkColor color;
220 const gchar *string;
221 gboolean success = FALSE;
223 string = g_variant_get_string (variant, NULL);
224 if (gdk_color_parse (string, &color)) {
225 g_value_set_boxed (value, &color);
226 success = TRUE;
229 return success;
232 static GVariant *
233 calendar_preferences_map_gdk_color_to_string (const GValue *value,
234 const GVariantType *expected_type,
235 gpointer user_data)
237 GVariant *variant;
238 const GdkColor *color;
240 color = g_value_get_boxed (value);
241 if (color == NULL) {
242 variant = g_variant_new_string ("");
243 } else {
244 gchar *string;
246 string = gdk_color_to_string (color);
247 variant = g_variant_new_string (string);
248 g_free (string);
251 return variant;
254 static void
255 calendar_preferences_dispose (GObject *object)
257 ECalendarPreferences *prefs = E_CALENDAR_PREFERENCES (object);
259 g_clear_object (&prefs->priv->builder);
260 g_clear_object (&prefs->priv->registry);
262 /* Chain up to parent's dispose() method. */
263 G_OBJECT_CLASS (e_calendar_preferences_parent_class)->dispose (object);
266 static void
267 e_calendar_preferences_class_init (ECalendarPreferencesClass *class)
269 GObjectClass *object_class;
271 g_type_class_add_private (class, sizeof (ECalendarPreferencesPrivate));
273 object_class = G_OBJECT_CLASS (class);
274 object_class->dispose = calendar_preferences_dispose;
277 static void
278 e_calendar_preferences_class_finalize (ECalendarPreferencesClass *class)
282 static void
283 e_calendar_preferences_init (ECalendarPreferences *preferences)
285 preferences->priv = G_TYPE_INSTANCE_GET_PRIVATE (preferences, E_TYPE_CALENDAR_PREFERENCES, ECalendarPreferencesPrivate);
287 gtk_orientable_set_orientation (GTK_ORIENTABLE (preferences), GTK_ORIENTATION_VERTICAL);
290 static GtkWidget *
291 calendar_preferences_get_config_widget (EConfig *ec,
292 EConfigItem *item,
293 GtkWidget *parent,
294 GtkWidget *old,
295 gint position,
296 gpointer data)
298 ECalendarPreferences *preferences = data;
300 return e_builder_get_widget (preferences->priv->builder, item->label);
303 static void
304 update_day_second_zone_caption (ECalendarPreferences *prefs)
306 gchar *location;
307 const gchar *caption;
308 icaltimezone *zone;
310 g_return_if_fail (prefs != NULL);
312 /* Translators: "None" indicates no second time zone set for a day view */
313 caption = C_("cal-second-zone", "None");
315 location = calendar_config_get_day_second_zone ();
316 if (location && *location) {
317 zone = icaltimezone_get_builtin_timezone (location);
318 if (zone && icaltimezone_get_display_name (zone)) {
319 caption = icaltimezone_get_display_name (zone);
322 g_free (location);
324 gtk_button_set_label (GTK_BUTTON (prefs->priv->day_second_zone), caption);
327 static void
328 on_set_day_second_zone (GtkWidget *item,
329 ECalendarPreferences *prefs)
331 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
332 return;
334 calendar_config_set_day_second_zone (g_object_get_data (G_OBJECT (item), "timezone"));
335 update_day_second_zone_caption (prefs);
338 static void
339 on_select_day_second_zone (GtkWidget *item,
340 ECalendarPreferences *prefs)
342 g_return_if_fail (prefs != NULL);
344 calendar_config_select_day_second_zone ();
345 update_day_second_zone_caption (prefs);
348 static void
349 day_second_zone_clicked (GtkWidget *widget,
350 ECalendarPreferences *prefs)
352 GtkWidget *menu, *item;
353 GSList *group = NULL, *recent_zones, *s;
354 gchar *location;
355 icaltimezone *zone, *second_zone = NULL;
357 menu = gtk_menu_new ();
359 location = calendar_config_get_day_second_zone ();
360 if (location && *location)
361 second_zone = icaltimezone_get_builtin_timezone (location);
362 g_free (location);
364 group = NULL;
365 item = gtk_radio_menu_item_new_with_label (group, C_("cal-second-zone", "None"));
366 group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
367 if (!second_zone)
368 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
369 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
370 g_signal_connect (
371 item, "toggled",
372 G_CALLBACK (on_set_day_second_zone), prefs);
374 recent_zones = calendar_config_get_day_second_zones ();
375 for (s = recent_zones; s != NULL; s = s->next) {
376 zone = icaltimezone_get_builtin_timezone (s->data);
377 if (!zone)
378 continue;
380 item = gtk_radio_menu_item_new_with_label (group, icaltimezone_get_display_name (zone));
381 group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
382 /* both comes from builtin, thus no problem to compare pointers */
383 if (zone == second_zone)
384 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
385 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
386 g_object_set_data_full (G_OBJECT (item), "timezone", g_strdup (s->data), g_free);
387 g_signal_connect (
388 item, "toggled",
389 G_CALLBACK (on_set_day_second_zone), prefs);
391 calendar_config_free_day_second_zones (recent_zones);
393 item = gtk_separator_menu_item_new ();
394 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
396 item = gtk_menu_item_new_with_label (_("Select..."));
397 g_signal_connect (
398 item, "activate",
399 G_CALLBACK (on_select_day_second_zone), prefs);
400 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
402 gtk_widget_show_all (menu);
404 gtk_menu_attach_to_widget (GTK_MENU (menu), widget, NULL);
405 g_signal_connect (menu, "deactivate", G_CALLBACK (gtk_menu_detach), NULL);
406 gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
409 static void
410 start_of_day_changed (GtkWidget *widget,
411 ECalendarPreferences *prefs)
413 EDateEdit *start, *end;
414 GSettings *settings;
415 gint start_hour;
416 gint start_minute;
417 gint end_hour;
418 gint end_minute;
420 start = E_DATE_EDIT (prefs->priv->start_of_day);
421 end = E_DATE_EDIT (prefs->priv->end_of_day);
423 e_date_edit_get_time_of_day (start, &start_hour, &start_minute);
424 e_date_edit_get_time_of_day (end, &end_hour, &end_minute);
426 if ((start_hour > end_hour) || (start_hour == end_hour && start_minute > end_minute)) {
427 if (start_hour < 23)
428 e_date_edit_set_time_of_day (end, start_hour + 1, start_minute);
429 else
430 e_date_edit_set_time_of_day (end, 23, 59);
432 return;
435 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
437 g_settings_set_int (settings, "day-start-hour", start_hour);
438 g_settings_set_int (settings, "day-start-minute", start_minute);
440 g_object_unref (settings);
443 static void
444 end_of_day_changed (GtkWidget *widget,
445 ECalendarPreferences *prefs)
447 EDateEdit *start, *end;
448 GSettings *settings;
449 gint start_hour;
450 gint start_minute;
451 gint end_hour;
452 gint end_minute;
454 start = E_DATE_EDIT (prefs->priv->start_of_day);
455 end = E_DATE_EDIT (prefs->priv->end_of_day);
457 e_date_edit_get_time_of_day (start, &start_hour, &start_minute);
458 e_date_edit_get_time_of_day (end, &end_hour, &end_minute);
460 if ((end_hour < start_hour) || (end_hour == start_hour && end_minute < start_minute)) {
461 if (end_hour < 1)
462 e_date_edit_set_time_of_day (start, 0, 0);
463 else
464 e_date_edit_set_time_of_day (start, end_hour - 1, end_minute);
466 return;
469 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
471 g_settings_set_int (settings, "day-end-hour", end_hour);
472 g_settings_set_int (settings, "day-end-minute", end_minute);
474 g_object_unref (settings);
477 static void
478 update_system_tz_widgets (GtkCheckButton *button,
479 ECalendarPreferences *prefs)
481 GtkWidget *widget;
482 icaltimezone *zone;
483 const gchar *display_name;
484 gchar *text;
486 widget = e_builder_get_widget (prefs->priv->builder, "system-tz-label");
487 g_return_if_fail (GTK_IS_LABEL (widget));
489 zone = e_cal_util_get_system_timezone ();
490 if (zone != NULL)
491 display_name = gettext (icaltimezone_get_display_name (zone));
492 else
493 display_name = "UTC";
495 text = g_strdup_printf ("(%s)", display_name);
496 gtk_label_set_text (GTK_LABEL (widget), text);
497 g_free (text);
500 static void
501 setup_changes (ECalendarPreferences *prefs)
503 g_signal_connect (
504 prefs->priv->day_second_zone, "clicked",
505 G_CALLBACK (day_second_zone_clicked), prefs);
507 g_signal_connect (
508 prefs->priv->start_of_day, "changed",
509 G_CALLBACK (start_of_day_changed), prefs);
511 g_signal_connect (
512 prefs->priv->end_of_day, "changed",
513 G_CALLBACK (end_of_day_changed), prefs);
516 static void
517 show_alarms_config (ECalendarPreferences *prefs)
519 GtkWidget *widget;
521 widget = e_alarm_selector_new (prefs->priv->registry, E_SOURCE_EXTENSION_CALENDAR);
522 atk_object_set_name (
523 gtk_widget_get_accessible (widget),
524 _("Selected Calendars for Notifications of Reminders"));
525 gtk_container_add (GTK_CONTAINER (prefs->priv->reminder_calendars_scrolled_window), widget);
526 gtk_widget_show (widget);
528 widget = e_alarm_selector_new (prefs->priv->registry, E_SOURCE_EXTENSION_MEMO_LIST);
529 atk_object_set_name (
530 gtk_widget_get_accessible (widget),
531 _("Selected Memo Lists for Notifications of Reminders"));
532 gtk_container_add (GTK_CONTAINER (prefs->priv->reminder_memos_scrolled_window), widget);
533 gtk_widget_show (widget);
535 widget = e_alarm_selector_new (prefs->priv->registry, E_SOURCE_EXTENSION_TASK_LIST);
536 atk_object_set_name (
537 gtk_widget_get_accessible (widget),
538 _("Selected Task Lists for Notifications of Reminders"));
539 gtk_container_add (GTK_CONTAINER (prefs->priv->reminder_tasks_scrolled_window), widget);
540 gtk_widget_show (widget);
543 /* Shows the current config settings in the dialog. */
544 static void
545 show_config (ECalendarPreferences *prefs)
547 GSettings *settings;
549 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
551 /* Day's second zone */
552 update_day_second_zone_caption (prefs);
554 /* Start of Day. */
555 e_date_edit_set_time_of_day (
556 E_DATE_EDIT (prefs->priv->start_of_day),
557 g_settings_get_int (settings, "day-start-hour"),
558 g_settings_get_int (settings, "day-start-minute"));
560 /* End of Day. */
561 e_date_edit_set_time_of_day (
562 E_DATE_EDIT (prefs->priv->end_of_day),
563 g_settings_get_int (settings, "day-end-hour"),
564 g_settings_get_int (settings, "day-end-minute"));
566 /* Alarms list */
567 show_alarms_config (prefs);
569 g_object_unref (settings);
572 /* plugin meta-data */
573 static ECalConfigItem eccp_items[] = {
574 { E_CONFIG_BOOK, (gchar *) "", (gchar *) "toplevel-notebook", calendar_preferences_get_config_widget },
575 { E_CONFIG_PAGE, (gchar *) "00.general", (gchar *) "general", calendar_preferences_get_config_widget },
576 { E_CONFIG_SECTION_TABLE, (gchar *) "00.general/00.time", (gchar *) "time", calendar_preferences_get_config_widget },
577 { E_CONFIG_SECTION_TABLE, (gchar *) "00.general/10.workWeek", (gchar *) "workWeek", calendar_preferences_get_config_widget },
578 { E_CONFIG_SECTION, (gchar *) "00.general/20.alerts", (gchar *) "alerts", calendar_preferences_get_config_widget },
579 { E_CONFIG_PAGE, (gchar *) "10.display", (gchar *) "display", calendar_preferences_get_config_widget },
580 { E_CONFIG_SECTION, (gchar *) "10.display/00.general", (gchar *) "displayGeneral", calendar_preferences_get_config_widget },
581 { E_CONFIG_SECTION, (gchar *) "10.display/10.taskList", (gchar *) "taskList", calendar_preferences_get_config_widget },
582 { E_CONFIG_PAGE, (gchar *) "12.tasks", (gchar *) "tasks-vbox", calendar_preferences_get_config_widget },
583 { E_CONFIG_PAGE, (gchar *) "15.alarms", (gchar *) "alarms", calendar_preferences_get_config_widget },
584 { E_CONFIG_PAGE, (gchar *) "20.freeBusy", (gchar *) "freebusy", calendar_preferences_get_config_widget },
585 { E_CONFIG_SECTION, (gchar *) "20.freeBusy/00.defaultServer", (gchar *) "default-freebusy-vbox", calendar_preferences_get_config_widget },
588 static void
589 eccp_free (EConfig *ec,
590 GSList *items,
591 gpointer data)
593 g_slist_free (items);
596 static void
597 itip_formatter_delete_toggled_cb (GtkWidget *widget)
599 GSettings *settings;
600 gboolean active;
602 settings = e_util_ref_settings ("org.gnome.evolution.plugin.itip");
603 active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
604 g_settings_set_boolean (settings, ITIP_FORMATTER_CONF_KEY_DELETE, active);
605 g_object_unref (settings);
608 static void
609 calendar_preferences_add_itip_formatter_page (EShell *shell,
610 GtkWidget *notebook)
612 ESourceRegistry *registry;
613 GtkWidget *page;
614 GtkWidget *tab_label;
615 GtkWidget *frame;
616 GtkWidget *frame_label;
617 GtkWidget *padding_label;
618 GtkWidget *hbox;
619 GtkWidget *inner_vbox;
620 GtkWidget *check;
621 GtkWidget *label;
622 GtkWidget *ess;
623 GtkWidget *scrolledwin;
624 gchar *str;
625 GSettings *settings;
627 g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
629 registry = e_shell_get_registry (shell);
631 /* Create a new notebook page */
632 page = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
633 gtk_container_set_border_width (GTK_CONTAINER (page), 12);
634 tab_label = gtk_label_new (_("Meeting Invitations"));
635 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, tab_label);
637 /* Frame */
638 frame = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
639 gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
641 /* "General" */
642 frame_label = gtk_label_new ("");
643 str = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("General"));
644 gtk_label_set_markup (GTK_LABEL (frame_label), str);
645 g_free (str);
646 gtk_misc_set_alignment (GTK_MISC (frame_label), 0.0, 0.5);
647 gtk_box_pack_start (GTK_BOX (frame), frame_label, FALSE, FALSE, 0);
649 /* Indent/padding */
650 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
651 gtk_box_pack_start (GTK_BOX (frame), hbox, FALSE, TRUE, 0);
652 padding_label = gtk_label_new ("");
653 gtk_box_pack_start (GTK_BOX (hbox), padding_label, FALSE, FALSE, 0);
654 inner_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
655 gtk_box_pack_start (GTK_BOX (hbox), inner_vbox, FALSE, FALSE, 0);
657 /* Delete message after acting */
658 settings = e_util_ref_settings ("org.gnome.evolution.plugin.itip");
660 check = gtk_check_button_new_with_mnemonic (_("_Delete message after acting"));
661 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), g_settings_get_boolean (settings, ITIP_FORMATTER_CONF_KEY_DELETE));
662 g_signal_connect (
663 check, "toggled",
664 G_CALLBACK (itip_formatter_delete_toggled_cb), NULL);
665 gtk_box_pack_start (GTK_BOX (inner_vbox), check, FALSE, FALSE, 0);
667 g_object_unref (settings);
669 /* "Conflict searching" */
670 frame = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
671 gtk_box_pack_start (GTK_BOX (page), frame, TRUE, TRUE, 24);
673 frame_label = gtk_label_new ("");
674 str = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("Conflict Search"));
675 gtk_label_set_markup (GTK_LABEL (frame_label), str);
676 g_free (str);
677 gtk_misc_set_alignment (GTK_MISC (frame_label), 0.0, 0.5);
678 gtk_box_pack_start (GTK_BOX (frame), frame_label, FALSE, FALSE, 0);
680 /* Indent/padding */
681 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
682 gtk_box_pack_start (GTK_BOX (frame), hbox, TRUE, TRUE, 0);
683 padding_label = gtk_label_new ("");
684 gtk_box_pack_start (GTK_BOX (hbox), padding_label, FALSE, FALSE, 0);
685 inner_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
686 gtk_box_pack_start (GTK_BOX (hbox), inner_vbox, TRUE, TRUE, 0);
688 /* Source selector */
689 label = gtk_label_new (_("Select the calendars to search for meeting conflicts"));
690 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
691 gtk_box_pack_start (GTK_BOX (inner_vbox), label, FALSE, FALSE, 0);
693 scrolledwin = gtk_scrolled_window_new (NULL, NULL);
695 gtk_scrolled_window_set_policy (
696 GTK_SCROLLED_WINDOW (scrolledwin),
697 GTK_POLICY_AUTOMATIC,
698 GTK_POLICY_AUTOMATIC);
699 gtk_scrolled_window_set_shadow_type (
700 GTK_SCROLLED_WINDOW (scrolledwin),
701 GTK_SHADOW_IN);
702 gtk_box_pack_start (GTK_BOX (inner_vbox), scrolledwin, TRUE, TRUE, 0);
704 ess = e_conflict_search_selector_new (registry);
705 atk_object_set_name (gtk_widget_get_accessible (ess), _("Conflict Search"));
706 gtk_container_add (GTK_CONTAINER (scrolledwin), ess);
708 gtk_widget_show_all (page);
711 static void
712 calendar_preferences_construct (ECalendarPreferences *prefs,
713 EShell *shell)
715 ECalConfig *ec;
716 ECalConfigTargetPrefs *target;
717 GSettings *settings;
718 GSettings *eds_settings;
719 GSettings *mail_settings;
720 gboolean locale_supports_12_hour_format;
721 gint i;
722 GtkWidget *toplevel;
723 GtkWidget *widget;
724 GtkWidget *table;
725 GSList *l;
727 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
728 mail_settings = e_util_ref_settings ("org.gnome.evolution.mail");
730 locale_supports_12_hour_format =
731 calendar_config_locale_supports_12_hour_format ();
733 /* Force 24 hour format for locales which don't support 12 hour format */
734 if (!locale_supports_12_hour_format)
735 g_settings_set_boolean (settings, "use-24hour-format", TRUE);
737 /* Make sure our custom widget classes are registered with
738 * GType before we load the GtkBuilder definition file. */
739 g_type_ensure (E_TYPE_DATE_EDIT);
740 g_type_ensure (E_TYPE_TIMEZONE_ENTRY);
742 prefs->priv->builder = gtk_builder_new ();
743 e_load_ui_builder_definition (prefs->priv->builder, "e-calendar-preferences.ui");
745 /** @HookPoint-ECalConfig: Calendar Preferences Page
746 * @Id: org.gnome.evolution.calendar.prefs
747 * @Class: org.gnome.evolution.calendar.config:1.0
748 * @Target: ECalConfigTargetPrefs
750 * The mail calendar preferences page
752 ec = e_cal_config_new ("org.gnome.evolution.calendar.prefs");
753 l = NULL;
754 for (i = 0; i < G_N_ELEMENTS (eccp_items); i++)
755 l = g_slist_prepend (l, &eccp_items[i]);
756 e_config_add_items ((EConfig *) ec, l, eccp_free, prefs);
758 calendar_preferences_add_itip_formatter_page (shell, e_builder_get_widget (prefs->priv->builder, "toplevel-notebook"));
760 widget = e_builder_get_widget (prefs->priv->builder, "use-system-tz-check");
761 g_settings_bind (
762 settings, "use-system-timezone",
763 widget, "active",
764 G_SETTINGS_BIND_DEFAULT);
765 g_signal_connect (
766 widget, "toggled",
767 G_CALLBACK (update_system_tz_widgets), prefs);
768 update_system_tz_widgets (GTK_CHECK_BUTTON (widget), prefs);
770 widget = e_builder_get_widget (prefs->priv->builder, "timezone");
771 g_settings_bind_with_mapping (
772 settings, "timezone",
773 widget, "timezone",
774 G_SETTINGS_BIND_DEFAULT,
775 calendar_preferences_map_string_to_icaltimezone,
776 calendar_preferences_map_icaltimezone_to_string,
777 NULL, (GDestroyNotify) NULL);
778 g_settings_bind (
779 settings, "use-system-timezone",
780 widget, "sensitive",
781 G_SETTINGS_BIND_DEFAULT |
782 G_SETTINGS_BIND_INVERT_BOOLEAN);
784 /* General tab */
785 prefs->priv->day_second_zone = e_builder_get_widget (prefs->priv->builder, "day_second_zone");
787 widget = e_builder_get_widget (prefs->priv->builder, "sun_button");
788 g_settings_bind (
789 settings, "work-day-sunday",
790 widget, "active",
791 G_SETTINGS_BIND_DEFAULT);
793 widget = e_builder_get_widget (prefs->priv->builder, "mon_button");
794 g_settings_bind (
795 settings, "work-day-monday",
796 widget, "active",
797 G_SETTINGS_BIND_DEFAULT);
799 widget = e_builder_get_widget (prefs->priv->builder, "tue_button");
800 g_settings_bind (
801 settings, "work-day-tuesday",
802 widget, "active",
803 G_SETTINGS_BIND_DEFAULT);
805 widget = e_builder_get_widget (prefs->priv->builder, "wed_button");
806 g_settings_bind (
807 settings, "work-day-wednesday",
808 widget, "active",
809 G_SETTINGS_BIND_DEFAULT);
811 widget = e_builder_get_widget (prefs->priv->builder, "thu_button");
812 g_settings_bind (
813 settings, "work-day-thursday",
814 widget, "active",
815 G_SETTINGS_BIND_DEFAULT);
817 widget = e_builder_get_widget (prefs->priv->builder, "fri_button");
818 g_settings_bind (
819 settings, "work-day-friday",
820 widget, "active",
821 G_SETTINGS_BIND_DEFAULT);
823 widget = e_builder_get_widget (prefs->priv->builder, "sat_button");
824 g_settings_bind (
825 settings, "work-day-saturday",
826 widget, "active",
827 G_SETTINGS_BIND_DEFAULT);
829 widget = e_builder_get_widget (prefs->priv->builder, "week_start_day");
830 g_settings_bind (
831 settings, "week-start-day-name",
832 widget, "active-id",
833 G_SETTINGS_BIND_DEFAULT);
835 widget = e_builder_get_widget (prefs->priv->builder, "start_of_day");
836 prefs->priv->start_of_day = widget; /* XXX delete this */
837 if (locale_supports_12_hour_format)
838 g_settings_bind (
839 settings, "use-24hour-format",
840 widget, "use-24-hour-format",
841 G_SETTINGS_BIND_GET);
843 widget = e_builder_get_widget (prefs->priv->builder, "end_of_day");
844 prefs->priv->end_of_day = widget; /* XXX delete this */
845 if (locale_supports_12_hour_format)
846 g_settings_bind (
847 settings, "use-24hour-format",
848 widget, "use-24-hour-format",
849 G_SETTINGS_BIND_GET);
851 widget = e_builder_get_widget (prefs->priv->builder, "use_12_hour");
852 gtk_widget_set_sensitive (widget, locale_supports_12_hour_format);
853 g_settings_bind (
854 settings, "use-24hour-format",
855 widget, "active",
856 G_SETTINGS_BIND_DEFAULT |
857 G_SETTINGS_BIND_INVERT_BOOLEAN);
859 widget = e_builder_get_widget (prefs->priv->builder, "use_24_hour");
860 gtk_widget_set_sensitive (widget, locale_supports_12_hour_format);
861 g_settings_bind (
862 settings, "use-24hour-format",
863 widget, "active",
864 G_SETTINGS_BIND_DEFAULT);
866 widget = e_builder_get_widget (prefs->priv->builder, "confirm_delete");
867 g_settings_bind (
868 settings, "confirm-delete",
869 widget, "active",
870 G_SETTINGS_BIND_DEFAULT);
872 widget = e_builder_get_widget (prefs->priv->builder, "default_reminder");
873 g_settings_bind (
874 settings, "use-default-reminder",
875 widget, "active",
876 G_SETTINGS_BIND_DEFAULT);
878 widget = e_builder_get_widget (prefs->priv->builder, "default_reminder_interval");
879 g_settings_bind (
880 settings, "default-reminder-interval",
881 widget, "value",
882 G_SETTINGS_BIND_DEFAULT);
883 g_settings_bind (
884 settings, "use-default-reminder",
885 widget, "sensitive",
886 G_SETTINGS_BIND_GET);
888 widget = e_builder_get_widget (prefs->priv->builder, "default_reminder_units");
889 g_settings_bind_with_mapping (
890 settings, "default-reminder-units",
891 widget, "active",
892 G_SETTINGS_BIND_DEFAULT,
893 calendar_preferences_map_string_to_integer,
894 calendar_preferences_map_integer_to_string,
895 g_type_class_ref (E_TYPE_DURATION_TYPE),
896 (GDestroyNotify) g_type_class_unref);
897 g_settings_bind (
898 settings, "use-default-reminder",
899 widget, "sensitive",
900 G_SETTINGS_BIND_GET);
902 widget = e_builder_get_widget (prefs->priv->builder, "classify-private");
903 g_settings_bind (
904 settings, "classify-private",
905 widget, "active",
906 G_SETTINGS_BIND_DEFAULT);
908 /* These settings control the "Birthdays & Anniversaries" backend. */
910 eds_settings =
911 e_util_ref_settings ("org.gnome.evolution-data-server.calendar");
913 widget = e_builder_get_widget (prefs->priv->builder, "ba_reminder");
914 g_settings_bind (
915 eds_settings, "contacts-reminder-enabled",
916 widget, "active",
917 G_SETTINGS_BIND_DEFAULT);
919 widget = e_builder_get_widget (prefs->priv->builder, "ba_reminder_interval");
920 g_settings_bind (
921 eds_settings, "contacts-reminder-interval",
922 widget, "value",
923 G_SETTINGS_BIND_DEFAULT);
924 g_settings_bind (
925 eds_settings, "contacts-reminder-enabled",
926 widget, "sensitive",
927 G_SETTINGS_BIND_GET);
929 widget = e_builder_get_widget (prefs->priv->builder, "ba_reminder_units");
930 g_settings_bind_with_mapping (
931 eds_settings, "contacts-reminder-units",
932 widget, "active",
933 G_SETTINGS_BIND_DEFAULT,
934 calendar_preferences_map_string_to_integer,
935 calendar_preferences_map_integer_to_string,
936 g_type_class_ref (E_TYPE_DURATION_TYPE),
937 (GDestroyNotify) g_type_class_unref);
938 g_settings_bind (
939 eds_settings, "contacts-reminder-enabled",
940 widget, "sensitive",
941 G_SETTINGS_BIND_GET);
943 g_object_unref (eds_settings);
945 /* Display tab */
946 widget = e_builder_get_widget (prefs->priv->builder, "time_divisions");
947 g_settings_bind_with_mapping (
948 settings, "time-divisions",
949 widget, "active",
950 G_SETTINGS_BIND_DEFAULT,
951 calendar_preferences_map_time_divisions_to_index,
952 calendar_preferences_map_index_to_time_divisions,
953 NULL, (GDestroyNotify) NULL);
955 widget = e_builder_get_widget (prefs->priv->builder, "show_end_times");
956 g_settings_bind (
957 settings, "show-event-end",
958 widget, "active",
959 G_SETTINGS_BIND_DEFAULT);
961 widget = e_builder_get_widget (prefs->priv->builder, "show_icons_month_view");
962 g_settings_bind (
963 settings, "show-icons-month-view",
964 widget, "active",
965 G_SETTINGS_BIND_DEFAULT);
967 widget = e_builder_get_widget (prefs->priv->builder, "compress_weekend");
968 g_settings_bind (
969 settings, "compress-weekend",
970 widget, "active",
971 G_SETTINGS_BIND_DEFAULT);
973 widget = e_builder_get_widget (prefs->priv->builder, "show_week_numbers");
974 g_settings_bind (
975 settings, "show-week-numbers",
976 widget, "active",
977 G_SETTINGS_BIND_DEFAULT);
979 widget = e_builder_get_widget (prefs->priv->builder, "recur_events_italic");
980 g_settings_bind (
981 settings, "recur-events-italic",
982 widget, "active",
983 G_SETTINGS_BIND_DEFAULT);
985 widget = e_builder_get_widget (prefs->priv->builder, "month_scroll_by_week");
986 g_settings_bind (
987 settings, "month-scroll-by-week",
988 widget, "active",
989 G_SETTINGS_BIND_DEFAULT);
991 widget = e_builder_get_widget (prefs->priv->builder, "week_view_days_left_to_right");
992 g_settings_bind (
993 settings, "week-view-days-left-to-right",
994 widget, "active",
995 G_SETTINGS_BIND_DEFAULT);
997 widget = e_builder_get_widget (prefs->priv->builder, "tasks_due_today_highlight");
998 g_settings_bind (
999 settings, "task-due-today-highlight",
1000 widget, "active",
1001 G_SETTINGS_BIND_DEFAULT);
1003 widget = e_builder_get_widget (prefs->priv->builder, "tasks_due_today_color");
1004 g_settings_bind_with_mapping (
1005 settings, "task-due-today-color",
1006 widget, "color",
1007 G_SETTINGS_BIND_DEFAULT,
1008 calendar_preferences_map_string_to_gdk_color,
1009 calendar_preferences_map_gdk_color_to_string,
1010 NULL, (GDestroyNotify) NULL);
1011 g_settings_bind (
1012 settings, "task-due-today-highlight",
1013 widget, "sensitive",
1014 G_SETTINGS_BIND_GET);
1016 widget = e_builder_get_widget (prefs->priv->builder, "tasks_overdue_highlight");
1017 g_settings_bind (
1018 settings, "task-overdue-highlight",
1019 widget, "active",
1020 G_SETTINGS_BIND_DEFAULT);
1022 widget = e_builder_get_widget (prefs->priv->builder, "tasks_overdue_color");
1023 g_settings_bind_with_mapping (
1024 settings, "task-overdue-color",
1025 widget, "color",
1026 G_SETTINGS_BIND_DEFAULT,
1027 calendar_preferences_map_string_to_gdk_color,
1028 calendar_preferences_map_gdk_color_to_string,
1029 NULL, (GDestroyNotify) NULL);
1030 g_settings_bind (
1031 settings, "task-overdue-highlight",
1032 widget, "sensitive",
1033 G_SETTINGS_BIND_GET);
1035 widget = e_builder_get_widget (prefs->priv->builder, "tasks_hide_completed");
1036 g_settings_bind (
1037 settings, "hide-completed-tasks",
1038 widget, "active",
1039 G_SETTINGS_BIND_DEFAULT);
1041 widget = e_builder_get_widget (prefs->priv->builder, "tasks_hide_completed_interval");
1042 g_settings_bind (
1043 settings, "hide-completed-tasks-value",
1044 widget, "value",
1045 G_SETTINGS_BIND_DEFAULT);
1046 g_settings_bind (
1047 settings, "hide-completed-tasks",
1048 widget, "sensitive",
1049 G_SETTINGS_BIND_GET);
1051 widget = e_builder_get_widget (prefs->priv->builder, "tasks_hide_completed_units");
1052 g_settings_bind_with_mapping (
1053 settings, "hide-completed-tasks-units",
1054 widget, "active",
1055 G_SETTINGS_BIND_DEFAULT,
1056 calendar_preferences_map_string_to_integer,
1057 calendar_preferences_map_integer_to_string,
1058 g_type_class_ref (E_TYPE_DURATION_TYPE),
1059 (GDestroyNotify) g_type_class_unref);
1060 g_settings_bind (
1061 settings, "hide-completed-tasks",
1062 widget, "sensitive",
1063 G_SETTINGS_BIND_GET);
1065 widget = e_builder_get_widget (prefs->priv->builder, "to_do_bar_show_no_duedate_tasks");
1066 g_settings_bind (
1067 mail_settings, "to-do-bar-show-no-duedate-tasks",
1068 widget, "active",
1069 G_SETTINGS_BIND_DEFAULT);
1071 /* Alarms tab */
1072 widget = e_builder_get_widget (prefs->priv->builder, "notify_with_tray");
1073 g_settings_bind (
1074 settings, "notify-with-tray",
1075 widget, "active",
1076 G_SETTINGS_BIND_DEFAULT);
1078 widget = e_builder_get_widget (prefs->priv->builder, "notify_window_on_top");
1079 g_settings_bind (
1080 settings, "notify-window-on-top",
1081 widget, "active",
1082 G_SETTINGS_BIND_DEFAULT);
1084 widget = e_builder_get_widget (prefs->priv->builder, "task_reminder_for_completed");
1085 g_settings_bind (
1086 settings, "task-reminder-for-completed",
1087 widget, "active",
1088 G_SETTINGS_BIND_DEFAULT);
1090 widget = e_builder_get_widget (prefs->priv->builder, "allow-past-reminders");
1091 g_settings_bind (
1092 settings, "allow-past-reminders",
1093 widget, "active",
1094 G_SETTINGS_BIND_DEFAULT);
1096 widget = e_builder_get_widget (prefs->priv->builder, "default-snooze-minutes-spin");
1097 g_settings_bind (
1098 settings, "default-snooze-minutes",
1099 widget, "value",
1100 G_SETTINGS_BIND_DEFAULT);
1102 prefs->priv->reminder_calendars_scrolled_window = e_builder_get_widget (prefs->priv->builder, "reminder-calendars-scrolled-window");
1103 prefs->priv->reminder_memos_scrolled_window = e_builder_get_widget (prefs->priv->builder, "reminder-memos-scrolled-window");
1104 prefs->priv->reminder_tasks_scrolled_window = e_builder_get_widget (prefs->priv->builder, "reminder-tasks-scrolled-window");
1106 /* Free/Busy tab */
1107 widget = e_builder_get_widget (prefs->priv->builder, "template_url");
1108 g_settings_bind (
1109 settings, "publish-template",
1110 widget, "text",
1111 G_SETTINGS_BIND_DEFAULT);
1113 /* date/time format */
1114 table = e_builder_get_widget (prefs->priv->builder, "datetime_format_table");
1115 e_datetime_format_add_setup_widget (table, 0, "calendar", "table", DTFormatKindDateTime, _("Ti_me and date:"));
1116 e_datetime_format_add_setup_widget (table, 1, "calendar", "table", DTFormatKindDate, _("_Date only:"));
1118 /* Hook up and add the toplevel widget */
1120 target = e_cal_config_target_new_prefs (ec);
1121 e_config_set_target ((EConfig *) ec, (EConfigTarget *) target);
1122 toplevel = e_config_create_widget ((EConfig *) ec);
1123 gtk_box_pack_start (GTK_BOX (prefs), toplevel, TRUE, TRUE, 0);
1125 show_config (prefs);
1126 /* FIXME: weakref? */
1127 setup_changes (prefs);
1129 g_object_unref (mail_settings);
1130 g_object_unref (settings);
1133 void
1134 e_calendar_preferences_type_register (GTypeModule *type_module)
1136 /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
1137 * function, so we have to wrap it with a public function in
1138 * order to register types from a separate compilation unit. */
1139 e_calendar_preferences_register_type (type_module);
1142 GtkWidget *
1143 e_calendar_preferences_new (EPreferencesWindow *window)
1145 EShell *shell;
1146 ESourceRegistry *registry;
1147 ECalendarPreferences *preferences;
1149 shell = e_preferences_window_get_shell (window);
1151 registry = e_shell_get_registry (shell);
1153 g_return_val_if_fail (E_IS_SHELL (shell), NULL);
1155 preferences = g_object_new (E_TYPE_CALENDAR_PREFERENCES, NULL);
1157 preferences->priv->registry = g_object_ref (registry);
1159 /* FIXME Kill this function. */
1160 calendar_preferences_construct (preferences, shell);
1162 return GTK_WIDGET (preferences);