evolution r37060 - in trunk/calendar: . gui gui/dialogs



Author: mcrha
Date: Mon Jan 12 14:49:16 2009
New Revision: 37060
URL: http://svn.gnome.org/viewvc/evolution?rev=37060&view=rev

Log:
2009-01-12  Milan Crha  <mcrha redhat com>

	** Fix for bug #563364

	* gui/e-day-view-time-item.h: (EDayViewTimeItem):
	* gui/e-day-view-time-item.c: (e_day_view_time_item_class_init),
	(e_day_view_time_item_init), (e_day_view_time_item_finalize),
	(e_day_view_time_item_get_column_width), (edvti_draw_zone),
	(e_day_view_time_item_draw), (edvti_second_zone_changed_cb),
	(edvti_on_select_zone), (edvti_on_set_zone),
	(e_day_view_time_item_show_popup_menu):
	Show two timezones in the day view's time column.

	* gui/apps_evolution_calendar.schemas.in:
	* gui/calendar-config-keys.h:
	* gui/calendar-config.h:
	* gui/calendar-config.c: (calendar_config_get_day_second_zones),
	(calendar_config_free_day_second_zones),
	(calendar_config_set_day_second_zone),
	(calendar_config_get_day_second_zone),
	(calendar_config_select_day_second_zone),
	(calendar_config_add_notification_day_second_zone):
	Access configuration for the second day time zone.

	* gui/dialogs/cal-prefs-dialog.glade:
	* gui/dialogs/cal-prefs-dialog.h: (struct _CalendarPrefsDialog):
	* gui/dialogs/cal-prefs-dialog.c: (update_day_second_zone_caption),
	(on_set_day_second_zone), (on_select_day_second_zone),
	(day_second_zone_clicked), (setup_changes), (show_config),
	(calendar_prefs_dialog_construct):
	Manage the second day zone in a Preferences dialog.



Modified:
   trunk/calendar/ChangeLog
   trunk/calendar/gui/apps_evolution_calendar.schemas.in
   trunk/calendar/gui/calendar-config-keys.h
   trunk/calendar/gui/calendar-config.c
   trunk/calendar/gui/calendar-config.h
   trunk/calendar/gui/dialogs/cal-prefs-dialog.c
   trunk/calendar/gui/dialogs/cal-prefs-dialog.glade
   trunk/calendar/gui/dialogs/cal-prefs-dialog.h
   trunk/calendar/gui/e-day-view-time-item.c
   trunk/calendar/gui/e-day-view-time-item.h

Modified: trunk/calendar/gui/apps_evolution_calendar.schemas.in
==============================================================================
--- trunk/calendar/gui/apps_evolution_calendar.schemas.in	(original)
+++ trunk/calendar/gui/apps_evolution_calendar.schemas.in	Mon Jan 12 14:49:16 2009
@@ -16,6 +16,43 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/evolution/calendar/display/day_second_zone</key>
+      <applyto>/apps/evolution/calendar/display/day_second_zone</applyto>
+      <owner>evolution-calendar</owner>
+      <type>string</type>
+      <default></default>
+      <locale name="C">
+        <short>The second timezone for a Day View</short>
+        <long>Shows the second time zone in a Day View, if set. Value is similar to one used in a 'timezone' key.</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/evolution/calendar/display/day_second_zones</key>
+      <applyto>/apps/evolution/calendar/display/day_second_zones</applyto>
+      <owner>evolution-calendar</owner>
+      <type>list</type>
+      <list_type>string</list_type>
+      <default>[]</default>
+      <locale name="C">
+        <short>Recently used second time zones in a Day View</short>
+        <long>List of recently used second time zones in a Day View.</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/evolution/calendar/display/day_second_zones_max</key>
+      <applyto>/apps/evolution/calendar/display/day_second_zones_max</applyto>
+      <owner>evolution-calendar</owner>
+      <type>int</type>
+      <default>5</default>
+      <locale name="C">
+        <short>Maximum number of recently used timezones to remember.</short>
+        <long>Maximum number of recently used timezones to remember in a 'day_second_zones' list.</long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/evolution/calendar/display/use_daylight_saving</key>
       <applyto>/apps/evolution/calendar/display/use_daylight_saving</applyto>
       <owner>evolution-calendar</owner>

Modified: trunk/calendar/gui/calendar-config-keys.h
==============================================================================
--- trunk/calendar/gui/calendar-config-keys.h	(original)
+++ trunk/calendar/gui/calendar-config-keys.h	Mon Jan 12 14:49:16 2009
@@ -61,6 +61,9 @@
 #define CALENDAR_CONFIG_COMPRESS_WEEKEND CALENDAR_CONFIG_PREFIX "/display/compress_weekend"
 #define CALENDAR_CONFIG_SHOW_EVENT_END CALENDAR_CONFIG_PREFIX "/display/show_event_end"
 #define CALENDAR_CONFIG_WORKING_DAYS CALENDAR_CONFIG_PREFIX "/display/working_days"
