evolution r37075 - in branches/kill-bonobo: . addressbook/gui/component addressbook/util calendar calendar/gui calendar/gui/dialogs calendar/importers e-util mail plugins/groupwise-features plugins/prefer-plain po shell ui



Author: mbarnes
Date: Thu Jan 15 03:39:43 2009
New Revision: 37075
URL: http://svn.gnome.org/viewvc/evolution?rev=37075&view=rev

Log:
Merge revisions 37047:37074 from trunk.


Modified:
   branches/kill-bonobo/   (props changed)
   branches/kill-bonobo/ChangeLog
   branches/kill-bonobo/addressbook/gui/component/eab-composer-util.c   (props changed)
   branches/kill-bonobo/addressbook/gui/component/eab-composer-util.h   (props changed)
   branches/kill-bonobo/addressbook/util/addressbook.c   (props changed)
   branches/kill-bonobo/addressbook/util/addressbook.h   (props changed)
   branches/kill-bonobo/calendar/ChangeLog
   branches/kill-bonobo/calendar/gui/apps_evolution_calendar.schemas.in
   branches/kill-bonobo/calendar/gui/calendar-config-keys.h
   branches/kill-bonobo/calendar/gui/calendar-config.c
   branches/kill-bonobo/calendar/gui/calendar-config.h
   branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.c
   branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.glade
   branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.h
   branches/kill-bonobo/calendar/gui/dialogs/recurrence-page.c
   branches/kill-bonobo/calendar/gui/e-cal-model.c
   branches/kill-bonobo/calendar/gui/e-day-view-time-item.c
   branches/kill-bonobo/calendar/gui/e-day-view-time-item.h
   branches/kill-bonobo/calendar/gui/e-meeting-time-sel.c
   branches/kill-bonobo/calendar/gui/e-timezone-entry.c
   branches/kill-bonobo/calendar/importers/icalendar-importer.c
   branches/kill-bonobo/e-util/e-plugin.c
   branches/kill-bonobo/e-util/e-plugin.h
   branches/kill-bonobo/mail/ChangeLog
   branches/kill-bonobo/mail/em-folder-view.c
   branches/kill-bonobo/mail/em-popup.c
   branches/kill-bonobo/mail/em-utils.c
   branches/kill-bonobo/mail/em-utils.h
   branches/kill-bonobo/mail/mail-folder-cache.c
   branches/kill-bonobo/plugins/groupwise-features/ChangeLog
   branches/kill-bonobo/plugins/groupwise-features/proxy-listing.glade
   branches/kill-bonobo/plugins/groupwise-features/proxy-login-dialog.glade
   branches/kill-bonobo/plugins/prefer-plain/ChangeLog
   branches/kill-bonobo/plugins/prefer-plain/prefer-plain.c
   branches/kill-bonobo/po/ChangeLog
   branches/kill-bonobo/po/es.po
   branches/kill-bonobo/po/pl.po
   branches/kill-bonobo/shell/main.c
   branches/kill-bonobo/ui/evolution-mail-reader.ui   (props changed)

Modified: branches/kill-bonobo/calendar/gui/apps_evolution_calendar.schemas.in
==============================================================================
--- branches/kill-bonobo/calendar/gui/apps_evolution_calendar.schemas.in	(original)
+++ branches/kill-bonobo/calendar/gui/apps_evolution_calendar.schemas.in	Thu Jan 15 03:39:43 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: branches/kill-bonobo/calendar/gui/calendar-config-keys.h
==============================================================================
--- branches/kill-bonobo/calendar/gui/calendar-config-keys.h	(original)
+++ branches/kill-bonobo/calendar/gui/calendar-config-keys.h	Thu Jan 15 03:39:43 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: branches/kill-bonobo/calendar/gui/calendar-config.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/calendar-config.c	(original)
+++ branches/kill-bonobo/calendar/gui/calendar-config.c	Thu Jan 15 03:39:43 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: branches/kill-bonobo/calendar/gui/calendar-config.h
==============================================================================
--- branches/kill-bonobo/calendar/gui/calendar-config.h	(original)
+++ branches/kill-bonobo/calendar/gui/calendar-config.h	Thu Jan 15 03:39:43 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: branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.c	(original)
+++ branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.c	Thu Jan 15 03:39:43 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: branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.glade
==============================================================================
--- branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.glade	(original)
+++ branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.glade	Thu Jan 15 03:39:43 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: branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.h
==============================================================================
--- branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.h	(original)
+++ branches/kill-bonobo/calendar/gui/dialogs/cal-prefs-dialog.h	Thu Jan 15 03:39:43 2009
@@ -43,6 +43,7 @@
 
 	/* General tab */
 	GtkWidget *timezone;
