From 1f17dab6b0d9c5413dea38dcc95e7a7bb5b4bd9b Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 2 Nov 2010 11:49:38 -0400 Subject: Move calendar preferences to the calendar module. Continue replacing the use of calendar-config functions with GObject property bindings to EShellSettings properties. --- modules/calendar/e-calendar-preferences.c | 905 ++++++++++++++++++++++++++++++ 1 file changed, 905 insertions(+) create mode 100644 modules/calendar/e-calendar-preferences.c (limited to 'modules/calendar/e-calendar-preferences.c') diff --git a/modules/calendar/e-calendar-preferences.c b/modules/calendar/e-calendar-preferences.c new file mode 100644 index 0000000000..9db9f4538b --- /dev/null +++ b/modules/calendar/e-calendar-preferences.c @@ -0,0 +1,905 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Authors: + * Damon Chaplin + * Ettore Perazzoli + * David Trowbridge + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-calendar-preferences.h" + +#include +#include +#include + +#include "calendar/gui/e-cal-config.h" +#include "calendar/gui/e-timezone-entry.h" +#include "calendar/gui/calendar-config.h" +#include "widgets/misc/e-dateedit.h" +#include "e-util/e-util.h" +#include "e-util/e-datetime-format.h" +#include "e-util/e-dialog-widgets.h" +#include "e-util/e-util-private.h" +#include "shell/e-shell-utils.h" + +/* same is used for Birthdays & Anniversaries calendar */ +static const gint default_reminder_units_map[] = { + E_DURATION_MINUTES, E_DURATION_HOURS, E_DURATION_DAYS, -1 +}; + +G_DEFINE_DYNAMIC_TYPE ( + ECalendarPreferences, + e_calendar_preferences, + GTK_TYPE_VBOX) + +static gboolean +transform_time_divisions_to_index (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer not_used) +{ + gboolean success = TRUE; + + g_return_val_if_fail (G_IS_BINDING (binding), FALSE); + + switch (g_value_get_int (source_value)) { + case 60: + g_value_set_int (target_value, 0); + break; + case 30: + g_value_set_int (target_value, 1); + break; + case 15: + g_value_set_int (target_value, 2); + break; + case 10: + g_value_set_int (target_value, 3); + break; + case 5: + g_value_set_int (target_value, 4); + break; + default: + success = FALSE; + } + + return success; +} + +static gboolean +transform_index_to_time_divisions (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer not_used) +{ + gboolean success = TRUE; + + switch (g_value_get_int (source_value)) { + case 0: + g_value_set_int (target_value, 60); + break; + case 1: + g_value_set_int (target_value, 30); + break; + case 2: + g_value_set_int (target_value, 15); + break; + case 3: + g_value_set_int (target_value, 10); + break; + case 4: + g_value_set_int (target_value, 5); + break; + default: + success = FALSE; + } + + return success; +} + +static void +calendar_preferences_dispose (GObject *object) +{ + ECalendarPreferences *prefs = (ECalendarPreferences *) object; + + if (prefs->builder != NULL) { + g_object_unref (prefs->builder); + prefs->builder = NULL; + } + + if (prefs->shell_settings != NULL) { + g_object_unref (prefs->shell_settings); + prefs->shell_settings = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_calendar_preferences_parent_class)->dispose (object); +} + +static void +e_calendar_preferences_class_init (ECalendarPreferencesClass *class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (class); + object_class->dispose = calendar_preferences_dispose; +} + +static void +e_calendar_preferences_class_finalize (ECalendarPreferencesClass *class) +{ +} + +static void +e_calendar_preferences_init (ECalendarPreferences *preferences) +{ +} + +static GtkWidget * +calendar_preferences_get_config_widget (EConfig *ec, + EConfigItem *item, + GtkWidget *parent, + GtkWidget *old, + gpointer data) +{ + ECalendarPreferences *preferences = data; + + return e_builder_get_widget (preferences->builder, item->label); +} + +static void +update_day_second_zone_caption (ECalendarPreferences *prefs) +{ + gchar *location; + const gchar *caption; + icaltimezone *zone; + + g_return_if_fail (prefs != NULL); + + /* Translators: "None" indicates no second time zone set for a day view */ + caption = C_("cal-second-zone", "None"); + + location = calendar_config_get_day_second_zone (); + if (location && *location) { + zone = icaltimezone_get_builtin_timezone (location); + if (zone && icaltimezone_get_display_name (zone)) { + caption = icaltimezone_get_display_name (zone); + } + } + g_free (location); + + gtk_button_set_label (GTK_BUTTON (prefs->day_second_zone), caption); +} + +static void +on_set_day_second_zone (GtkWidget *item, ECalendarPreferences *prefs) +{ + if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item))) + return; + + calendar_config_set_day_second_zone (g_object_get_data (G_OBJECT (item), "timezone")); + update_day_second_zone_caption (prefs); +} + +static void +on_select_day_second_zone (GtkWidget *item, ECalendarPreferences *prefs) +{ + g_return_if_fail (prefs != NULL); + + calendar_config_select_day_second_zone (); + update_day_second_zone_caption (prefs); +} + +static void +day_second_zone_clicked (GtkWidget *widget, ECalendarPreferences *prefs) +{ + GtkWidget *menu, *item; + GSList *group = NULL, *recent_zones, *s; + gchar *location; + icaltimezone *zone, *second_zone = NULL; + + menu = gtk_menu_new (); + + location = calendar_config_get_day_second_zone (); + if (location && *location) + second_zone = icaltimezone_get_builtin_timezone (location); + g_free (location); + + group = NULL; + item = gtk_radio_menu_item_new_with_label (group, C_("cal-second-zone", "None")); + group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); + if (!second_zone) + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + g_signal_connect (item, "toggled", G_CALLBACK (on_set_day_second_zone), prefs); + + recent_zones = calendar_config_get_day_second_zones (); + for (s = recent_zones; s != NULL; s = s->next) { + zone = icaltimezone_get_builtin_timezone (s->data); + if (!zone) + continue; + + item = gtk_radio_menu_item_new_with_label (group, icaltimezone_get_display_name (zone)); + group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); + /* both comes from builtin, thus no problem to compare pointers */ + if (zone == second_zone) + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + g_object_set_data_full (G_OBJECT (item), "timezone", g_strdup (s->data), g_free); + g_signal_connect (item, "toggled", G_CALLBACK (on_set_day_second_zone), prefs); + } + calendar_config_free_day_second_zones (recent_zones); + + item = gtk_separator_menu_item_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label (_("Select...")); + g_signal_connect (item, "activate", G_CALLBACK (on_select_day_second_zone), prefs); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + gtk_widget_show_all (menu); + + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, + 0, gtk_get_current_event_time ()); +} + +static void +start_of_day_changed (GtkWidget *widget, ECalendarPreferences *prefs) +{ + gint start_hour, start_minute, end_hour, end_minute; + EDateEdit *start, *end; + + start = E_DATE_EDIT (prefs->start_of_day); + end = E_DATE_EDIT (prefs->end_of_day); + + e_date_edit_get_time_of_day (start, &start_hour, &start_minute); + e_date_edit_get_time_of_day (end, &end_hour, &end_minute); + + if ((start_hour > end_hour) || (start_hour == end_hour && start_minute > end_minute)) { + if (start_hour < 23) + e_date_edit_set_time_of_day (end, start_hour + 1, start_minute); + else + e_date_edit_set_time_of_day (end, 23, 59); + + return; + } + + e_shell_settings_set_int ( + prefs->shell_settings, + "cal-work-day-start-hour", start_hour); + e_shell_settings_set_int ( + prefs->shell_settings, + "cal-work-day-start-minute", start_minute); +} + +static void +end_of_day_changed (GtkWidget *widget, ECalendarPreferences *prefs) +{ + gint start_hour, start_minute, end_hour, end_minute; + EDateEdit *start, *end; + + start = E_DATE_EDIT (prefs->start_of_day); + end = E_DATE_EDIT (prefs->end_of_day); + + e_date_edit_get_time_of_day (start, &start_hour, &start_minute); + e_date_edit_get_time_of_day (end, &end_hour, &end_minute); + + if ((end_hour < start_hour) || (end_hour == start_hour && end_minute < start_minute)) { + if (end_hour < 1) + e_date_edit_set_time_of_day (start, 0, 0); + else + e_date_edit_set_time_of_day (start, end_hour - 1, end_minute); + + return; + } + + e_shell_settings_set_int ( + prefs->shell_settings, + "cal-work-day-end-hour", end_hour); + e_shell_settings_set_int ( + prefs->shell_settings, + "cal-work-day-end-minute", end_minute); +} + +static void +notify_with_tray_toggled (GtkToggleButton *toggle, ECalendarPreferences *prefs) +{ + GConfClient *gconf; + + g_return_if_fail (toggle != NULL); + + gconf = gconf_client_get_default (); + gconf_client_set_bool (gconf, "/apps/evolution/calendar/notify/notify_with_tray", gtk_toggle_button_get_active (toggle), NULL); + g_object_unref (gconf); +} + +static void +alarms_selection_changed (ESourceSelector *selector, ECalendarPreferences *prefs) +{ + ESourceList *source_list = prefs->alarms_list; + GSList *selection; + GSList *l; + GSList *groups; + ESource *source; + const gchar *alarm; + + /* first we clear all the alarm flags from all sources */ + for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) { + ESourceGroup *group = E_SOURCE_GROUP (groups->data); + GSList *sources; + for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) { + source = E_SOURCE (sources->data); + + alarm = e_source_get_property (source, "alarm"); + if (alarm && !g_ascii_strcasecmp (alarm, "never")) + continue; + + e_source_set_property (source, "alarm", "false"); + } + } + + /* then we loop over the selector's selection, setting the + property on those sources */ + selection = e_source_selector_get_selection (selector); + for (l = selection; l; l = l->next) { + source = E_SOURCE (l->data); + + alarm = (gchar *)e_source_get_property (source, "alarm"); + if (alarm && !g_ascii_strcasecmp (alarm, "never")) + continue; + + e_source_set_property (E_SOURCE (l->data), "alarm", "true"); + } + e_source_selector_free_selection (selection); + + /* FIXME show an error if this fails? */ + e_source_list_sync (source_list, NULL); +} + +static void +update_system_tz_widgets (EShellSettings *shell_settings, + GParamSpec *pspec, + ECalendarPreferences *prefs) +{ + GtkWidget *widget; + icaltimezone *zone; + const gchar *display_name; + gchar *text; + + widget = e_builder_get_widget (prefs->builder, "system-tz-label"); + g_return_if_fail (GTK_IS_LABEL (widget)); + + zone = e_cal_util_get_system_timezone (); + if (zone != NULL) + display_name = gettext (icaltimezone_get_display_name (zone)); + else + display_name = "UTC"; + + text = g_strdup_printf ("(%s)", display_name); + gtk_label_set_text (GTK_LABEL (widget), text); + g_free (text); +} + +static void +setup_changes (ECalendarPreferences *prefs) +{ + g_signal_connect (G_OBJECT (prefs->day_second_zone), "clicked", G_CALLBACK (day_second_zone_clicked), prefs); + + g_signal_connect (G_OBJECT (prefs->start_of_day), "changed", G_CALLBACK (start_of_day_changed), prefs); + g_signal_connect (G_OBJECT (prefs->end_of_day), "changed", G_CALLBACK (end_of_day_changed), prefs); + + g_signal_connect (G_OBJECT (prefs->notify_with_tray), "toggled", G_CALLBACK (notify_with_tray_toggled), prefs); + g_signal_connect (G_OBJECT (prefs->alarm_list_widget), "selection_changed", G_CALLBACK (alarms_selection_changed), prefs); +} + +static void +initialize_selection (ESourceSelector *selector, ESourceList *source_list) +{ + GSList *groups; + + for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) { + ESourceGroup *group = E_SOURCE_GROUP (groups->data); + GSList *sources; + for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) { + ESource *source = E_SOURCE (sources->data); + const gchar *completion = e_source_get_property (source, "alarm"); + if (!completion || !g_ascii_strcasecmp (completion, "true")) { + if (!completion) + e_source_set_property (E_SOURCE (source), "alarm", "true"); + e_source_selector_select_source (selector, source); + } + } + } +} + +static void +show_alarms_config (ECalendarPreferences *prefs) +{ + GConfClient *gconf; + + if (e_cal_get_sources (&prefs->alarms_list, E_CAL_SOURCE_TYPE_EVENT, NULL)) { + prefs->alarm_list_widget = e_source_selector_new (prefs->alarms_list); + atk_object_set_name (gtk_widget_get_accessible (prefs->alarm_list_widget), _("Selected Calendars for Alarms")); + gtk_container_add (GTK_CONTAINER (prefs->scrolled_window), prefs->alarm_list_widget); + gtk_widget_show (prefs->alarm_list_widget); + initialize_selection (E_SOURCE_SELECTOR (prefs->alarm_list_widget), prefs->alarms_list); + } + + gconf = gconf_client_get_default (); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs->notify_with_tray), gconf_client_get_bool (gconf, "/apps/evolution/calendar/notify/notify_with_tray", NULL)); + g_object_unref (gconf); +} + +/* Shows the current config settings in the dialog. */ +static void +show_config (ECalendarPreferences *prefs) +{ + EShellSettings *shell_settings; + + shell_settings = prefs->shell_settings; + + /* Day's second zone */ + update_day_second_zone_caption (prefs); + + /* Start of Day. */ + e_date_edit_set_time_of_day ( + E_DATE_EDIT (prefs->start_of_day), + e_shell_settings_get_int ( + shell_settings, "cal-work-day-start-hour"), + e_shell_settings_get_int ( + shell_settings, "cal-work-day-start-minute")); + + /* End of Day. */ + e_date_edit_set_time_of_day ( + E_DATE_EDIT (prefs->end_of_day), + e_shell_settings_get_int ( + shell_settings, "cal-work-day-end-hour"), + e_shell_settings_get_int ( + shell_settings, "cal-work-day-end-minute")); + + /* Alarms list */ + show_alarms_config (prefs); +} + +/* plugin meta-data */ +static ECalConfigItem eccp_items[] = { + { E_CONFIG_BOOK, (gchar *) "", (gchar *) "toplevel-notebook", calendar_preferences_get_config_widget }, + { E_CONFIG_PAGE, (gchar *) "00.general", (gchar *) "general", calendar_preferences_get_config_widget }, + { E_CONFIG_SECTION_TABLE, (gchar *) "00.general/00.time", (gchar *) "time", calendar_preferences_get_config_widget }, + { E_CONFIG_SECTION_TABLE, (gchar *) "00.general/10.workWeek", (gchar *) "workWeek", calendar_preferences_get_config_widget }, + { E_CONFIG_SECTION, (gchar *) "00.general/20.alerts", (gchar *) "alerts", calendar_preferences_get_config_widget }, + { E_CONFIG_PAGE, (gchar *) "10.display", (gchar *) "display", calendar_preferences_get_config_widget }, + { E_CONFIG_SECTION, (gchar *) "10.display/00.general", (gchar *) "displayGeneral", calendar_preferences_get_config_widget }, + { E_CONFIG_SECTION, (gchar *) "10.display/10.taskList", (gchar *) "taskList", calendar_preferences_get_config_widget }, + { E_CONFIG_PAGE, (gchar *) "15.alarms", (gchar *) "alarms", calendar_preferences_get_config_widget }, + { E_CONFIG_PAGE, (gchar *) "20.freeBusy", (gchar *) "freebusy", calendar_preferences_get_config_widget }, + { E_CONFIG_SECTION, (gchar *) "20.freeBusy/00.defaultServer", (gchar *) "default-freebusy-vbox", calendar_preferences_get_config_widget }, +}; + +static void +eccp_free (EConfig *ec, GSList *items, gpointer data) +{ + g_slist_free (items); +} + +static void +calendar_preferences_construct (ECalendarPreferences *prefs, + EShell *shell) +{ + ECalConfig *ec; + ECalConfigTargetPrefs *target; + EShellSettings *shell_settings; + gboolean locale_supports_12_hour_format; + gint i; + GtkWidget *toplevel; + GtkWidget *widget; + GtkWidget *table; + GSList *l; + + shell_settings = prefs->shell_settings; + + locale_supports_12_hour_format = + calendar_config_locale_supports_12_hour_format (); + + /* Force 24 hour format for locales which don't support 12 hour format */ + if (!locale_supports_12_hour_format + && !e_shell_settings_get_boolean (shell_settings, "cal-use-24-hour-format")) + e_shell_settings_set_boolean (shell_settings, "cal-use-24-hour-format", TRUE); + + /* Make sure our custom widget classes are registered with + * GType before we load the GtkBuilder definition file. */ + E_TYPE_DATE_EDIT; + E_TYPE_TIMEZONE_ENTRY; + + prefs->builder = gtk_builder_new (); + e_load_ui_builder_definition (prefs->builder, "e-calendar-preferences.ui"); + + /** @HookPoint-ECalConfig: Calendar Preferences Page + * @Id: org.gnome.evolution.calendar.prefs + * @Type: E_CONFIG_BOOK + * @Class: org.gnome.evolution.calendar.config:1.0 + * @Target: ECalConfigTargetPrefs + * + * The mail calendar preferences page + */ + ec = e_cal_config_new (E_CONFIG_BOOK, "org.gnome.evolution.calendar.prefs"); + l = NULL; + for (i = 0; i < G_N_ELEMENTS (eccp_items); i++) + l = g_slist_prepend (l, &eccp_items[i]); + e_config_add_items ((EConfig *) ec, l, NULL, NULL, eccp_free, prefs); + + widget = e_builder_get_widget (prefs->builder, "use-system-tz-check"); + g_object_bind_property ( + shell_settings, "cal-use-system-timezone", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + g_signal_connect ( + shell_settings, "notify::cal-use-system-timezone", + G_CALLBACK (update_system_tz_widgets), prefs); + g_object_notify (G_OBJECT (shell_settings), "cal-use-system-timezone"); + + widget = e_builder_get_widget (prefs->builder, "timezone"); + g_object_bind_property ( + shell_settings, "cal-timezone", + widget, "timezone", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + g_object_bind_property ( + shell_settings, "cal-use-system-timezone", + widget, "sensitive", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE | + G_BINDING_INVERT_BOOLEAN); + + /* General tab */ + prefs->day_second_zone = e_builder_get_widget (prefs->builder, "day_second_zone"); + + widget = e_builder_get_widget (prefs->builder, "sun_button"); + g_object_bind_property ( + shell_settings, "cal-working-days-sunday", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "mon_button"); + g_object_bind_property ( + shell_settings, "cal-working-days-monday", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "tue_button"); + g_object_bind_property ( + shell_settings, "cal-working-days-tuesday", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "wed_button"); + g_object_bind_property ( + shell_settings, "cal-working-days-wednesday", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "thu_button"); + g_object_bind_property ( + shell_settings, "cal-working-days-thursday", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "fri_button"); + g_object_bind_property ( + shell_settings, "cal-working-days-friday", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "sat_button"); + g_object_bind_property ( + shell_settings, "cal-working-days-saturday", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "week_start_day"); + g_object_bind_property ( + shell_settings, "cal-week-start-day", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "start_of_day"); + prefs->start_of_day = widget; /* XXX delete this */ + if (locale_supports_12_hour_format) + g_object_bind_property ( + shell_settings, "cal-use-24-hour-format", + widget, "use-24-hour-format", + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "end_of_day"); + prefs->end_of_day = widget; /* XXX delete this */ + if (locale_supports_12_hour_format) + g_object_bind_property ( + shell_settings, "cal-use-24-hour-format", + widget, "use-24-hour-format", + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "use_12_hour"); + gtk_widget_set_sensitive (widget, locale_supports_12_hour_format); + g_object_bind_property ( + shell_settings, "cal-use-24-hour-format", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE | + G_BINDING_INVERT_BOOLEAN); + + widget = e_builder_get_widget (prefs->builder, "use_24_hour"); + gtk_widget_set_sensitive (widget, locale_supports_12_hour_format); + g_object_bind_property ( + shell_settings, "cal-use-24-hour-format", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "confirm_delete"); + g_object_bind_property ( + shell_settings, "cal-confirm-delete", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "default_reminder"); + g_object_bind_property ( + shell_settings, "cal-use-default-reminder", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "default_reminder_interval"); + g_object_bind_property ( + shell_settings, "cal-default-reminder-interval", + widget, "value", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + g_object_bind_property ( + shell_settings, "cal-use-default-reminder", + widget, "sensitive", + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "default_reminder_units"); + g_object_bind_property ( + shell_settings, "cal-default-reminder-units", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + g_object_bind_property ( + shell_settings, "cal-use-default-reminder", + widget, "sensitive", + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "ba_reminder"); + g_object_bind_property ( + shell_settings, "cal-use-ba-reminder", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "ba_reminder_interval"); + g_object_bind_property ( + shell_settings, "cal-ba-reminder-interval", + widget, "value", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + g_object_bind_property ( + shell_settings, "cal-use-ba-reminder", + widget, "sensitive", + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "ba_reminder_units"); + g_object_bind_property ( + shell_settings, "cal-ba-reminder-units", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + g_object_bind_property ( + shell_settings, "cal-use-ba-reminder", + widget, "sensitive", + G_BINDING_SYNC_CREATE); + + /* Display tab */ + widget = e_builder_get_widget (prefs->builder, "time_divisions"); + g_object_bind_property_full ( + shell_settings, "cal-time-divisions", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE, + transform_time_divisions_to_index, + transform_index_to_time_divisions, + NULL, (GDestroyNotify) NULL); + + widget = e_builder_get_widget (prefs->builder, "show_end_times"); + g_object_bind_property ( + shell_settings, "cal-show-event-end-times", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "compress_weekend"); + g_object_bind_property ( + shell_settings, "cal-compress-weekend", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "show_week_numbers"); + g_object_bind_property ( + shell_settings, "cal-show-week-numbers", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "recur_events_italic"); + g_object_bind_property ( + shell_settings, "cal-recur-events-italic", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "month_scroll_by_week"); + g_object_bind_property ( + shell_settings, "cal-month-scroll-by-week", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "tasks_due_today_color"); + g_object_bind_property_full ( + shell_settings, "cal-tasks-color-due-today", + widget, "color", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE, + e_binding_transform_string_to_color, + e_binding_transform_color_to_string, + NULL, (GDestroyNotify) NULL); + + widget = e_builder_get_widget (prefs->builder, "tasks_overdue_color"); + g_object_bind_property_full ( + shell_settings, "cal-tasks-color-overdue", + widget, "color", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE, + e_binding_transform_string_to_color, + e_binding_transform_color_to_string, + (GDestroyNotify) NULL, NULL); + + widget = e_builder_get_widget (prefs->builder, "tasks_hide_completed"); + g_object_bind_property ( + shell_settings, "cal-hide-completed-tasks", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "tasks_hide_completed_interval"); + g_object_bind_property ( + shell_settings, "cal-hide-completed-tasks-value", + widget, "value", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + g_object_bind_property ( + shell_settings, "cal-hide-completed-tasks", + widget, "sensitive", + G_BINDING_SYNC_CREATE); + + widget = e_builder_get_widget (prefs->builder, "tasks_hide_completed_units"); + g_object_bind_property ( + shell_settings, "cal-hide-completed-tasks-units", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + g_object_bind_property ( + shell_settings, "cal-hide-completed-tasks", + widget, "sensitive", + G_BINDING_SYNC_CREATE); + + /* Alarms tab */ + prefs->notify_with_tray = e_builder_get_widget (prefs->builder, "notify_with_tray"); + prefs->scrolled_window = e_builder_get_widget (prefs->builder, "calendar-source-scrolled-window"); + + /* Free/Busy tab */ + widget = e_builder_get_widget (prefs->builder, "template_url"); + g_object_bind_property ( + shell_settings, "cal-free-busy-template", + widget, "text", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + /* date/time format */ + table = e_builder_get_widget (prefs->builder, "datetime_format_table"); + e_datetime_format_add_setup_widget (table, 0, "calendar", "table", DTFormatKindDateTime, _("Ti_me and date:")); + e_datetime_format_add_setup_widget (table, 1, "calendar", "table", DTFormatKindDate, _("_Date only:")); + + /* Hide senseless preferences when running in Express mode */ + e_shell_hide_widgets_for_express_mode (shell, prefs->builder, + "label_second_zone", + "hbox_second_zone", + "timezone", + "timezone_label", + "hbox_use_system_timezone", + "hbox_time_divisions", + "show_end_times", + "month_scroll_by_week", + NULL); + + /* HACK: GTK+ 2.18 and 2.20 has a GtkTable which includes + * row/column spacing even for empty rows/columns. + * When Evo runs in Express mode, we hide all the rows in + * the Time section of the calendar's General preferences + * page. However, due to that behavior in GTK+, we get a + * lot of extra spacing in that section. Since we know that + * in Express mode we only leave a single row visible, we'll + * make the table's row spacing equal to 0 in that case. */ + if (e_shell_get_express_mode (shell)) { + widget = e_builder_get_widget (prefs->builder, "time"); + gtk_table_set_row_spacings (GTK_TABLE (widget), 0); + } + + /* Hook up and add the toplevel widget */ + + target = e_cal_config_target_new_prefs (ec); + e_config_set_target ((EConfig *)ec, (EConfigTarget *) target); + toplevel = e_config_create_widget ((EConfig *)ec); + gtk_container_add (GTK_CONTAINER (prefs), toplevel); + + show_config (prefs); + /* FIXME: weakref? */ + setup_changes (prefs); +} + +void +e_calendar_preferences_type_register (GTypeModule *type_module) +{ + /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration + * function, so we have to wrap it with a public function in + * order to register types from a separate compilation unit. */ + e_calendar_preferences_register_type (type_module); +} + +GtkWidget * +e_calendar_preferences_new (EPreferencesWindow *window) +{ + EShell *shell; + EShellSettings *shell_settings; + ECalendarPreferences *preferences; + + shell = e_preferences_window_get_shell (window); + shell_settings = e_shell_get_shell_settings (shell); + + g_return_val_if_fail (E_IS_SHELL (shell), NULL); + + preferences = g_object_new (E_TYPE_CALENDAR_PREFERENCES, NULL); + + preferences->shell_settings = g_object_ref (shell_settings); + + /* FIXME Kill this function. */ + calendar_preferences_construct (preferences, shell); + + return GTK_WIDGET (preferences); +} -- cgit v1.2.3