+#define CALENDAR_CONFIG_DAY_SECOND_ZONE CALENDAR_CONFIG_PREFIX "/display/day_second_zone"
+#define CALENDAR_CONFIG_DAY_SECOND_ZONES_LIST CALENDAR_CONFIG_PREFIX "/display/day_second_zones"
+#define CALENDAR_CONFIG_DAY_SECOND_ZONES_MAX CALENDAR_CONFIG_PREFIX "/display/day_second_zones_max"
 
 /* Date navigator settings */
 #define CALENDAR_CONFIG_DN_SHOW_WEEK_NUMBERS CALENDAR_CONFIG_PREFIX "/date_navigator/show_week_numbers"

Modified: trunk/calendar/gui/calendar-config.c
==============================================================================
--- trunk/calendar/gui/calendar-config.c	(original)
+++ trunk/calendar/gui/calendar-config.c	Mon Jan 12 14:49:16 2009
@@ -1567,3 +1567,132 @@
 
 	return path;
 }
+
+/* contains list of strings, locations, recently used as the second timezone in a day view.
+   Free with calendar_config_free_day_second_zones. */
+GSList *
+calendar_config_get_day_second_zones (void)
+{
+	GSList *res;
+
+	calendar_config_init ();
+
+	res = gconf_client_get_list (config, CALENDAR_CONFIG_DAY_SECOND_ZONES_LIST, GCONF_VALUE_STRING, NULL);
+
+	return res;
+}
+
+/* frees list from calendar_config_get_day_second_zones */
+void
+calendar_config_free_day_second_zones (GSList *zones)
+{
+	if (zones) {
+		g_slist_foreach (zones, (GFunc)g_free, NULL);
+		g_slist_free (zones);
+	}
+}
+
+/* keeps max 'day_second_zones_max' zones, if 'location' is already in a list, then it'll became first there */
+void
+calendar_config_set_day_second_zone (const char *location)
+{
+	calendar_config_init ();
+
+	if (location && *location) {
+		GSList *lst, *l;
+		GError *error = NULL;
+		int max_zones;
+
+		/* configurable max number of timezones to remember */
+		max_zones = gconf_client_get_int (config, CALENDAR_CONFIG_DAY_SECOND_ZONES_MAX, &error);
+
+		if (error) {
+			g_error_free (error);
+			max_zones = -1;
+		}
+
+		if (max_zones <= 0)
+			max_zones = 5;
+
+		lst = calendar_config_get_day_second_zones ();
+		for (l = lst; l; l = l->next) {
+			if (l->data && g_str_equal (l->data, location)) {
+				if (l != lst) {
+					/* isn't first in the list */
+					char *val = l->data;
+
+					lst = g_slist_remove (lst, val);
+					lst = g_slist_prepend (lst, val);
+				}
+				break;
+			}
+		}
+
+		if (!l) {
+			/* not in the list yet */
+			lst = g_slist_prepend (lst, g_strdup (location));
+		}
+
+		while (g_slist_length (lst) > max_zones) {
+			l = g_slist_last (lst);
+			g_free (l->data);
+			lst = g_slist_delete_link (lst, l);
+		}
+
+		gconf_client_set_list (config, CALENDAR_CONFIG_DAY_SECOND_ZONES_LIST, GCONF_VALUE_STRING, lst, NULL);
+
+		calendar_config_free_day_second_zones (lst);
+	}
+
+	gconf_client_set_string (config, CALENDAR_CONFIG_DAY_SECOND_ZONE, location ? location : "", NULL);
+}
+
+/* location of the second time zone user has selected. Free with g_free. */
+char *
+calendar_config_get_day_second_zone (void)
+{
+	calendar_config_init ();
+
+	return gconf_client_get_string (config, CALENDAR_CONFIG_DAY_SECOND_ZONE, NULL);
+}
+
+void
+calendar_config_select_day_second_zone (void)
+{
+	icaltimezone *zone = NULL;
+	ETimezoneDialog *tzdlg;
+	GtkWidget *dialog;
+	char *second_location;
+
+	second_location = calendar_config_get_day_second_zone ();
+	if (second_location && *second_location)
+		zone = icaltimezone_get_builtin_timezone (second_location);
+	g_free (second_location);
+
+	if (!zone)
+		zone = calendar_config_get_icaltimezone ();
+
+	tzdlg = e_timezone_dialog_new ();
+	e_timezone_dialog_set_timezone (tzdlg, zone);
+
+	dialog = e_timezone_dialog_get_toplevel (tzdlg);
+
+	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+		zone = e_timezone_dialog_get_timezone (tzdlg);
+		calendar_config_set_day_second_zone (zone ? icaltimezone_get_location (zone) : NULL);
+	}
+
+	g_object_unref (tzdlg);
+}
+
+guint
+calendar_config_add_notification_day_second_zone (GConfClientNotifyFunc func, gpointer data)
+{
+	guint id;
+
+	calendar_config_init ();
+
+	id = gconf_client_notify_add (config, CALENDAR_CONFIG_DAY_SECOND_ZONE, func, data, NULL, NULL);
+
+	return id;
+}