+	GtkWidget *day_second_zone;
 	GtkWidget *daylight_saving;
 	GtkWidget *working_days[7];
 	GtkWidget *week_start_day;

Modified: branches/kill-bonobo/calendar/gui/dialogs/recurrence-page.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/dialogs/recurrence-page.c	(original)
+++ branches/kill-bonobo/calendar/gui/dialogs/recurrence-page.c	Thu Jan 15 03:39:43 2009
@@ -903,6 +903,37 @@
 	e_cal_component_set_exdate_list (comp, list);
 	e_cal_component_free_exdate_list (list);
 
+	if (GTK_WIDGET_VISIBLE (priv->ending_menu) && GTK_WIDGET_IS_SENSITIVE (priv->ending_menu) &&
+	    e_dialog_option_menu_get (priv->ending_menu, ending_types_map) == ENDING_UNTIL) {
+		/* check whether the "until" date is in the future */
+		struct icaltimetype tt;
+		gboolean ok = TRUE;
+
+		if (e_date_edit_get_date (E_DATE_EDIT (priv->ending_date_edit), &tt.year, &tt.month, &tt.day)) {
+			ECalComponentDateTime dtstart;
+
+			/* the dtstart should be set already */
+			e_cal_component_get_dtstart (comp, &dtstart);
+
+			tt.is_date = 1;
+			tt.zone = NULL;
+
+			if (dtstart.value && icaltime_is_valid_time (*dtstart.value)) {
+				ok = icaltime_compare_date_only (*dtstart.value, tt) <= 0;
+
+				if (!ok)
+					e_date_edit_set_date (E_DATE_EDIT (priv->ending_date_edit), dtstart.value->year, dtstart.value->month, dtstart.value->day);
+			}
+
+			e_cal_component_free_datetime (&dtstart);
+		}
+
+		if (!ok) {
+			comp_editor_page_display_validation_error (COMP_EDITOR_PAGE (rpage), _("End time of the recurrence was before event's start"), priv->ending_date_edit);
+			return FALSE;
+		}
+	}
+
 	return TRUE;
 }
 

Modified: branches/kill-bonobo/calendar/gui/e-cal-model.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/e-cal-model.c	(original)
+++ branches/kill-bonobo/calendar/gui/e-cal-model.c	Thu Jan 15 03:39:43 2009
@@ -1518,6 +1518,15 @@
 			id = e_cal_component_get_id (comp);
 
 			comp_data = search_by_id_and_client (priv, client, id);
+
+			e_cal_component_free_id (id);
+			g_object_unref (comp);
+
+			if (!comp_data) {
+				/* the modified component is not in the model yet, just skip it */
+				continue;
+			}
+
 			if (comp_data->icalcomp)
 				icalcomponent_free (comp_data->icalcomp);
 			if (comp_data->dtstart) {

Modified: branches/kill-bonobo/calendar/gui/e-day-view-time-item.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/e-day-view-time-item.c	(original)
+++ branches/kill-bonobo/calendar/gui/e-day-view-time-item.c	Thu Jan 15 03:39:43 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: branches/kill-bonobo/calendar/gui/e-day-view-time-item.h
==============================================================================
--- branches/kill-bonobo/calendar/gui/e-day-view-time-item.h	(original)
+++ branches/kill-bonobo/calendar/gui/e-day-view-time-item.h	Thu Jan 15 03:39:43 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 {

Modified: branches/kill-bonobo/calendar/gui/e-meeting-time-sel.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/e-meeting-time-sel.c	(original)
+++ branches/kill-bonobo/calendar/gui/e-meeting-time-sel.c	Thu Jan 15 03:39:43 2009
@@ -185,6 +185,7 @@
 static void e_meeting_time_selector_update_end_date_edit (EMeetingTimeSelector *mts);
 static void e_meeting_time_selector_ensure_meeting_time_shown (EMeetingTimeSelector *mts);
 static void e_meeting_time_selector_update_dates_shown (EMeetingTimeSelector *mts);
+static gboolean e_meeting_time_selector_on_canvas_scroll_event (GtkWidget *widget, GdkEventScroll *event, EMeetingTimeSelector *mts);
 
 static void row_inserted_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
 static void row_changed_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
@@ -358,6 +359,8 @@
 			  G_CALLBACK (e_meeting_time_selector_on_canvas_realized), mts);
 	g_signal_connect (mts->display_main, "size_allocate",
 			  G_CALLBACK (e_meeting_time_selector_on_canvas_size_allocate), mts);
+	g_signal_connect (mts->display_main, "scroll-event",
+			  G_CALLBACK (e_meeting_time_selector_on_canvas_scroll_event), mts);
 
 	gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (sw), GTK_LAYOUT (mts->display_main)->vadjustment);
 