Modified: trunk/calendar/gui/calendar-config.h
==============================================================================
--- trunk/calendar/gui/calendar-config.h	(original)
+++ trunk/calendar/gui/calendar-config.h	Mon Jan 12 14:49:16 2009
@@ -258,4 +258,11 @@
 void calendar_config_set_daylight_saving (gboolean daylight_saving);
 guint calendar_config_add_notification_daylight_saving (GConfClientNotifyFunc func, gpointer data);
 
+GSList *calendar_config_get_day_second_zones (void);
+void    calendar_config_free_day_second_zones (GSList *zones);
+void    calendar_config_set_day_second_zone (const char *location);
+char *  calendar_config_get_day_second_zone (void);
+void    calendar_config_select_day_second_zone (void);
+guint   calendar_config_add_notification_day_second_zone (GConfClientNotifyFunc func, gpointer data);
+
 #endif /* _CALENDAR_CONFIG_H_ */

Modified: trunk/calendar/gui/dialogs/cal-prefs-dialog.c
==============================================================================
--- trunk/calendar/gui/dialogs/cal-prefs-dialog.c	(original)
+++ trunk/calendar/gui/dialogs/cal-prefs-dialog.c	Mon Jan 12 14:49:16 2009
@@ -132,6 +132,101 @@
 }
 
 static void