@@ -2308,6 +2311,17 @@
 	e_meeting_time_selector_ensure_meeting_time_shown (mts);
 }
 
+static gboolean
+e_meeting_time_selector_on_canvas_scroll_event (GtkWidget *widget, GdkEventScroll *event, EMeetingTimeSelector *mts)
+{
+	gboolean return_val = FALSE;
+
+	/* escalate to the list view's parent, which is a scrolled window */
+	g_signal_emit_by_name (gtk_widget_get_parent (GTK_WIDGET (mts->list_view)), "scroll-event", event, &return_val);
+
+	return return_val;
+}
+
 /* This updates the canvas scroll regions according to the number of attendees.
    If the total height needed is less than the height of the canvas, we must
    use the height of the canvas, or it causes problems. */

Modified: branches/kill-bonobo/calendar/gui/e-timezone-entry.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/e-timezone-entry.c	(original)
+++ branches/kill-bonobo/calendar/gui/e-timezone-entry.c	Thu Jan 15 03:39:43 2009
@@ -104,7 +104,6 @@
 e_timezone_entry_init		(ETimezoneEntry	*tentry)
 {
 	ETimezoneEntryPrivate *priv;
-	GtkWidget *image;
 	AtkObject *a11y;
 
 	tentry->priv = priv = g_new0 (ETimezoneEntryPrivate, 1);
@@ -119,7 +118,7 @@
 	gtk_widget_show (priv->entry);
 	g_signal_connect (priv->entry, "changed", G_CALLBACK (on_entry_changed), tentry);
 
-	priv->button = gtk_button_new ();
+	priv->button = gtk_button_new_with_label (_("Select..."));
 	g_signal_connect (priv->button, "clicked", G_CALLBACK (on_button_clicked), tentry);
 	gtk_box_pack_start (GTK_BOX (tentry), priv->button, FALSE, FALSE, 6);
 	gtk_widget_show (priv->button);
@@ -127,11 +126,6 @@
 	if (a11y != NULL) {
 		atk_object_set_name (a11y, _("Select Timezone"));
 	}
-
-	image = gtk_image_new_from_icon_name (
-		"stock_timezone", GTK_ICON_SIZE_BUTTON);
-	gtk_container_add (GTK_CONTAINER (priv->button), image);
-	gtk_widget_show (image);
 }
 
 

Modified: branches/kill-bonobo/calendar/importers/icalendar-importer.c
==============================================================================
--- branches/kill-bonobo/calendar/importers/icalendar-importer.c	(original)
+++ branches/kill-bonobo/calendar/importers/icalendar-importer.c	Thu Jan 15 03:39:43 2009
@@ -247,7 +247,7 @@
 
 		g_signal_connect (selector, "primary_selection_changed", G_CALLBACK (primary_selection_changed_cb), target);
 
-		rb = gtk_radio_button_new_with_label (group, import_type_strings[i]);
+		rb = gtk_radio_button_new_with_label (group, _(import_type_strings[i]));
 		gtk_box_pack_start (GTK_BOX (hbox), rb, FALSE, FALSE, 6);
 
 		sd = g_malloc0(sizeof(*sd));