+update_day_second_zone_caption (CalendarPrefsDialog *prefs)
+{
+	char *location;
+	const char *caption;
+	icaltimezone *zone;
+
+	g_return_if_fail (prefs != NULL);
+
+	caption = _("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, CalendarPrefsDialog *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, CalendarPrefsDialog *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, CalendarPrefsDialog *prefs)
+{
+	GtkWidget *menu, *item;
+	GSList *group = NULL, *recent_zones, *s;
+	char *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, _("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
 daylight_saving_changed (GtkWidget *widget, CalendarPrefsDialog *prefs)
 {
 	gboolean set = gtk_toggle_button_get_active ((GtkToggleButton *) prefs->daylight_saving);
@@ -373,6 +468,7 @@
 		g_signal_connect (G_OBJECT (prefs->working_days[i]), "toggled", G_CALLBACK (working_days_changed), prefs);
 
 	g_signal_connect (G_OBJECT (prefs->timezone), "changed", G_CALLBACK (timezone_changed), prefs);
+	g_signal_connect (G_OBJECT (prefs->day_second_zone), "clicked", G_CALLBACK (day_second_zone_clicked), prefs);
 	g_signal_connect (G_OBJECT (prefs->daylight_saving), "toggled", G_CALLBACK (daylight_saving_changed), prefs);
 
 	g_signal_connect (G_OBJECT (prefs->start_of_day), "changed", G_CALLBACK (start_of_day_changed), prefs);
@@ -513,6 +609,9 @@
 	set = calendar_config_get_daylight_saving ();
 	gtk_toggle_button_set_active ((GtkToggleButton *) prefs->daylight_saving, set);
 
+	/* Day's second zone */
+	update_day_second_zone_caption (prefs);
+
 	/* Working Days. */
 	working_days = calendar_config_get_working_days ();
 	mask = 1 << 0;
@@ -637,6 +736,7 @@
 
 	/* General tab */
 	prefs->timezone = glade_xml_get_widget (gui, "timezone");
+	prefs->day_second_zone = glade_xml_get_widget (gui, "day_second_zone");
 	prefs->daylight_saving = glade_xml_get_widget (gui, "daylight_cb");
 	for (i = 0; i < 7; i++)
 		prefs->working_days[i] = glade_xml_get_widget (gui, working_day_names[i]);

Modified: trunk/calendar/gui/dialogs/cal-prefs-dialog.glade
==============================================================================
--- trunk/calendar/gui/dialogs/cal-prefs-dialog.glade	(original)
+++ trunk/calendar/gui/dialogs/cal-prefs-dialog.glade	Mon Jan 12 14:49:16 2009
@@ -6,7 +6,7 @@
 
 <widget class="GtkWindow" id="window1">
   <property name="visible">True</property>
-  <property name="title" translatable="no">window1</property>
+  <property name="title">window1</property>
   <property name="type">GTK_WINDOW_TOPLEVEL</property>
   <property name="window_position">GTK_WIN_POS_NONE</property>
   <property name="modal">False</property>
@@ -96,46 +96,37 @@
 	      <child>
 		<widget class="GtkTable" id="time">
 		  <property name="visible">True</property>
-		  <property name="n_rows">3</property>
+		  <property name="n_rows">4</property>
 		  <property name="n_columns">2</property>
 		  <property name="homogeneous">False</property>
 		  <property name="row_spacing">6</property>
 		  <property name="column_spacing">6</property>
 
 		  <child>
-		    <widget class="GtkLabel" id="timezone_label">
+		    <widget class="Custom" id="timezone">
 		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Time _zone:</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-      		      <property name="mnemonic_widget">timezone</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
+		      <property name="creation_function">make_timezone_entry</property>
+		      <property name="int1">0</property>
+		      <property name="int2">0</property>
+		      <property name="last_modification_time">Thu, 13 Jan 2005 04:18:03 GMT</property>
+		      <accessibility>
+			<atkrelation target="timezone_label" type="labelled-by"/>
+		      </accessibility>
 		    </widget>
 		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
 		      <property name="top_attach">0</property>
 		      <property name="bottom_attach">1</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
+		      <property name="y_options">fill</property>
 		    </packing>
 		  </child>
 
 		  <child>
-		    <widget class="GtkLabel" id="label11">
+		    <widget class="GtkLabel" id="timezone_label">
 		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Time format:</property>
-		      <property name="use_underline">False</property>
+		      <property name="label" translatable="yes">Time _zone:</property>
+		      <property name="use_underline">True</property>
 		      <property name="use_markup">False</property>
 		      <property name="justify">GTK_JUSTIFY_LEFT</property>
 		      <property name="wrap">False</property>
@@ -144,6 +135,7 @@
 		      <property name="yalign">0.5</property>
 		      <property name="xpad">0</property>
 		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">timezone</property>
 		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
 		      <property name="width_chars">-1</property>
 		      <property name="single_line_mode">False</property>
@@ -152,30 +144,32 @@
 		    <packing>
 		      <property name="left_attach">0</property>
 		      <property name="right_attach">1</property>
-		      <property name="top_attach">2</property>
-		      <property name="bottom_attach">3</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
 		      <property name="x_options">fill</property>
 		      <property name="y_options"></property>
 		    </packing>
 		  </child>
 
 		  <child>
-		    <widget class="Custom" id="timezone">
+		    <widget class="GtkCheckButton" id="daylight_cb">
 		      <property name="visible">True</property>
-		      <property name="creation_function">make_timezone_entry</property>
-		      <property name="int1">0</property>
-		      <property name="int2">0</property>
-		      <property name="last_modification_time">Thu, 13 Jan 2005 04:18:03 GMT</property>
-		      <accessibility>
-			<atkrelation target="timezone_label" type="labelled-by"/>
-		      </accessibility>
+		      <property name="can_focus">True</property>
+		      <property name="label" translatable="yes">Adjust for daylight sa_ving time</property>
+		      <property name="use_underline">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		      <property name="active">False</property>
+		      <property name="inconsistent">False</property>
+		      <property name="draw_indicator">True</property>
 		    </widget>
 		    <packing>
 		      <property name="left_attach">1</property>
 		      <property name="right_attach">2</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="y_options">fill</property>
+		      <property name="top_attach">1</property>
+		      <property name="bottom_attach">2</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
 		    </packing>
 		  </child>
 
@@ -235,24 +229,116 @@
 		  </child>
 
 		  <child>
-		    <widget class="GtkCheckButton" id="daylight_cb">
+		    <widget class="GtkLabel" id="label11">
 		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">Adjust for daylight sa_ving time</property>
+		      <property name="label" translatable="yes">Time format:</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">2</property>
+		      <property name="bottom_attach">3</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label63">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Se_cond zone:</property>
 		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		      <property name="active">False</property>
-		      <property name="inconsistent">False</property>
-		      <property name="draw_indicator">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">day_second_zone</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">3</property>
+		      <property name="bottom_attach">4</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox25">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkButton" id="day_second_zone">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">None</property>
+			  <property name="use_underline">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label64">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">(Shown in a Day View)</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">6</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
 		    </widget>
 		    <packing>
 		      <property name="left_attach">1</property>
 		      <property name="right_attach">2</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
+		      <property name="top_attach">3</property>
+		      <property name="bottom_attach">4</property>
 		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
+		      <property name="y_options">fill</property>
 		    </packing>
 		  </child>
 		</widget>
@@ -348,7 +434,7 @@
 		      <property name="yalign">0.5</property>
 		      <property name="xpad">0</property>
 		      <property name="ypad">0</property>
-      		      <property name="mnemonic_widget">week_start_day</property>
+		      <property name="mnemonic_widget">week_start_day</property>
 		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
 		      <property name="width_chars">-1</property>
 		      <property name="single_line_mode">False</property>
@@ -405,7 +491,7 @@
 		      <property name="yalign">0.5</property>
 		      <property name="xpad">0</property>
 		      <property name="ypad">0</property>
-      		      <property name="mnemonic_widget">start_of_day</property>
+		      <property name="mnemonic_widget">start_of_day</property>
 		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
 		      <property name="width_chars">-1</property>
 		      <property name="single_line_mode">False</property>

Modified: trunk/calendar/gui/dialogs/cal-prefs-dialog.h
==============================================================================
--- trunk/calendar/gui/dialogs/cal-prefs-dialog.h	(original)
+++ trunk/calendar/gui/dialogs/cal-prefs-dialog.h	Mon Jan 12 14:49:16 2009
@@ -44,6 +44,7 @@
 
 	/* General tab */
 	GtkWidget *timezone;
+	GtkWidget *day_second_zone;
 	GtkWidget *daylight_saving;
 	GtkWidget *working_days[7];
 	GtkWidget *week_start_day;

Modified: trunk/calendar/gui/e-day-view-time-item.c
==============================================================================
--- trunk/calendar/gui/e-day-view-time-item.c	(original)
+++ trunk/calendar/gui/e-day-view-time-item.c	Mon Jan 12 14:49:16 2009
@@ -32,6 +32,8 @@
 #include "e-day-view-time-item.h"
 #include "calendar-config.h"
 #include <libecal/e-cal-time-util.h>
+#include <widgets/e-timezone-dialog/e-timezone-dialog.h>
+#include <libedataserver/e-data-server-util.h>
 
 
 /* The spacing between items in the time column. GRID_X_PAD is the space down
@@ -59,6 +61,8 @@
                                                const GValue *value,
                                                GParamSpec *pspec);
 
+static void e_day_view_time_item_finalize (GObject *object);
+
 static void e_day_view_time_item_update (GnomeCanvasItem *item,
 					 double *affine,
 					 ArtSVP *clip_path, int flags);
@@ -88,7 +92,7 @@
 static gint e_day_view_time_item_convert_position_to_row (EDayViewTimeItem *dvtmitem,
 							  gint y);
 
-
+static void  edvti_second_zone_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data);
 /* The arguments we take */
 enum {
 	PROP_0,
@@ -105,6 +109,7 @@
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->set_property = e_day_view_time_item_set_property;
+	object_class->finalize = e_day_view_time_item_finalize;
 
 	item_class = GNOME_CANVAS_ITEM_CLASS (class);
 	item_class->update = e_day_view_time_item_update;
@@ -126,9 +131,21 @@
 static void
 e_day_view_time_item_init (EDayViewTimeItem *dvtmitem)
 {
+	char *last;
+
 	dvtmitem->dragging_selection = FALSE;
-}
+	dvtmitem->second_zone = NULL;
+
+	last = calendar_config_get_day_second_zone();
 
+	if (last) {
+		if (*last)
+			dvtmitem->second_zone = icaltimezone_get_builtin_timezone (last);
+		g_free (last);
+	}
+
+	dvtmitem->second_zone_changed_id = calendar_config_add_notification_day_second_zone (edvti_second_zone_changed_cb, dvtmitem);
+}
 
 static void
 e_day_view_time_item_set_property (GObject *object,
@@ -149,6 +166,20 @@
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
 
+static void
+e_day_view_time_item_finalize (GObject *object)
+{
+	EDayViewTimeItem *dvtmitem;
+
+	dvtmitem = E_DAY_VIEW_TIME_ITEM (object);
+
+	if (dvtmitem->second_zone_changed_id)
+		calendar_config_remove_notification (dvtmitem->second_zone_changed_id);
+	dvtmitem->second_zone_changed_id = 0;
+
+	if (G_OBJECT_CLASS (e_day_view_time_item_parent_class)->finalize)
+		G_OBJECT_CLASS (e_day_view_time_item_parent_class)->finalize (object);
+}
 
 static void
 e_day_view_time_item_update (GnomeCanvasItem *item,
@@ -229,6 +260,10 @@
 
 	dvtmitem->column_width = MAX (column_width_default,
 				      column_width_60_min_rows);
+
+	if (dvtmitem->second_zone)
+		return (2 * dvtmitem->column_width) - E_DVTMI_TIME_GRID_X_PAD;
+
 	return dvtmitem->column_width;
 }
 
@@ -237,17 +272,19 @@
  * DRAWING ROUTINES - functions to paint the canvas item.
  */
 static void
-e_day_view_time_item_draw (GnomeCanvasItem *canvas_item,
-			   GdkDrawable	   *drawable,
-			   int		    x,
-			   int		    y,
-			   int		    width,
-			   int		    height)
+edvti_draw_zone (GnomeCanvasItem   *canvas_item,
+		GdkDrawable	   *drawable,
+		int		    x,
+		int		    y,
+		int		    width,
+		int		    height,
+		int		    x_offset,
+		icaltimezone       *use_zone)
 {
 	EDayView *day_view;
 	EDayViewTimeItem *dvtmitem;
 	GtkStyle *style;
-	gchar buffer[64], *suffix;
+	gchar buffer[64], *suffix, *midnight_day = NULL, *midnight_month = NULL;
 	gint hour, display_hour, minute, row;
 	gint row_y, start_y, large_hour_y_offset, small_font_y_offset;
 	gint long_line_x1, long_line_x2, short_line_x1;
@@ -260,6 +297,7 @@
 	PangoFontMetrics *large_font_metrics, *small_font_metrics;
 	cairo_t *cr;
 	GdkColor fg, dark;
+	GdkColor mb_color;
 
 	cr = gdk_cairo_create (drawable);
 
@@ -280,8 +318,8 @@
 	dark = style->dark[GTK_STATE_NORMAL];
 
 	/* The start and end of the long horizontal line between hours. */
-	long_line_x1 = E_DVTMI_TIME_GRID_X_PAD - x;
-	long_line_x2 = dvtmitem->column_width - E_DVTMI_TIME_GRID_X_PAD - x;
+	long_line_x1 = (use_zone ? 0 : E_DVTMI_TIME_GRID_X_PAD) - x + x_offset;
+	long_line_x2 = dvtmitem->column_width - E_DVTMI_TIME_GRID_X_PAD - x - (use_zone ? E_DVTMI_TIME_GRID_X_PAD : 0) + x_offset;
 
 	if (day_view->mins_per_row == 60) {
 		/* The right edge of the complete time string in 60-min
@@ -315,6 +353,51 @@
 	hour = day_view->first_hour_shown;
 	minute = day_view->first_minute_shown;
 
+	if (use_zone) {
+		/* shift time with a difference between local time and the other timezone */
+		icaltimezone *cal_zone = e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view));
+		struct icaltimetype tt;
+		int diff;
+		struct tm mn;
+
+		tt = icaltime_today ();
+
+		/* diff is number of minutes */
+		diff = (icaltimezone_get_utc_offset (use_zone, &tt, NULL) -
+		        icaltimezone_get_utc_offset (cal_zone, &tt, NULL)
+		       ) / 60;
+
+		tt = icaltime_today ();
+		tt.is_date = FALSE;
+		icaltime_set_timezone (&tt, cal_zone);
+		tt = icaltime_convert_to_zone (tt, use_zone);
+
+		if (diff != 0) {
+			/* shows the next midnight */
+			icaltime_adjust (&tt, 1, 0, 0, 0);
+		}
+
+		mn = icaltimetype_to_tm (&tt);
+
+		/* up to two characters/numbers */
+		e_utf8_strftime (buffer, sizeof (buffer), "%d", &mn);
+		midnight_day = g_strdup (buffer);
+		/* up to three characters, abbreviated month name */
+		e_utf8_strftime (buffer, sizeof (buffer), "%b", &mn);
+		midnight_month = g_strdup (buffer);
+
+		minute += (diff % 60);
+		hour += (diff / 60) + (minute / 60);
+
+		minute = minute % 60;
+		if (minute < 0) {
+			hour--;
+			minute += 60;
+		}
+
+		hour = (hour + 48) % 24;
+	}
+
 	/* The offset of the large hour string from the top of the row. */
 	large_hour_y_offset = E_DVTMI_LARGE_HOUR_Y_PAD;
 
@@ -333,7 +416,6 @@
 	if (e_day_view_get_show_marcus_bains (day_view)) {
 		struct icaltimetype time_now;
 		int marcus_bains_y;
-		GdkColor mb_color;
 
 		cairo_save (cr);
 		gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_MARCUS_BAINS_LINE]);
@@ -345,15 +427,27 @@
 			if (gdk_colormap_alloc_color (colormap, &mb_color, TRUE, TRUE)) {
 				gdk_cairo_set_source_color (cr, &mb_color);
 			}
-		}
+		} else
+			mb_color = day_view->colors[E_DAY_VIEW_COLOR_MARCUS_BAINS_LINE];
 
 		time_now = icaltime_current_time_with_zone (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
 		marcus_bains_y = (time_now.hour * 60 + time_now.minute) * day_view->row_height / day_view->mins_per_row - y;
 		cairo_set_line_width (cr, 1.5);
-		cairo_move_to (cr, long_line_x1, marcus_bains_y);
+		cairo_move_to (cr, long_line_x1 - (use_zone ? E_DVTMI_TIME_GRID_X_PAD : 0), marcus_bains_y);
 		cairo_line_to (cr, long_line_x2, marcus_bains_y);
 		cairo_stroke (cr);
 		cairo_restore (cr);
+	} else {
+		mb_color = day_view->colors[E_DAY_VIEW_COLOR_MARCUS_BAINS_LINE];
+
+		if (day_view->marcus_bains_time_bar_color && gdk_color_parse (day_view->marcus_bains_time_bar_color, &mb_color)) {
+			GdkColormap *colormap;
+
+			colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view));
+			if (gdk_colormap_alloc_color (colormap, &mb_color, TRUE, TRUE)) {
+				gdk_cairo_set_source_color (cr, &mb_color);
+			}
+		}
 	}
 
 	/* Step through each row, drawing the times and the horizontal lines
@@ -361,6 +455,7 @@
 	for (row = 0, row_y = 0 - y;
 	     row < day_view->rows && row_y < height;
 	     row++, row_y += day_view->row_height) {
+		gboolean show_midnight_date = use_zone && hour == 0 && (minute == 0 || day_view->mins_per_row == 60) && midnight_day && midnight_month;
 
 		/* If the row is above the first row we want to draw just
 		   increment the time and skip to the next row. */