Modified: branches/kill-bonobo/e-util/e-plugin.c
==============================================================================
--- branches/kill-bonobo/e-util/e-plugin.c	(original)
+++ branches/kill-bonobo/e-util/e-plugin.c	Thu Jan 15 03:39:43 2009
@@ -608,8 +608,7 @@
 			}
 
 			while ( (d = g_dir_read_name(dir)) ) {
-				if (strlen(d) > 6
-						&& !strcmp(d + strlen(d) - 6, ".eplug")) {
+				if (g_str_has_suffix  (d, ".eplug")) {
 					char * name = g_build_filename(path, d, NULL);
 
 					ep_load(name, i);
@@ -987,8 +986,10 @@
    pages.
 */
 
+static GList *missing_symbols = NULL;
+
 static int
-epl_loadmodule(EPlugin *ep)
+epl_loadmodule(EPlugin *ep, gboolean fatal)
 {
 	EPluginLib *epl = E_PLUGIN_LIB (ep);
 	EPluginLibEnableFunc enable;
@@ -997,7 +998,10 @@
 		return 0;
 
 	if ((epl->module = g_module_open(epl->location, 0)) == NULL) {
-		g_warning("can't load plugin '%s': %s", epl->location, g_module_error());
+		if (fatal)
+			g_warning("can't load plugin '%s': %s", epl->location, g_module_error());
+		else
+			missing_symbols = g_list_prepend (missing_symbols, g_object_ref (ep));
 		return -1;
 	}
 
@@ -1013,6 +1017,22 @@
 	return 0;
 }
 
+void
+e_plugin_load_plugins_with_missing_symbols (void)
+{
+	GList *list = missing_symbols;
+
+	while (list) {
+		EPlugin *ep = list->data;
+		epl_loadmodule (ep, TRUE);
+		g_object_unref (ep);
+		list = g_list_next (list);
+	}
+
+	g_list_free (missing_symbols);
+	missing_symbols = NULL;
+}
+
 static void *
 epl_invoke(EPlugin *ep, const char *name, void *data)
 {
@@ -1024,7 +1044,7 @@
 		return NULL;
 	}
 
-	if (epl_loadmodule(ep) != 0)
+	if (epl_loadmodule(ep, FALSE) != 0)
 		return NULL;
 
 	if (!g_module_symbol(epl->module, name, (void *)&cb)) {
@@ -1041,7 +1061,7 @@
 	EPluginLib *epl = E_PLUGIN_LIB (ep);
 	gpointer symbol;
 
-	if (epl_loadmodule (ep) != 0)
+	if (epl_loadmodule (ep, FALSE) != 0)
 		return NULL;
 
 	if (!g_module_symbol (epl->module, name, &symbol))
@@ -1080,9 +1100,15 @@
 
 		tmp = xmlGetProp(root, (const unsigned char *)"load-on-startup");
 		if (tmp) {
+			if (strcmp (tmp, "after-ui") == 0) {
+				missing_symbols = g_list_prepend (missing_symbols, g_object_ref (ep));
+			} else {
+				if (epl_loadmodule(ep, FALSE) != 0) {
+					xmlFree(tmp);
+					return -1;
+				}
+			}
 			xmlFree(tmp);
-			if (epl_loadmodule(ep) != 0)
-				return -1;
 		}
 	}
 
@@ -1097,7 +1123,7 @@
 
 	pd (printf ("\n epl_get_configure_widget \n"));
 
-	if (epl_loadmodule (ep) != 0) {
+	if (epl_loadmodule (ep, FALSE) != 0) {
 		pd (printf ("\n epl_loadmodule  \n"));
 		return NULL;
 	}
@@ -1122,7 +1148,7 @@
 		return;
 
 	/* this will noop if we're disabling since we tested it above */
-	if (epl_loadmodule(ep) != 0)
+	if (epl_loadmodule(ep, FALSE) != 0)
 		return;
 
 	if (g_module_symbol(epl->module, "e_plugin_lib_enable", (void *)&enable)) {

Modified: branches/kill-bonobo/e-util/e-plugin.h
==============================================================================
--- branches/kill-bonobo/e-util/e-plugin.h	(original)
+++ branches/kill-bonobo/e-util/e-plugin.h	Thu Jan 15 03:39:43 2009
@@ -134,6 +134,7 @@
 int e_plugin_construct(EPlugin *ep, xmlNodePtr root);
 void e_plugin_add_load_path(const char *);
 int e_plugin_load_plugins(void);
+void e_plugin_load_plugins_with_missing_symbols(void);
 GSList * e_plugin_list_plugins(void);
 
 void e_plugin_register_type(GType type);

Modified: branches/kill-bonobo/mail/em-folder-view.c
==============================================================================
--- branches/kill-bonobo/mail/em-folder-view.c	(original)
+++ branches/kill-bonobo/mail/em-folder-view.c	Thu Jan 15 03:39:43 2009
@@ -1675,37 +1675,6 @@
 //	}
 //}
 
-static gchar *
-url_unescape_amp (const gchar *url)
-{
-	gchar *buff;
-	int i, j, amps;
-
-	if (!url)
-		return NULL;
-
-	amps = 0;
-	for (i = 0; url [i]; i++) {
-		if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
-			amps++;
-	}
-
-	buff = g_strdup (url);
-
-	if (!amps)
-		return buff;
-
-	for (i = 0, j = 0; url [i]; i++, j++) {
-		buff [j] = url [i];
-
-		if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
-			i += 4;
-	}
-	buff [j] = 0;
-
-	return buff;
-}
-
 static void
 emp_uri_popup_link_copy(EPopup *ep, EPopupItem *pitem, void *data)
 {
@@ -1713,7 +1682,7 @@
 	struct _EMFolderViewPrivate *p = emfv->priv;
 
 	g_free(p->selection_uri);
-	p->selection_uri = url_unescape_amp(pitem->user_data);
+	p->selection_uri = em_utils_url_unescape_amp(pitem->user_data);
 
 	gtk_selection_owner_set(p->invisible, GDK_SELECTION_PRIMARY, gtk_get_current_event_time());
 	gtk_selection_owner_set(p->invisible, GDK_SELECTION_CLIPBOARD, gtk_get_current_event_time());

Modified: branches/kill-bonobo/mail/em-popup.c
==============================================================================
--- branches/kill-bonobo/mail/em-popup.c	(original)
+++ branches/kill-bonobo/mail/em-popup.c	Thu Jan 15 03:39:43 2009
@@ -585,9 +585,11 @@
 emp_uri_popup_link_open(EPopup *ep, EPopupItem *item, void *data)
 {
 	EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
+	gchar *unescaped_uri = em_utils_url_unescape_amp (t->uri);
 
 	/* FIXME Pass a parent window. */
-	e_show_uri (NULL, t->uri);
+	e_show_uri (NULL, unescaped_uri);
+	g_free (unescaped_uri);
 }
 
 static void

Modified: branches/kill-bonobo/mail/em-utils.c
==============================================================================
--- branches/kill-bonobo/mail/em-utils.c	(original)
+++ branches/kill-bonobo/mail/em-utils.c	Thu Jan 15 03:39:43 2009
@@ -2473,3 +2473,34 @@
 			widget, "response",
 			G_CALLBACK (gtk_widget_destroy), NULL);
 }
+
+gchar *
+em_utils_url_unescape_amp (const gchar *url)
+{
+	gchar *buff;
+	int i, j, amps;
+
+	if (!url)
+		return NULL;
+
+	amps = 0;
+	for (i = 0; url [i]; i++) {
+		if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
+			amps++;
+	}
+
+	buff = g_strdup (url);
+
+	if (!amps)
+		return buff;
+
+	for (i = 0, j = 0; url [i]; i++, j++) {
+		buff [j] = url [i];
+
+		if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
+			i += 4;
+	}
+	buff [j] = 0;
+
+	return buff;
+}

Modified: branches/kill-bonobo/mail/em-utils.h
==============================================================================
--- branches/kill-bonobo/mail/em-utils.h	(original)
+++ branches/kill-bonobo/mail/em-utils.h	Thu Jan 15 03:39:43 2009
@@ -109,6 +109,9 @@
 /* clears flag 'get_password_canceled' at every known accounts, so if needed, get_password will show dialog */
 void em_utils_clear_get_password_canceled_accounts_flag (void);
 
+/* Unescapes &amp; back to a real & in URIs */
+gchar *em_utils_url_unescape_amp (const gchar *url);
+
 G_END_DECLS
 
 #endif /* __EM_UTILS_H__ */

Modified: branches/kill-bonobo/mail/mail-folder-cache.c
==============================================================================
--- branches/kill-bonobo/mail/mail-folder-cache.c	(original)
+++ branches/kill-bonobo/mail/mail-folder-cache.c	Thu Jan 15 03:39:43 2009
@@ -462,6 +462,7 @@
 				    ((flags & CAMEL_MESSAGE_DELETED) == 0) &&
 				    (camel_message_info_date_received (info) > last_newmail))
 					new++;
+				camel_message_info_free (info);
 			}
 		}
 	}