@@ -389,7 +484,11 @@
 			cairo_stroke (cr);
 			cairo_restore (cr);
 
-			if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
+			if (show_midnight_date) {
+				strcpy (buffer, midnight_day);
+				strcat (buffer, " ");
+				strcat (buffer, midnight_month);
+			} else if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
 				g_snprintf (buffer, sizeof (buffer), "%i:%02i",
 					    display_hour, minute);
 			} else {
@@ -398,7 +497,10 @@
 			}
 
 			cairo_save (cr);
-			gdk_cairo_set_source_color (cr, &fg);
+			if (show_midnight_date)
+				gdk_cairo_set_source_color (cr, &mb_color);
+			else
+				gdk_cairo_set_source_color (cr, &fg);
 			layout = pango_cairo_create_layout (cr);
 			pango_layout_set_text (layout, buffer, -1);
 			pango_layout_get_pixel_size (layout, &minute_width, NULL);
@@ -418,8 +520,11 @@
 
 				cairo_save (cr);
 				gdk_cairo_set_source_color (cr, &dark);
-				g_snprintf (buffer, sizeof (buffer), "%i",
-					    display_hour);
+				if (show_midnight_date)
+					strcpy (buffer, midnight_day);
+				else
+					g_snprintf (buffer, sizeof (buffer), "%i",
+						    display_hour);
 
 				cairo_set_line_width (cr, 0.7);
 				cairo_move_to (cr, long_line_x1, row_y);
@@ -428,7 +533,10 @@
 				cairo_restore (cr);
 
 				cairo_save (cr);
-				gdk_cairo_set_source_color (cr, &fg);
+				if (show_midnight_date)
+					gdk_cairo_set_source_color (cr, &mb_color);
+				else
+					gdk_cairo_set_source_color (cr, &fg);
 				layout = pango_cairo_create_layout (cr);
 				pango_layout_set_text (layout, buffer, -1);
 				pango_layout_set_font_description (layout, day_view->large_font_desc);
@@ -457,7 +565,9 @@
 			if (day_view->mins_per_row != 30 || minute != 30) {
 				/* In 12-hour format we display 'am' or 'pm'
 				   instead of '00'. */
-				if (minute == 0
+				if (show_midnight_date)
+					strcpy (buffer, midnight_month);
+				else if (minute == 0
 				    && !e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
 					strcpy (buffer, suffix);
 				} else {
@@ -466,7 +576,10 @@
 				}
 
 				cairo_save (cr);
-				gdk_cairo_set_source_color (cr, &fg);
+				if (show_midnight_date)
+					gdk_cairo_set_source_color (cr, &mb_color);
+				else
+					gdk_cairo_set_source_color (cr, &fg);
 				layout = pango_cairo_create_layout (cr);
 				pango_layout_set_text (layout, buffer, -1);
 				pango_layout_set_font_description (layout, day_view->small_font_desc);
@@ -487,6 +600,28 @@
 	pango_font_metrics_unref (large_font_metrics);
 	pango_font_metrics_unref (small_font_metrics);
 	cairo_destroy (cr);
+
+	g_free (midnight_day);
+	g_free (midnight_month);
+}
+
+static void
+e_day_view_time_item_draw (GnomeCanvasItem *canvas_item,
+			   GdkDrawable	   *drawable,
+			   int		    x,
+			   int		    y,
+			   int		    width,
+			   int		    height)
+{
+	EDayViewTimeItem *dvtmitem;
+
+	dvtmitem = E_DAY_VIEW_TIME_ITEM (canvas_item);
+	g_return_if_fail (dvtmitem != NULL);
+
+	edvti_draw_zone (canvas_item, drawable, x, y, width, height, 0, NULL);
+
+	if (dvtmitem->second_zone)
+		edvti_draw_zone (canvas_item, drawable, x, y, width, height, dvtmitem->column_width, dvtmitem->second_zone);
 }
 
 /* Increment the time by the 5/10/15/30/60 minute interval.
@@ -551,6 +686,37 @@
 	return FALSE;
 }
 
+static void
+edvti_second_zone_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data)
+{
+	EDayViewTimeItem *dvtmitem = user_data;
+	char *location;
+
+	g_return_if_fail (user_data != NULL);
+	g_return_if_fail (E_IS_DAY_VIEW_TIME_ITEM (dvtmitem));
+
+	location = calendar_config_get_day_second_zone ();
+	dvtmitem->second_zone = location ? icaltimezone_get_builtin_timezone (location) : NULL;
+	g_free (location);
+
+	gtk_widget_set_size_request (dvtmitem->day_view->time_canvas, e_day_view_time_item_get_column_width (dvtmitem), -1);
+	gtk_widget_queue_draw (dvtmitem->day_view->time_canvas);
+}
+
+static void
+edvti_on_select_zone (GtkWidget *item, EDayViewTimeItem *dvtmitem)
+{
+	calendar_config_select_day_second_zone ();
+}
+
+static void
+edvti_on_set_zone (GtkWidget *item, EDayViewTimeItem *dvtmitem)
+{
+	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"));
+}
 
 static void
 e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem,
@@ -559,10 +725,11 @@
 	static gint divisions[] = { 60, 30, 15, 10, 5 };
 	EDayView *day_view;
 	gint num_divisions = sizeof (divisions) / sizeof (divisions[0]);
-	GtkWidget *menu, *item;
+	GtkWidget *menu, *item, *submenu;
 	gchar buffer[256];
-	GSList *group = NULL;
+	GSList *group = NULL, *recent_zones, *s;
 	gint current_divisions, i;
+	icaltimezone *zone;
 
 	day_view = dvtmitem->day_view;
 	g_return_if_fail (day_view != NULL);
@@ -596,6 +763,61 @@
 				  G_CALLBACK (e_day_view_time_item_on_set_divisions), dvtmitem);
 	}
 
+	item = gtk_separator_menu_item_new ();
+	gtk_widget_show (item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+	submenu = gtk_menu_new ();
+	item = gtk_menu_item_new_with_label (_("Show the second time zone"));
+	gtk_widget_show (item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+	gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
+
+	zone = e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view));
+	if (zone)
+		item = gtk_menu_item_new_with_label (icaltimezone_get_display_name (zone));
+	else
+		item = gtk_menu_item_new_with_label ("---");
+	gtk_widget_set_sensitive (item, FALSE);
+	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
+	
+	item = gtk_separator_menu_item_new ();
+	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
+
+	group = NULL;
+	item = gtk_radio_menu_item_new_with_label (group, _("None"));
+	group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
+	if (!dvtmitem->second_zone)
+		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
+	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
+	g_signal_connect (item, "toggled", G_CALLBACK (edvti_on_set_zone), dvtmitem);
+
+	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 == dvtmitem->second_zone)
+			gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
+		gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
+		g_object_set_data_full (G_OBJECT (item), "timezone", g_strdup (s->data), g_free);
+		g_signal_connect (item, "toggled", G_CALLBACK (edvti_on_set_zone), dvtmitem);
+	}
+	calendar_config_free_day_second_zones (recent_zones);
+
+	item = gtk_separator_menu_item_new ();
+	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
+
+	item = gtk_menu_item_new_with_label (_("Select..."));
+	g_signal_connect (item, "activate", G_CALLBACK (edvti_on_select_zone), dvtmitem);
+	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
+
+	gtk_widget_show_all (submenu);
+
 	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
 			event->button.button, event->button.time);
 }

Modified: trunk/calendar/gui/e-day-view-time-item.h
==============================================================================
--- trunk/calendar/gui/e-day-view-time-item.h	(original)
+++ trunk/calendar/gui/e-day-view-time-item.h	Mon Jan 12 14:49:16 2009
@@ -53,6 +53,10 @@
 
 	/* TRUE if we are currently dragging the selection times. */
 	gboolean dragging_selection;
+
+	/* the second timezone shown here; NULL if none; do not free it, it's from the builtin zones */
+	guint second_zone_changed_id;
+	icaltimezone *second_zone;
 } EDayViewTimeItem;
 
 typedef struct {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]