Modified: branches/kill-bonobo/plugins/groupwise-features/proxy-listing.glade
==============================================================================
--- branches/kill-bonobo/plugins/groupwise-features/proxy-listing.glade	(original)
+++ branches/kill-bonobo/plugins/groupwise-features/proxy-listing.glade	Thu Jan 15 03:39:43 2009
@@ -169,7 +169,7 @@
 	  <child>
 	    <widget class="GtkLabel" id="label1">
 	      <property name="visible">True</property>
-	      <property name="label" translatable="yes" comment="To Translators: In this case, Proxy does not mean something like 'HTTP Proxy', but a GroupWise feature by which one person can send/read mails/appointments using another person's identity without knowing his password, for example if that other person is on vacation">Proxy</property>
+	      <property name="label" translatable="yes" comments="To Translators: In this case, Proxy does not mean something like 'HTTP Proxy', but a GroupWise feature by which one person can send/read mails/appointments using another person's identity without knowing his password, for example if that other person is on vacation">Proxy</property>
 	      <property name="use_underline">False</property>
 	      <property name="use_markup">False</property>
 	      <property name="justify">GTK_JUSTIFY_LEFT</property>

Modified: branches/kill-bonobo/plugins/groupwise-features/proxy-login-dialog.glade
==============================================================================
--- branches/kill-bonobo/plugins/groupwise-features/proxy-login-dialog.glade	(original)
+++ branches/kill-bonobo/plugins/groupwise-features/proxy-login-dialog.glade	Thu Jan 15 03:39:43 2009
@@ -7,7 +7,7 @@
 <widget class="GtkDialog" id="proxy_login_dialog">
   <property name="visible">True</property>
   <property name="height_request">325</property>
-  <property name="title" translatable="yes" comment="To Translators: In this case, Proxy does not mean something like 'HTTP Proxy', but a GroupWise feature by which one person can send/read mails/appointments using another person's identity without knowing his password, for example if that other person is on vacation">Proxy Login</property>
+  <property name="title" translatable="yes" comments="To Translators: In this case, Proxy does not mean something like 'HTTP Proxy', but a GroupWise feature by which one person can send/read mails/appointments using another person's identity without knowing his password, for example if that other person is on vacation">Proxy Login</property>
   <property name="type">GTK_WINDOW_TOPLEVEL</property>
   <property name="window_position">GTK_WIN_POS_NONE</property>
   <property name="modal">True</property>

Modified: branches/kill-bonobo/plugins/prefer-plain/prefer-plain.c
==============================================================================
--- branches/kill-bonobo/plugins/prefer-plain/prefer-plain.c	(original)
+++ branches/kill-bonobo/plugins/prefer-plain/prefer-plain.c	Thu Jan 15 03:39:43 2009
@@ -119,9 +119,7 @@
 		/* Try to find text/html part even when not as last and force to show it.
 		   Old handler will show the last part of multipart/alternate, but if we
 		   can offer HTML, then offer it, regardless of position in multipart.
-		   But do this only when have text/plain in a list, because otherwise it
-		   can be something else (like outlooks meeting invites with only text/html
-		   part and calendar part).
+		   But do this when have only text/plain and text/html parts, not more.
 		*/
 		nparts = camel_multipart_get_number (mp);
 		for (i = 0; i < nparts; i++) {
@@ -148,7 +146,7 @@
 			}
 		}
 
-		if (display_part && have_plain) {
+		if (display_part && have_plain && nparts == 2) {
 			g_string_append_printf (t->format->part_id, ".alternative.%d", displayid);
 			em_format_part_as (t->format, t->stream, display_part, "text/html");
 			g_string_truncate (t->format->part_id, partidlen);

Modified: branches/kill-bonobo/shell/main.c
==============================================================================
--- branches/kill-bonobo/shell/main.c	(original)
+++ branches/kill-bonobo/shell/main.c	Thu Jan 15 03:39:43 2009
@@ -327,6 +327,14 @@
 	}
 #endif
 
+	/* This must be done after Bonobo has created all the components. For 
+	 * example the mail component makes the global variable `session` which
+	 * is being used by several EPlugins */
+
+	if (!disable_eplugin) {
+		e_plugin_load_plugins_with_missing_symbols ();
+	}
+
 	return FALSE;
 }
 



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