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

Bug#771502: marked as done (Pre-approval for evolution/3.12.9~git20141130.241663-1)



Your message dated Sun, 30 Nov 2014 22:27:48 +0000
with message-id <1417386468.2472.43.camel@adam-barratt.org.uk>
and subject line Re: Bug#771502: Pre-approval for evolution/3.12.9~git20141130.241663-1
has caused the Debian Bug report #771502,
regarding Pre-approval for evolution/3.12.9~git20141130.241663-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
771502: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=771502
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Hi,

following the update in evolution-data-server, I’m proposing another one 
in evolution, again fixing a number of crashes and UI bugs, including a RC 
bug.

Upstream also removed the geoclue build-dependency that was no longer 
used.

evolution (3.12.9~git20141130.241663-1) UNRELEASED; urgency=medium

  * New upstream git snapshot from stable branch, includes only bugfixes 
    and translations.
    + Fix crash caused by hidden alert buttons. Closes: #770390.
  * Remove geoclue build-dependency.
  * Update (build-)dependencies on e-d-s to 3.12.9~.

I’m attaching the upstream and Debian changes. Individual upstream 
changes can be found at 
https://git.gnome.org/browse/evolution/log/?h=evolution-3-12

unblock evolution/3.12.9~git20141130.241663-1

Thanks again for your tireless work.
-- 
 .''`.        Josselin Mouette
: :' :
`. `'
  `-
Index: debian/control
===================================================================
--- debian/control	(révision 2640)
+++ debian/control	(copie de travail)
@@ -20,7 +20,6 @@
                dpkg-dev (>= 1.16.1),
                libcamel1.2-dev (>= 3.12.7),
                libchamplain-gtk-0.12-dev,
-               libgeoclue-dev (>= 0.12.0),
                libglib2.0-dev (>= 2.36),
                libgtk-3-dev (>= 3.8.0),
                libgail-3-dev (>= 3.0.2),
Index: debian/changelog
===================================================================
--- debian/changelog	(révision 2640)
+++ debian/changelog	(copie de travail)
@@ -1,3 +1,12 @@
+evolution (3.12.9~git20141130.241663-1) UNRELEASED; urgency=medium
+
+  * New upstream git snapshot from stable branch, includes only bugfixes 
+    and translations.
+    + Fix crash caused by hidden alert buttons. Closes: #770390.
+  * Remove geoclue build-dependency.
+
+ -- Josselin Mouette <joss@debian.org>  Sun, 30 Nov 2014 10:08:31 +0100
+
 evolution (3.12.7-1) unstable; urgency=medium
 
   * New upstream release 3.12.7
diff --git a/AUTHORS b/AUTHORS
index fdf3f54..05fff3e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,7 +3,6 @@ inception at Ximian, Inc. in the late 1990s, and we thank them all.
 
 The Evolution project is currently maintained by:
 
-  Matthew Barnes <mbarnes@redhat.com>
   Milan Crha <mcrha@redhat.com>
   Fabiano Fid�io <fabiano@fidencio.org>
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 5625868..01bab6a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1,4 +1,3 @@
-Matthew Barnes <mbarnes@redhat.com>
 Milan Crha <mcrha@redhat.com>
 
 User Documentation:
diff --git a/NEWS b/NEWS
index 40f3b4e..df7c7bc 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,35 @@
+Evolution 3.12.8 2014-11-10
+---------------------------
+
+Bug Fixes:
+	Bug 729305 - EAlertDialog too wide with wrapped GtkLabel-s (Milan Crha)
+	Bug 737330 - EShellSwitcher: Count with GtkPaned::handle-size for button widths (Milan Crha)
+	Bug 738453 - Inefficient sort by subject in message list (Milan Crha)
+	Bug 738463 - [a11y] Fix various problems with fetching children (Mike Gorse)
+	Bug 650670 - Duplicate entries when contact is in several address books (Milan Crha)
+	Bug 739375 - Crash when sort folder with Due By column (Milan Crha)
+	Bug 739386 - Forward style Inline is missing a line break (Milan Crha)
+	Bug 739364 - Drop references to geoclue (Milan Crha)
+	Bug 676471 - Double free when sorting by date columns in calendar (Milan Crha)
+	Bug 739605 - Remove alert buttons on the alert bar hide (Milan Crha)
+	Bug 739562 - Message composer autosave not updating (Milan Crha)
+
+Miscellaneous:
+	Update AUTHORS, MAINTAINERS, doap, etc. (Matthew Barnes)
+	Address two possible places causing runtime warning on a GSource removal (Milan Crha)
+	cal_comp_util_compare_event_timezones: Do not ask with NULL tzid (Milan Crha)
+	[Mark-All-Read] Save changes to the server immediately (Milan Crha)
+	Avoid automatic mail account update when the application is exiting (Milan Crha)
+
+Translations:
+	Fran Diéguez (gl)
+	Daniel Mustieles (es)
+	Marek Černocký (cs)
+	Aurimas Černius (lt)
+	Kjartan Maraas (nb)
+	Bernd Homuth (de)
+	Guillaume Bernard (fr)
+
 Evolution 3.12.7 2014-10-13
 ---------------------------
 
diff --git a/addressbook/gui/widgets/e-contact-map.c b/addressbook/gui/widgets/e-contact-map.c
index 5ae1fbd..fde0e8b 100644
--- a/addressbook/gui/widgets/e-contact-map.c
+++ b/addressbook/gui/widgets/e-contact-map.c
@@ -26,8 +26,6 @@
 
 #include <champlain/champlain.h>
 #include <champlain-gtk/champlain-gtk.h>
-#include <geoclue/geoclue-address.h>
-#include <geoclue/geoclue-position.h>
 #include <geocode-glib/geocode-glib.h>
 
 #include <clutter/clutter.h>
diff --git a/calendar/alarm-notify/alarm-queue.c b/calendar/alarm-notify/alarm-queue.c
index f52a9ef..7087f8a 100644
--- a/calendar/alarm-notify/alarm-queue.c
+++ b/calendar/alarm-notify/alarm-queue.c
@@ -342,7 +342,8 @@ alarm_queue_discard_alarm_cb (GObject *source,
 
 	g_return_if_fail (client != NULL);
 
-	if (!e_cal_client_discard_alarm_finish (client, result, &error))
+	if (!e_cal_client_discard_alarm_finish (client, result, &error) &&
+	    !g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_NOT_SUPPORTED))
 		g_warning ("Failed to discard alarm at '%s': %s",
 			e_source_get_display_name (e_client_get_source (E_CLIENT (client))),
 			error ? error->message : "Unknown error");
@@ -375,8 +376,7 @@ remove_queued_alarm (CompQueuedAlarms *cqa,
 
 	cqa->queued_alarms = g_slist_delete_link (cqa->queued_alarms, l);
 
-	if (remove_alarm) {
-		GError *error = NULL;
+	if (remove_alarm && !e_client_is_readonly (E_CLIENT (cqa->parent_client->cal_client))) {
 		ECalComponentId *id;
 
 		id = e_cal_component_get_id (cqa->alarms->comp);
@@ -388,16 +388,6 @@ remove_queued_alarm (CompQueuedAlarms *cqa,
 				alarm_queue_discard_alarm_cb, NULL);
 			cqa->expecting_update = FALSE;
 
-			if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_NOT_SUPPORTED)) {
-				g_error_free (error);
-
-			} else if (error != NULL) {
-				g_warning (
-					"%s: Failed to discard alarm: %s",
-					G_STRFUNC, error->message);
-				g_error_free (error);
-			}
-
 			e_cal_component_free_id (id);
 		}
 	}
diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c
index 16dfd5d..77b31b4 100644
--- a/calendar/gui/comp-util.c
+++ b/calendar/gui/comp-util.c
@@ -150,8 +150,11 @@ cal_comp_util_compare_event_timezones (ECalComponent *comp,
 		/* If the TZIDs differ, we have to compare the UTC offsets
 		 * of the start and end times, using their own timezones and
 		 * the given timezone. */
-		e_cal_client_get_timezone_sync (
-			client, start_datetime.tzid, &start_zone, NULL, NULL);
+		if (start_datetime.tzid)
+			e_cal_client_get_timezone_sync (client, start_datetime.tzid, &start_zone, NULL, NULL);
+		else
+			start_zone = NULL;
+
 		if (start_zone == NULL)
 			goto out;
 
@@ -168,8 +171,11 @@ cal_comp_util_compare_event_timezones (ECalComponent *comp,
 				goto out;
 		}
 
-		e_cal_client_get_timezone_sync (
-			client, end_datetime.tzid, &end_zone, NULL, NULL);
+		if (end_datetime.tzid)
+			e_cal_client_get_timezone_sync (client, end_datetime.tzid, &end_zone, NULL, NULL);
+		else
+			end_zone = NULL;
+
 		if (end_zone == NULL)
 			goto out;
 
diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c
index b3099cd..b211f4c 100644
--- a/calendar/gui/e-cal-model-calendar.c
+++ b/calendar/gui/e-cal-model-calendar.c
@@ -94,7 +94,7 @@ get_dtend (ECalModelCalendar *model,
 			comp_data->dtend->zone = NULL;
 	}
 
-	return comp_data->dtend;
+	return e_cal_model_copy_cell_date_value (comp_data->dtend);
 }
 
 static gpointer
@@ -400,16 +400,7 @@ cal_model_calendar_duplicate_value (ETableModel *etm,
 
 	switch (col) {
 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
-		if (value) {
-			ECellDateEditValue *dv, *orig_dv;
-
-			orig_dv = (ECellDateEditValue *) value;
-			dv = g_new0 (ECellDateEditValue, 1);
-			*dv = *orig_dv;
-
-			return dv;
-		}
-		break;
+		return e_cal_model_copy_cell_date_value (value);
 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
 		return g_strdup (value);
@@ -432,6 +423,9 @@ cal_model_calendar_free_value (ETableModel *etm,
 
 	switch (col) {
 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
+		if (value)
+			g_free (value);
+		break;
 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
 		break;
diff --git a/calendar/gui/e-cal-model-tasks.c b/calendar/gui/e-cal-model-tasks.c
index f07d9bf..ee6123c 100644
--- a/calendar/gui/e-cal-model-tasks.c
+++ b/calendar/gui/e-cal-model-tasks.c
@@ -207,7 +207,7 @@ get_completed (ECalModelComponent *comp_data)
 			comp_data->completed->zone = NULL;
 	}
 
-	return comp_data->completed;
+	return e_cal_model_copy_cell_date_value (comp_data->completed);
 }
 
 static ECellDateEditValue *
@@ -237,7 +237,7 @@ get_due (ECalModelComponent *comp_data)
 			comp_data->due->zone = NULL;
 	}
 
-	return comp_data->due;
+	return e_cal_model_copy_cell_date_value (comp_data->due);
 }
 
 static gpointer
@@ -1027,16 +1027,7 @@ cal_model_tasks_duplicate_value (ETableModel *etm,
 		return g_strdup (value);
 	case E_CAL_MODEL_TASKS_FIELD_COMPLETED :
 	case E_CAL_MODEL_TASKS_FIELD_DUE :
-		if (value) {
-			ECellDateEditValue *dv, *orig_dv;
-
-			orig_dv = (ECellDateEditValue *) value;
-			dv = g_new0 (ECellDateEditValue, 1);
-			*dv = *orig_dv;
-
-			return dv;
-		}
-		break;
+		return e_cal_model_copy_cell_date_value (value);
 
 	case E_CAL_MODEL_TASKS_FIELD_COMPLETE :
 	case E_CAL_MODEL_TASKS_FIELD_PERCENT :
@@ -1062,6 +1053,9 @@ cal_model_tasks_free_value (ETableModel *etm,
 	switch (col) {
 	case E_CAL_MODEL_TASKS_FIELD_COMPLETED :
 	case E_CAL_MODEL_TASKS_FIELD_DUE :
+		if (value)
+			g_free (value);
+		break;
 	case E_CAL_MODEL_TASKS_FIELD_GEO :
 	case E_CAL_MODEL_TASKS_FIELD_PRIORITY :
 	case E_CAL_MODEL_TASKS_FIELD_STATUS :
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index f7f3d6e..05ffef5 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -540,7 +540,7 @@ get_dtstart (ECalModel *model,
 			comp_data->dtstart->zone = NULL;
 	}
 
-	return comp_data->dtstart;
+	return e_cal_model_copy_cell_date_value (comp_data->dtstart);
 }
 
 static ECellDateEditValue *
@@ -548,40 +548,39 @@ get_datetime_from_utc (ECalModel *model,
                        ECalModelComponent *comp_data,
                        icalproperty_kind propkind,
                        struct icaltimetype (*get_value) (const icalproperty *prop),
-                                                         ECellDateEditValue **buffer)
+		       ECellDateEditValue **buffer)
 {
-	ECalModelPrivate *priv;
-	struct icaltimetype tt_value;
-	icalproperty *prop;
-	ECellDateEditValue *res;
+	g_return_val_if_fail (buffer != NULL, NULL);
 
-	g_return_val_if_fail (buffer!= NULL, NULL);
-
-	if (*buffer)
-		return *buffer;
+	if (!*buffer) {
+		ECalModelPrivate *priv;
+		struct icaltimetype tt_value;
+		icalproperty *prop;
+		ECellDateEditValue *res;
 
-	priv = model->priv;
+		priv = model->priv;
 
-	prop = icalcomponent_get_first_property (comp_data->icalcomp, propkind);
-	if (!prop)
-		return NULL;
+		prop = icalcomponent_get_first_property (comp_data->icalcomp, propkind);
+		if (!prop)
+			return NULL;
 
-	tt_value = get_value (prop);
+		tt_value = get_value (prop);
 
-	/* these are always in UTC, thus convert to default zone, if any and done */
-	if (priv->zone)
-		icaltimezone_convert_time (&tt_value, icaltimezone_get_utc_timezone (), priv->zone);
+		/* these are always in UTC, thus convert to default zone, if any and done */
+		if (priv->zone)
+			icaltimezone_convert_time (&tt_value, icaltimezone_get_utc_timezone (), priv->zone);
 
-	if (!icaltime_is_valid_time (tt_value) || icaltime_is_null_time (tt_value))
-		return NULL;
+		if (!icaltime_is_valid_time (tt_value) || icaltime_is_null_time (tt_value))
+			return NULL;
 
-	res = g_new0 (ECellDateEditValue, 1);
-	res->tt = tt_value;
-	res->zone = NULL;
+		res = g_new0 (ECellDateEditValue, 1);
+		res->tt = tt_value;
+		res->zone = NULL;
 
-	*buffer = res;
+		*buffer = res;
+	}
 
-	return res;
+	return e_cal_model_copy_cell_date_value (*buffer);
 }
 
 static gpointer
@@ -1515,16 +1514,7 @@ cal_model_duplicate_value (ETableModel *etm,
 	case E_CAL_MODEL_FIELD_DTSTART :
 	case E_CAL_MODEL_FIELD_CREATED :
 	case E_CAL_MODEL_FIELD_LASTMODIFIED :
-		if (value) {
-			ECellDateEditValue *dv, *orig_dv;
-
-			orig_dv = (ECellDateEditValue *) value;
-			dv = g_new0 (ECellDateEditValue, 1);
-			*dv = *orig_dv;
-
-			return dv;
-		}
-		break;
+		return e_cal_model_copy_cell_date_value (value);
 	}
 
 	return NULL;
@@ -1548,8 +1538,8 @@ cal_model_free_value (ETableModel *etm,
 	case E_CAL_MODEL_FIELD_HAS_ALARMS :
 	case E_CAL_MODEL_FIELD_ICON :
 	case E_CAL_MODEL_FIELD_COLOR :
-	case E_CAL_MODEL_FIELD_DTSTART:
 		break;
+	case E_CAL_MODEL_FIELD_DTSTART:
 	case E_CAL_MODEL_FIELD_CREATED :
 	case E_CAL_MODEL_FIELD_LASTMODIFIED :
 		if (value)
@@ -4357,3 +4347,20 @@ e_cal_model_set_default_time_func (ECalModel *model,
 	model->priv->get_default_time = func;
 	model->priv->get_default_time_user_data = user_data;
 }
+
+
+ECellDateEditValue *
+e_cal_model_copy_cell_date_value (const ECellDateEditValue *value)
+{
+	ECellDateEditValue *copy;
+
+	if (!value)
+		return NULL;
+
+
+	copy = g_new0 (ECellDateEditValue, 1);
+	copy->tt = value->tt;
+	copy->zone = value->zone;
+
+	return copy;
+}
diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h
index 6711c81..98130ed 100644
--- a/calendar/gui/e-cal-model.h
+++ b/calendar/gui/e-cal-model.h
@@ -326,6 +326,10 @@ void		e_cal_model_update_status_message
 						 const gchar *message,
 						 gdouble percent);
 
+ECellDateEditValue *
+		e_cal_model_copy_cell_date_value
+						(const ECellDateEditValue *value);
+
 G_END_DECLS
 
 #endif /* E_CAL_MODEL_H */
diff --git a/calendar/gui/e-cell-date-edit-text.c b/calendar/gui/e-cell-date-edit-text.c
index 1d13953..103e27d 100644
--- a/calendar/gui/e-cell-date-edit-text.c
+++ b/calendar/gui/e-cell-date-edit-text.c
@@ -115,6 +115,7 @@ cell_date_edit_text_get_text (ECellText *cell,
 	ECellDateEditValue *dv = e_table_model_value_at (model, col, row);
 	icaltimezone *timezone;
 	struct tm tmp_tm;
+	gchar *res;
 
 	if (!dv)
 		return g_strdup ("");
@@ -127,9 +128,13 @@ cell_date_edit_text_get_text (ECellText *cell,
 	 * it will be set to the current timezone. See set_value (). */
 	tmp_tm = icaltimetype_to_tm_with_zone (&dv->tt, dv->zone, timezone);
 
-	return e_datetime_format_format_tm (
+	res = e_datetime_format_format_tm (
 		"calendar", "table", dv->tt.is_date ?
 		DTFormatKindDate : DTFormatKindDateTime, &tmp_tm);
+
+	e_table_model_free_value (model, col, dv);
+
+	return res;
 }
 
 static void
diff --git a/calendar/gui/e-month-view.c b/calendar/gui/e-month-view.c
index a159190..265d974 100644
--- a/calendar/gui/e-month-view.c
+++ b/calendar/gui/e-month-view.c
@@ -81,7 +81,7 @@ month_view_cursor_key_down (EWeekView *week_view)
 		if (e_calendar_view_get_selected_time_range (
 			E_CALENDAR_VIEW (week_view), &current, NULL)) {
 
-			current = time_add_week (current, -1);
+			current = time_add_week (current, 1);
 			e_week_view_scroll_a_step (
 				week_view, E_CAL_VIEW_MOVE_PAGE_DOWN);
 			e_week_view_set_selected_time_range_visible (
diff --git a/calendar/gui/ea-calendar-helpers.c b/calendar/gui/ea-calendar-helpers.c
index fec0849..a60751d 100644
--- a/calendar/gui/ea-calendar-helpers.c
+++ b/calendar/gui/ea-calendar-helpers.c
@@ -89,6 +89,10 @@ ea_calendar_helpers_get_cal_view_from (GnomeCanvasItem *canvas_item)
 	/* parent of canvas_item->canvas is the EDayView or EWeekView widget */
 	canvas = canvas_item->canvas;
 	view_widget = gtk_widget_get_parent (GTK_WIDGET (canvas));
+
+	if (view_widget && GTK_IS_BOX (view_widget))
+		view_widget = gtk_widget_get_parent (view_widget);
+
 	if (!view_widget || !E_IS_CALENDAR_VIEW (view_widget))
 		return NULL;
 
diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c
index 7190c05..8620f7e 100644
--- a/calendar/gui/itip-utils.c
+++ b/calendar/gui/itip-utils.c
@@ -132,7 +132,7 @@ itip_get_user_identities (ESourceRegistry *registry)
 
 	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
 
-	list = e_source_registry_list_sources (registry, extension_name);
+	list = e_source_registry_list_enabled (registry, extension_name);
 
 	identities = g_new0 (gchar *, g_list_length (list) + 1);
 
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index 59e1625..d3b5a74 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -192,6 +192,7 @@ e_composer_private_constructed (EMsgComposer *composer)
 	priv->charset = e_composer_get_default_charset ();
 
 	priv->is_from_message = FALSE;
+	priv->disable_signature = FALSE;
 
 	e_composer_actions_init (composer);
 
@@ -883,6 +884,9 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box,
 		goto exit;
 	}
 
+	if (composer->priv->disable_signature)
+		goto exit;
+
 	/* "Edit as New Message" sets "priv->is_from_message".
 	 * Always put the signature at the bottom for that case. */
 	top_signature =
@@ -1036,8 +1040,9 @@ e_composer_update_signature (EMsgComposer *composer)
 
 	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
 
-	/* Do nothing if we're redirecting a message. */
-	if (composer->priv->redirect)
+	/* Do nothing if we're redirecting a message or we disabled
+	 * the signature on purpose */
+	if (composer->priv->redirect || composer->priv->disable_signature)
 		return;
 
 	table = e_msg_composer_get_header_table (composer);
diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h
index b09e025..5dde038 100644
--- a/composer/e-composer-private.h
+++ b/composer/e-composer-private.h
@@ -98,6 +98,7 @@ struct _EMsgComposerPrivate {
 	CamelMimeMessage *redirect;
 
 	gboolean is_from_message;
+	gboolean disable_signature;
 
 	gchar *selected_signature_uid;
 };
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 74ca819..f926311 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -4276,6 +4276,9 @@ e_msg_composer_set_body (EMsgComposer *composer,
 
 	table = e_msg_composer_get_header_table (composer);
 
+	/* Disable signature */
+	priv->disable_signature = TRUE;
+
 	identity_uid = e_composer_header_table_get_identity_uid (table);
 	source = e_composer_header_table_ref_source (table, identity_uid);
 
diff --git a/configure.ac b/configure.ac
index b338750..e9e07a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 dnl Evolution Versions
 m4_define([evo_major_version], [3])
 m4_define([evo_minor_version], [12])
-m4_define([evo_micro_version], [7])
+m4_define([evo_micro_version], [9])
 m4_define([evo_version],
 	[evo_major_version.evo_minor_version.evo_micro_version])
 m4_define([evo_stable_version],
@@ -60,7 +60,6 @@ m4_define([libpst_minimum_version], [0.6.54])
 dnl Optional Packages
 m4_define([champlain_minimum_version], [0.12])
 m4_define([clutter_gtk_minimum_version], [0.90])
-m4_define([geoclue_minimum_version], [0.12.0])
 m4_define([geocode_glib_minimum_version], [3.10])
 m4_define([gladeui_minimum_version], [3.10.0])
 m4_define([gweather_minimum_version], [3.8])
@@ -215,7 +214,6 @@ case "$host" in
 	DL_LIB=''
 	SOFTOKN3_LIB=''
 	CHAMPLAIN_REQUIREMENT=''
-	GEOCLUE_REQUIREMENT=''
 	;;
 *openbsd*|*freebsd*)
 	os_win32=no
@@ -1276,7 +1274,7 @@ fi
 AM_CONDITIONAL(ENABLE_WEATHER, [test "x$enable_weather" != "xno"])
 
 dnl ********************************************************************
-dnl maps in contacts preview requires champlain-gtk, geoclue and clutter
+dnl maps in contacts preview requires champlain-gtk and clutter
 dnl ********************************************************************
 AC_ARG_ENABLE([contact-maps],
 	[AS_HELP_STRING([--enable-contact-maps],
@@ -1298,11 +1296,10 @@ if test "x$enable_contact_maps" = "xyes"; then
 
 	PKG_CHECK_MODULES(
 		[GEO],
-		[geoclue >= geoclue_minimum_version
-		 geocode-glib-1.0 >= geocode_glib_minimum_version],,
+		[geocode-glib-1.0 >= geocode_glib_minimum_version],,
 		[AC_MSG_ERROR([
 
-	geoclue and/or geocode-glib not found.
+	geocode-glib not found.
 
 	If you want to disable the contact maps feature,
 	please append --disable-contact-maps to configure.
diff --git a/e-util/e-activity-proxy.c b/e-util/e-activity-proxy.c
index d0805b2..8ebaed1 100644
--- a/e-util/e-activity-proxy.c
+++ b/e-util/e-activity-proxy.c
@@ -62,11 +62,46 @@ G_DEFINE_TYPE (
 	e_activity_proxy,
 	GTK_TYPE_FRAME)
 
+typedef struct {
+	EActivityProxy *proxy; /* Not referenced */
+	EActivity *activity;   /* Referenced */
+} UnsetTimeoutData;
+
+static void
+unset_timeout_data_free (gpointer ptr)
+{
+	UnsetTimeoutData *utd = ptr;
+
+	if (utd) {
+		g_object_unref (utd->activity);
+		g_free (utd);
+	}
+}
+
+static gboolean
+activity_proxy_unset_timeout_id (gpointer user_data)
+{
+	UnsetTimeoutData *utd = user_data;
+
+	g_return_val_if_fail (utd != NULL, FALSE);
+
+	if (g_source_is_destroyed (g_main_current_source ()))
+		return FALSE;
+
+	g_return_val_if_fail (E_IS_ACTIVITY_PROXY (utd->proxy), FALSE);
+
+	if (g_source_get_id (g_main_current_source ()) == utd->proxy->priv->timeout_id)
+		utd->proxy->priv->timeout_id = 0;
+
+	return FALSE;
+}
+
 static void
 activity_proxy_feedback (EActivityProxy *proxy)
 {
 	EActivity *activity;
 	EActivityState state;
+	UnsetTimeoutData *utd;
 
 	activity = e_activity_proxy_get_activity (proxy);
 	g_return_if_fail (E_IS_ACTIVITY (activity));
@@ -78,11 +113,15 @@ activity_proxy_feedback (EActivityProxy *proxy)
 	if (proxy->priv->timeout_id > 0)
 		g_source_remove (proxy->priv->timeout_id);
 
+	utd = g_new0 (UnsetTimeoutData, 1);
+	utd->proxy = proxy;
 	/* Hold a reference on the EActivity for a short
 	 * period so the activity proxy stays visible. */
+	utd->activity = g_object_ref (activity);
+
 	proxy->priv->timeout_id = e_named_timeout_add_seconds_full (
-		G_PRIORITY_LOW, FEEDBACK_PERIOD, (GSourceFunc) gtk_false,
-		g_object_ref (activity), (GDestroyNotify) g_object_unref);
+		G_PRIORITY_LOW, FEEDBACK_PERIOD, activity_proxy_unset_timeout_id,
+		utd, unset_timeout_data_free);
 }
 
 static void
diff --git a/e-util/e-alert-bar.c b/e-util/e-alert-bar.c
index 233de93..66fbb34 100644
--- a/e-util/e-alert-bar.c
+++ b/e-util/e-alert-bar.c
@@ -202,9 +202,22 @@ alert_bar_response_cb (EAlert *alert,
 	if (g_queue_remove (queue, alert))
 		g_object_unref (alert);
 
-	if (g_queue_is_empty (queue))
+	if (g_queue_is_empty (queue)) {
+		GtkWidget *action_area;
+		GList *children;
+
 		gtk_widget_hide (GTK_WIDGET (alert_bar));
-	else if (was_head) {
+
+		action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (alert_bar));
+
+		/* Remove all buttons from the previous alert. */
+		children = gtk_container_get_children (GTK_CONTAINER (action_area));
+		while (children != NULL) {
+			GtkWidget *child = GTK_WIDGET (children->data);
+			gtk_container_remove (GTK_CONTAINER (action_area), child);
+			children = g_list_delete_link (children, children);
+		}
+	} else if (was_head) {
 		GtkInfoBar *info_bar = GTK_INFO_BAR (alert_bar);
 		gtk_info_bar_response (info_bar, response_id);
 		alert_bar_show_alert (alert_bar);
diff --git a/e-util/e-alert-dialog.c b/e-util/e-alert-dialog.c
index a85c7fe..e072775 100644
--- a/e-util/e-alert-dialog.c
+++ b/e-util/e-alert-dialog.c
@@ -240,6 +240,8 @@ alert_dialog_constructed (GObject *object)
 	gtk_label_set_attributes (GTK_LABEL (widget), list);
 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 	gtk_label_set_selectable (GTK_LABEL (widget), TRUE);
+	gtk_label_set_width_chars (GTK_LABEL (widget), 40);
+	gtk_label_set_max_width_chars (GTK_LABEL (widget), 60);
 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 	gtk_widget_set_can_focus (widget, FALSE);
@@ -248,6 +250,8 @@ alert_dialog_constructed (GObject *object)
 	widget = gtk_label_new (secondary);
 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 	gtk_label_set_selectable (GTK_LABEL (widget), TRUE);
+	gtk_label_set_width_chars (GTK_LABEL (widget), 60);
+	gtk_label_set_max_width_chars (GTK_LABEL (widget), 80);
 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 	gtk_widget_set_can_focus (widget, FALSE);
diff --git a/e-util/e-alert.c b/e-util/e-alert.c
index e98895b..438f523 100644
--- a/e-util/e-alert.c
+++ b/e-util/e-alert.c
@@ -429,7 +429,15 @@ alert_set_tag (EAlert *alert,
 static gboolean
 alert_timeout_cb (gpointer user_data)
 {
-	EAlert *alert = E_ALERT (user_data);
+	EAlert *alert = user_data;
+
+	if (g_source_is_destroyed (g_main_current_source ()))
+		return FALSE;
+
+	g_return_val_if_fail (E_IS_ALERT (alert), FALSE);
+
+	if (g_source_get_id (g_main_current_source ()) == alert->priv->timeout_id)
+		alert->priv->timeout_id = 0;
 
 	e_alert_response (alert, alert->priv->default_response);
 
diff --git a/e-util/e-calendar-item.c b/e-util/e-calendar-item.c
index a8159b0..8d3d2b8 100644
--- a/e-util/e-calendar-item.c
+++ b/e-util/e-calendar-item.c
@@ -1054,7 +1054,7 @@ e_calendar_item_draw (GnomeCanvasItem *canvas_item,
 	ECalendarItem *calitem;
 	GtkWidget *widget;
 	GtkStyleContext *style_context;
-	gint char_height, row, col, row_y, bar_height, col_x;
+	gint char_height, row, col, row_y, bar_height;
 	PangoContext *pango_context;
 	PangoFontMetrics *font_metrics;
 	GdkRGBA bg_color;
@@ -1148,26 +1148,6 @@ e_calendar_item_draw (GnomeCanvasItem *canvas_item,
 		gtk_style_context_restore (style_context);
 
 		for (col = 0; col < calitem->cols; col++) {
-			if (col != 0) {
-				col_x = calitem->x1 + calitem->x_offset
-					+ calitem->month_width * col;
-
-				gtk_style_context_save (style_context);
-				gtk_style_context_add_class (
-					style_context,
-					GTK_STYLE_CLASS_SEPARATOR);
-				cairo_save (cr);
-				gtk_render_line (
-					style_context, cr,
-					(gdouble) col_x - 1 - x,
-					(gdouble) row_y + border.top + 1 - y,
-					(gdouble) row_y + bar_height -
-						border.bottom - 2 - y,
-					(gdouble) col_x - x);
-				cairo_restore (cr);
-				gtk_style_context_restore (style_context);
-			}
-
 			e_calendar_item_draw_month (
 				calitem, cr, x, y,
 				width, height, row, col);
diff --git a/e-util/e-name-selector-entry.c b/e-util/e-name-selector-entry.c
index e0382da..9c6e3ef 100644
--- a/e-util/e-name-selector-entry.c
+++ b/e-util/e-name-selector-entry.c
@@ -63,6 +63,8 @@ struct _ENameSelectorEntryPrivate {
 
 	/* For asynchronous operations. */
 	GQueue cancellables;
+
+	GHashTable *known_contacts; /* gchar * ~> 1 */
 };
 
 enum {
@@ -207,6 +209,11 @@ name_selector_entry_dispose (GObject *object)
 		priv->contact_store = NULL;
 	}
 
+	if (priv->known_contacts) {
+		g_hash_table_destroy (priv->known_contacts);
+		priv->known_contacts = NULL;
+	}
+
 	g_slist_foreach (priv->user_query_fields, (GFunc) g_free, NULL);
 	g_slist_free (priv->user_query_fields);
 	priv->user_query_fields = NULL;
@@ -373,6 +380,77 @@ e_name_selector_entry_class_init (ENameSelectorEntryClass *class)
 		G_TYPE_NONE, 1, G_TYPE_POINTER);
 }
 
+static gchar *
+describe_contact (EContact *contact)
+{
+	GString *description;
+	const gchar *str;
+	GList *emails, *link;
+
+	g_return_val_if_fail (E_IS_CONTACT (contact), NULL);
+
+	emails = e_contact_get (contact, E_CONTACT_EMAIL);
+	/* Cannot merge one contact with multiple addresses with another contact */
+	if (!e_contact_get (contact, E_CONTACT_IS_LIST) && emails && emails->next) {
+		deep_free_list (emails);
+		return NULL;
+	}
+
+	description = g_string_new ("");
+
+	if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+		g_string_append (description, "list\n");
+	} else {
+		g_string_append (description, "indv\n");
+	}
+
+	str = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+	g_string_append (description, str ? str : "");
+	g_string_append (description, "\n");
+
+	str = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+	g_string_append (description, str ? str : "");
+	g_string_append (description, "\n");
+
+	emails = e_contact_get (contact, E_CONTACT_EMAIL);
+	emails = g_list_sort (emails, (GCompareFunc) g_ascii_strcasecmp);
+	for (link = emails; link; link = g_list_next (link)) {
+		str = link->data;
+
+		g_string_append (description, str ? str : "");
+		g_string_append (description, "\n");
+	}
+
+	deep_free_list (emails);
+
+	return g_string_free (description, FALSE);
+}
+
+static gboolean
+is_duplicate_contact_and_remember (ENameSelectorEntry *nsentry,
+				   EContact *contact)
+{
+	gchar *description;
+
+	g_return_val_if_fail (E_IS_NAME_SELECTOR_ENTRY (nsentry), FALSE);
+	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
+
+	description = describe_contact (contact);
+	if (!description) {
+		/* Might be a contact with multiple addresses */
+		return FALSE;
+	}
+
+	if (g_hash_table_lookup (nsentry->priv->known_contacts, description)) {
+		g_free (description);
+		return TRUE;
+	}
+
+	g_hash_table_insert (nsentry->priv->known_contacts, description, GINT_TO_POINTER (1));
+
+	return FALSE;
+}
+
 /* Remove unquoted commas and control characters from string */
 static gchar *
 sanitize_string (const gchar *string)
@@ -1161,6 +1239,7 @@ clear_completion_model (ENameSelectorEntry *name_selector_entry)
 		return;
 
 	e_contact_store_set_query (name_selector_entry->priv->contact_store, NULL);
+	g_hash_table_remove_all (name_selector_entry->priv->known_contacts);
 	priv->is_completing = FALSE;
 }
 
@@ -1184,6 +1263,8 @@ update_completion_model (ENameSelectorEntry *name_selector_entry)
 		cue_str = get_entry_substring (name_selector_entry, range_start, range_end);
 		set_completion_query (name_selector_entry, cue_str);
 		g_free (cue_str);
+
+		g_hash_table_remove_all (name_selector_entry->priv->known_contacts);
 	} else {
 		/* N/A; Clear completion model */
 		clear_completion_model (name_selector_entry);
@@ -2170,6 +2251,9 @@ generate_contact_rows (EContactStore *contact_store,
 	if (!contact_uid)
 		return 0;  /* Can happen with broken databases */
 
+	if (is_duplicate_contact_and_remember (name_selector_entry, contact))
+		return 0;
+
 	if (e_contact_get (contact, E_CONTACT_IS_LIST))
 		return 1;
 
@@ -3231,6 +3315,7 @@ e_name_selector_entry_init (ENameSelectorEntry *name_selector_entry)
 
 	name_selector_entry->priv->minimum_query_length = 3;
 	name_selector_entry->priv->show_address = FALSE;
+	name_selector_entry->priv->known_contacts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
 	/* Edit signals */
 
diff --git a/e-util/e-poolv.c b/e-util/e-poolv.c
index 701e6c2..1207d08 100644
--- a/e-util/e-poolv.c
+++ b/e-util/e-poolv.c
@@ -26,14 +26,9 @@
 
 struct _EPoolv {
 	guchar length;
-	gchar *s[1];
+	const gchar *s[1];
 };
 
-static GHashTable *poolv_pool;
-static CamelMemPool *poolv_mempool;
-
-G_LOCK_DEFINE_STATIC (poolv);
-
 /**
  * e_poolv_new:
  * @size: The number of elements in the poolv, maximum of 254 elements.
@@ -57,17 +52,6 @@ e_poolv_new (guint size)
 	poolv = g_malloc0 (sizeof (*poolv) + (size - 1) * sizeof (gchar *));
 	poolv->length = size;
 
-	G_LOCK (poolv);
-
-	if (!poolv_pool)
-		poolv_pool = g_hash_table_new (g_str_hash, g_str_equal);
-
-	if (!poolv_mempool)
-		poolv_mempool = camel_mempool_new (
-			32 * 1024, 512, CAMEL_MEMPOOL_ALIGN_BYTE);
-
-	G_UNLOCK (poolv);
-
 	return poolv;
 }
 
@@ -91,26 +75,21 @@ e_poolv_set (EPoolv *poolv,
              gchar *str,
              gint freeit)
 {
+	const gchar *old_str;
+
 	g_return_val_if_fail (poolv != NULL, NULL);
 	g_return_val_if_fail (index >= 0 && index < poolv->length, NULL);
 
 	if (!str) {
+		camel_pstring_free (poolv->s[index]);
 		poolv->s[index] = NULL;
 		return poolv;
 	}
 
-	G_LOCK (poolv);
+	old_str = poolv->s[index];
+	poolv->s[index] = (gchar *) camel_pstring_add (str, freeit);
 
-	if ((poolv->s[index] = g_hash_table_lookup (poolv_pool, str)) != NULL) {
-	} else {
-		poolv->s[index] = camel_mempool_strdup (poolv_mempool, str);
-		g_hash_table_insert (poolv_pool, poolv->s[index], poolv->s[index]);
-	}
-
-	G_UNLOCK (poolv);
-
-	if (freeit)
-		g_free (str);
+	camel_pstring_free (old_str);
 
 	return poolv;
 }
@@ -147,7 +126,13 @@ e_poolv_get (EPoolv *poolv,
 void
 e_poolv_destroy (EPoolv *poolv)
 {
+	gint ii;
+
 	g_return_if_fail (poolv != NULL);
 
+	for (ii = 0; ii < poolv->length; ii++) {
+		camel_pstring_free (poolv->s[ii]);
+	}
+
 	g_free (poolv);
 }
diff --git a/e-util/e-spell-entry.c b/e-util/e-spell-entry.c
index 75c7a6a..00e27f2 100644
--- a/e-util/e-spell-entry.c
+++ b/e-util/e-spell-entry.c
@@ -66,6 +66,8 @@ word_misspelled (ESpellEntry *entry,
 	const gchar *text;
 	gchar *word;
 	gboolean result = TRUE;
+	GSList *li;
+	gssize wlen;
 
 	if (start == end)
 		return FALSE;
@@ -75,16 +77,13 @@ word_misspelled (ESpellEntry *entry,
 
 	g_strlcpy (word, text + start, end - start + 1);
 
-	if (g_unichar_isalpha (*word)) {
-		GSList *li;
-		gssize wlen = strlen (word);
+	wlen = strlen (word);
 
-		for (li = entry->priv->checkers; li; li = g_slist_next (li)) {
-			GtkhtmlSpellChecker *checker = li->data;
-			if (gtkhtml_spell_checker_check_word (checker, word, wlen)) {
-				result = FALSE;
-				break;
-			}
+	for (li = entry->priv->checkers; li; li = g_slist_next (li)) {
+		GtkhtmlSpellChecker *checker = li->data;
+		if (gtkhtml_spell_checker_check_word (checker, word, wlen)) {
+			result = FALSE;
+			break;
 		}
 	}
 
diff --git a/e-util/e-table-extras.c b/e-util/e-table-extras.c
index 07f81ba..43fca94 100644
--- a/e-util/e-table-extras.c
+++ b/e-util/e-table-extras.c
@@ -113,7 +113,11 @@ e_int64ptr_compare (gconstpointer data1,
 {
 	const gint64 *pa = data1, *pb = data2;
 
-	return (*pa == *pb) ? 0 : (*pa < *pb) ? -1 : 1;
+	if (pa && pb)
+		return (*pa == *pb) ? 0 : (*pa < *pb) ? -1 : 1;
+
+	/* sort unset values before set */
+	return (!pa && !pb) ? 0 : (pa ? 1 : -1);
 }
 
 /* UTF-8 strncasecmp - not optimized */
diff --git a/e-util/gal-a11y-e-table-click-to-add.c b/e-util/gal-a11y-e-table-click-to-add.c
index 6fabe31..6386ebb 100644
--- a/e-util/gal-a11y-e-table-click-to-add.c
+++ b/e-util/gal-a11y-e-table-click-to-add.c
@@ -145,7 +145,13 @@ etcta_get_name (AtkObject *obj)
 static gint
 etcta_get_n_children (AtkObject *accessible)
 {
-	return 1;
+	ETableClickToAdd * etcta;
+
+	etcta = E_TABLE_CLICK_TO_ADD (
+		atk_gobject_accessible_get_object (
+		ATK_GOBJECT_ACCESSIBLE (accessible)));
+
+	return (etcta->rect || etcta->row) ? 1 : 0;
 }
 
 static AtkObject *
diff --git a/e-util/gal-a11y-e-table-item.c b/e-util/gal-a11y-e-table-item.c
index a650d68..6990d4d 100644
--- a/e-util/gal-a11y-e-table-item.c
+++ b/e-util/gal-a11y-e-table-item.c
@@ -1115,7 +1115,7 @@ gal_a11y_e_table_item_new (ETableItem *item)
 	AtkObject *parent;
 	const gchar *name;
 
-	g_return_val_if_fail (item && item->cols >= 0 && item->rows >= 0, NULL);
+	g_return_val_if_fail (item && item->cols >= 0, NULL);
 	a11y = g_object_new (gal_a11y_e_table_item_get_type (), NULL);
 
 	atk_object_initialize (ATK_OBJECT (a11y), item);
@@ -1133,7 +1133,7 @@ gal_a11y_e_table_item_new (ETableItem *item)
 	GET_PRIVATE (a11y)->item = item;
 	/* Initialize cell data. */
 	GET_PRIVATE (a11y)->cols = item->cols;
-	GET_PRIVATE (a11y)->rows = item->rows;
+	GET_PRIVATE (a11y)->rows = item->rows >= 0 ? item->rows : 0;
 
 	GET_PRIVATE (a11y)->columns = e_table_header_get_columns (item->header);
 	if (GET_PRIVATE (a11y)->columns == NULL)
diff --git a/e-util/gal-a11y-e-table.c b/e-util/gal-a11y-e-table.c
index 26bcc03..e766b18 100644
--- a/e-util/gal-a11y-e-table.c
+++ b/e-util/gal-a11y-e-table.c
@@ -132,9 +132,10 @@ et_get_n_children (AtkObject *accessible)
 	et = E_TABLE (gtk_accessible_get_widget (GTK_ACCESSIBLE (a11y)));
 
 	if (et && et->group) {
-		if (E_IS_TABLE_GROUP_LEAF (et->group))
-			n = 1;
-		else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
+		if (E_IS_TABLE_GROUP_LEAF (et->group)) {
+			if (find_first_table_item (et->group))
+				n++;
+		} else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
 			ETableGroupContainer *etgc = (ETableGroupContainer *) et->group;
 			n = g_list_length (etgc->children);
 		}
@@ -162,11 +163,13 @@ et_ref_child (AtkObject *accessible,
 	if (i == 0 || i < child_no - 1) {
 		if (E_IS_TABLE_GROUP_LEAF (et->group)) {
 			ETableItem *eti = find_first_table_item (et->group);
-			AtkObject *aeti = eti_get_accessible (eti, accessible);
-			if (aeti)
-				g_object_ref (aeti);
-			return aeti;
-
+			AtkObject *aeti;
+			if (eti) {
+				aeti = eti_get_accessible (eti, accessible);
+				if (aeti)
+					g_object_ref (aeti);
+				return aeti;
+			}
 		} else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
 			ETableGroupContainer *etgc = (ETableGroupContainer *) et->group;
 			ETableGroupContainerChildNode *child_node = g_list_nth_data (etgc->children, i);
@@ -179,7 +182,9 @@ et_ref_child (AtkObject *accessible,
 				return aeti;
 			}
 		}
-	} else if (i == child_no -1) {
+	}
+
+	if (i == child_no -1) {
 		ETableClickToAdd * etcta;
 
 		if (et && et->use_click_to_add && et->click_to_add) {
diff --git a/em-format/e-mail-parser-multipart-mixed.c b/em-format/e-mail-parser-multipart-mixed.c
index ad94895..432fef4 100644
--- a/em-format/e-mail-parser-multipart-mixed.c
+++ b/em-format/e-mail-parser-multipart-mixed.c
@@ -69,12 +69,13 @@ empe_mp_mixed_parse (EMailParserExtension *extension,
 		EMailPart *mail_part;
 		CamelMimePart *subpart;
 		CamelContentType *ct;
+		gboolean handled;
 
 		subpart = camel_multipart_get_part (mp, i);
 
 		g_string_append_printf (part_id, ".mixed.%d", i);
 
-		e_mail_parser_parse_part (
+		handled = e_mail_parser_parse_part (
 			parser, subpart, part_id, cancellable, &work_queue);
 
 		mail_part = g_queue_peek_head (&work_queue);
@@ -95,7 +96,7 @@ empe_mp_mixed_parse (EMailParserExtension *extension,
 				parser, subpart, part_id, &work_queue);
 
 		/* Force messages to be expandable */
-		} else if (mail_part == NULL ||
+		} else if ((mail_part == NULL && !handled) ||
 		    (camel_content_type_is (ct, "message", "*") &&
 		     mail_part != NULL &&
 		     !e_mail_part_get_is_attachment (mail_part))) {
diff --git a/em-format/e-mail-parser-text-plain.c b/em-format/e-mail-parser-text-plain.c
index 26e459c..7fbc59c 100644
--- a/em-format/e-mail-parser-text-plain.c
+++ b/em-format/e-mail-parser-text-plain.c
@@ -45,29 +45,6 @@ static const gchar *parser_mime_types[] = {
 };
 
 static gboolean
-part_is_empty (CamelMimePart *part)
-{
-	CamelDataWrapper *dw;
-	GByteArray *ba;
-	guint i;
-
-	dw = camel_medium_get_content (CAMEL_MEDIUM (part));
-	ba = camel_data_wrapper_get_byte_array (dw);
-
-	if (!ba)
-		return TRUE;
-
-	for (i = 0; i < ba->len; i++) {
-
-		/* Checks for \n, \t, \f, \r, \v and space */
-		if (!isspace (ba->data[i]))
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
 process_part (EMailParser *parser,
               GString *part_id,
               gint part_number,
@@ -80,9 +57,6 @@ process_part (EMailParser *parser,
 	EMailPart *mail_part;
 	gint s_len = part_id->len;
 
-	if (part_is_empty (part))
-		return TRUE;
-
 	type = camel_mime_part_get_content_type (part);
 	if (!camel_content_type_is (type, "text", "*")) {
 		e_mail_parser_parse_part (
diff --git a/evolution.doap b/evolution.doap
index 70f1a05..dcdd89b 100644
--- a/evolution.doap
+++ b/evolution.doap
@@ -7,6 +7,7 @@
 
   <name xml:lang="en">evolution</name>
   <shortdesc xml:lang="en">Manage your email, contacts and schedule</shortdesc>
+  <description>Manage your email, contacts and schedule</description>
   <homepage rdf:resource="http://live.gnome.org/Apps/Evolution"; />
   <mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/evolution-list"; />
   <download-page rdf:resource="http://download.gnome.org/sources/evolution"; />
@@ -15,18 +16,6 @@
   <programming-language>C</programming-language>
   <programming-language>XML</programming-language>
 
-  <!-- Project Leads -->
-
-  <maintainer>
-    <foaf:Person>
-      <foaf:name>Matthew Barnes</foaf:name>
-      <foaf:mbox rdf:resource="mailto:mbarnes@redhat.com"; />
-      <gnome:userid>mbarnes</gnome:userid>
-    </foaf:Person>
-  </maintainer>
-
-  <!-- Alphabetically -->
-
   <maintainer>
     <foaf:Person>
       <foaf:name>Milan Crha</foaf:name>
diff --git a/help/Makefile.am b/help/Makefile.am
index a0777a0..353a1ad 100644
--- a/help/Makefile.am
+++ b/help/Makefile.am
@@ -238,6 +238,6 @@ HELP_FILES = \
 	xinclude-mail-account-identity.xml \
 	xinclude-searching.xml
 
-HELP_LINGUAS = cs de el en_GB es eu fr gl hu mk oc ru sl sv te zh_CN
+HELP_LINGUAS = cs de el en_GB es eu fr gl hu ja mk oc ru sl sv te zh_CN
 
 -include $(top_srcdir)/git.mk
diff --git a/help/ja/ja.po b/help/ja/ja.po
new file mode 100644
index 0000000..e94558e
diff --git a/libemail-engine/e-mail-session-utils.c b/libemail-engine/e-mail-session-utils.c
index 524b09d..a248eac 100644
--- a/libemail-engine/e-mail-session-utils.c
+++ b/libemail-engine/e-mail-session-utils.c
@@ -878,7 +878,8 @@ e_mail_session_send_to (EMailSession *session,
 		NULL, CAMEL_MIME_PART (message)->headers);
 	((CamelMessageInfoBase *) info)->size =
 		get_message_size (message, cancellable);
-	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0);
+	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN |
+		(camel_mime_message_has_attachment (message) ? CAMEL_MESSAGE_ATTACHMENTS : 0), ~0);
 
 	/* expand, or remove empty, group addresses */
 	em_utils_expand_groups (CAMEL_INTERNET_ADDRESS (recipients));
diff --git a/libemail-engine/mail-ops.c b/libemail-engine/mail-ops.c
index df0b6d0..969fbcb 100644
--- a/libemail-engine/mail-ops.c
+++ b/libemail-engine/mail-ops.c
@@ -569,6 +569,22 @@ static void	report_status		(struct _send_queue_msg *m,
 					 const gchar *desc,
 					 ...);
 
+static guint32
+get_message_size (CamelMimeMessage *message,
+                  GCancellable *cancellable)
+{
+	CamelStream *null;
+	guint32 size;
+
+	null = camel_stream_null_new ();
+	camel_data_wrapper_write_to_stream_sync (
+		CAMEL_DATA_WRAPPER (message), null, cancellable, NULL);
+	size = CAMEL_STREAM_NULL (null)->written;
+	g_object_unref (null);
+
+	return size;
+}
+
 /* send 1 message to a specific transport */
 static void
 mail_send_message (struct _send_queue_msg *m,
@@ -666,7 +682,9 @@ mail_send_message (struct _send_queue_msg *m,
 
 	/* Now check for posting, failures are ignored */
 	info = camel_message_info_new (NULL);
-	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0);
+	((CamelMessageInfoBase *) info)->size = get_message_size (message, cancellable);
+	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN |
+		(camel_mime_message_has_attachment (message) ? CAMEL_MESSAGE_ATTACHMENTS : 0), ~0);
 
 	for (header = xev; header && !local_error; header = header->next) {
 		gchar *uri;
diff --git a/libgnomecanvas/gnome-canvas-pixbuf.c b/libgnomecanvas/gnome-canvas-pixbuf.c
index 1250897..87c3c26 100644
--- a/libgnomecanvas/gnome-canvas-pixbuf.c
+++ b/libgnomecanvas/gnome-canvas-pixbuf.c
@@ -272,6 +272,9 @@ gnome_canvas_pixbuf_draw (GnomeCanvasItem *item,
 
 	gnome_canvas_item_i2c_matrix (item, &matrix);
 
+	matrix.x0 -= x;
+	matrix.y0 -= y;
+
 	cairo_save (cr);
 	cairo_transform (cr, &matrix);
 
diff --git a/mail/e-mail-printer.c b/mail/e-mail-printer.c
index 3d93196..6205a50 100644
--- a/mail/e-mail-printer.c
+++ b/mail/e-mail-printer.c
@@ -367,7 +367,8 @@ mail_printer_new_web_view (const gchar *charset,
 		G_OBJECT (web_settings),
 		"enable-frame-flattening", FALSE, NULL);
 
-	e_mail_display_set_force_load_images (E_MAIL_DISPLAY (web_view), TRUE);
+	/* Do not load remote images, print what user sees in the preview panel */
+	e_mail_display_set_force_load_images (E_MAIL_DISPLAY (web_view), FALSE);
 
 	formatter = e_mail_display_get_formatter (E_MAIL_DISPLAY (web_view));
 	if (charset != NULL && *charset != '\0')
diff --git a/mail/e-mail-ui-session.c b/mail/e-mail-ui-session.c
index 96db4bb..3f12abc 100644
--- a/mail/e-mail-ui-session.c
+++ b/mail/e-mail-ui-session.c
@@ -631,12 +631,16 @@ mail_ui_session_user_alert (CamelSession *session,
 	g_free (display_name);
 }
 
+extern gint camel_application_is_exiting;
+
 static void
 mail_ui_session_refresh_service (EMailSession *session,
                                  CamelService *service)
 {
-	if (camel_session_get_online (CAMEL_SESSION (session)))
+	if (!camel_application_is_exiting &&
+	    camel_session_get_online (CAMEL_SESSION (session))) {
 		mail_receive_service (service);
+	}
 }
 
 static EMVFolderContext *
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index fb6d19a..98b392f 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -795,8 +795,8 @@ composer_save_to_drafts_append_mail (AsyncContext *async_context,
 
 	info = camel_message_info_new (NULL);
 
-	camel_message_info_set_flags (
-		info, CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_SEEN, ~0);
+	camel_message_info_set_flags (info, CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_SEEN |
+		(camel_mime_message_has_attachment (async_context->message) ? CAMEL_MESSAGE_ATTACHMENTS : 0), ~0);
 
 	camel_medium_remove_header (
 		CAMEL_MEDIUM (async_context->message),
@@ -1758,6 +1758,12 @@ forward_non_attached (EMailBackend *backend,
 	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
 
 	forward = quoting_text (QUOTING_FORWARD);
+	if (style == E_MAIL_FORWARD_STYLE_INLINE && forward) {
+		gchar *tmp = forward;
+		forward = g_strconcat (forward, "<br>", NULL);
+		g_free (tmp);
+	}
+
 	text = em_utils_message_to_html (
 		CAMEL_SESSION (session), message,
 		forward, flags, NULL, NULL, &validity_found);
@@ -2118,7 +2124,7 @@ reply_get_composer (EShell *shell,
 	if ((subject = (gchar *) camel_mime_message_get_subject (message))) {
 		gboolean skip_len = -1;
 
-		if (em_utils_is_re_in_subject (subject, &skip_len) && skip_len > 0)
+		if (em_utils_is_re_in_subject (subject, &skip_len, NULL) && skip_len > 0)
 			subject = subject + skip_len;
 
 		subject = g_strdup_printf ("Re: %s", subject);
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 2291e08..eb8324f 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -1446,10 +1446,10 @@ check_prefix (const gchar *subject,
 
 gboolean
 em_utils_is_re_in_subject (const gchar *subject,
-                           gint *skip_len)
+                           gint *skip_len,
+			   const gchar * const *use_prefixes_strv)
 {
-	GSettings *settings;
-	gchar *prefixes, **prefixes_strv;
+	gchar **prefixes_strv;
 	gboolean res;
 	gint ii;
 
@@ -1464,18 +1464,25 @@ em_utils_is_re_in_subject (const gchar *subject,
 	if (check_prefix (subject, "Re", skip_len))
 		return TRUE;
 
-	settings = g_settings_new ("org.gnome.evolution.mail");
-	prefixes = g_settings_get_string (settings, "composer-localized-re");
-	g_object_unref (settings);
+	if (use_prefixes_strv) {
+		prefixes_strv = (gchar **) use_prefixes_strv;
+	} else {
+		GSettings *settings;
+		gchar *prefixes;
 
-	if (!prefixes || !*prefixes) {
+		settings = g_settings_new ("org.gnome.evolution.mail");
+		prefixes = g_settings_get_string (settings, "composer-localized-re");
+		g_object_unref (settings);
+
+		if (!prefixes || !*prefixes) {
+			g_free (prefixes);
+			return FALSE;
+		}
+
+		prefixes_strv = g_strsplit (prefixes, ",", -1);
 		g_free (prefixes);
-		return FALSE;
 	}
 
-	prefixes_strv = g_strsplit (prefixes, ",", -1);
-	g_free (prefixes);
-
 	if (!prefixes_strv)
 		return FALSE;
 
@@ -1488,7 +1495,8 @@ em_utils_is_re_in_subject (const gchar *subject,
 			res = check_prefix (subject, prefix, skip_len);
 	}
 
-	g_strfreev (prefixes_strv);
+	if (!use_prefixes_strv)
+		g_strfreev (prefixes_strv);
 
 	return res;
 }
diff --git a/mail/em-utils.h b/mail/em-utils.h
index 6725a06..3127145 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -76,7 +76,8 @@ gchar *em_utils_url_unescape_amp (const gchar *url);
 void emu_restore_folder_tree_state (EMFolderTree *folder_tree);
 
 gboolean	em_utils_is_re_in_subject	(const gchar *subject,
-						 gint *skip_len);
+						 gint *skip_len,
+						 const gchar * const *use_prefixes_strv);
 
 G_END_DECLS
 
diff --git a/mail/message-list.c b/mail/message-list.c
index 995dac5..864e1ec 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -116,6 +116,10 @@ struct _MessageListPrivate {
 	const gchar *newest_read_uid;
 	time_t oldest_unread_date;
 	const gchar *oldest_unread_uid;
+
+	GSettings *mail_settings;
+	gchar **re_prefixes;
+	GMutex re_prefixes_lock;
 };
 
 /* XXX Plain GNode suffers from O(N) tail insertions, and that won't
@@ -776,8 +780,11 @@ get_normalised_string (MessageList *message_list,
 
 		subject = string;
 		while (found_re) {
+			g_mutex_lock (&message_list->priv->re_prefixes_lock);
 			found_re = em_utils_is_re_in_subject (
-				subject, &skip_len) && skip_len > 0;
+				subject, &skip_len, (const gchar * const *) message_list->priv->re_prefixes) && skip_len > 0;
+			g_mutex_unlock (&message_list->priv->re_prefixes_lock);
+
 			if (found_re)
 				subject += skip_len;
 
@@ -1529,7 +1536,8 @@ add_all_labels_foreach (ETreeModel *etm,
 }
 
 static const gchar *
-get_trimmed_subject (CamelMessageInfo *info)
+get_trimmed_subject (CamelMessageInfo *info,
+		     MessageList *message_list)
 {
 	const gchar *subject;
 	const gchar *mlist;
@@ -1561,8 +1569,10 @@ get_trimmed_subject (CamelMessageInfo *info)
 		while (found_re) {
 			found_re = FALSE;
 
+			g_mutex_lock (&message_list->priv->re_prefixes_lock);
 			found_re = em_utils_is_re_in_subject (
-				subject, &skip_len) && skip_len > 0;
+				subject, &skip_len, (const gchar * const *) message_list->priv->re_prefixes) && skip_len > 0;
+			g_mutex_unlock (&message_list->priv->re_prefixes_lock);
 			if (found_re)
 				subject += skip_len;
 
@@ -1677,7 +1687,7 @@ ml_tree_value_at_ex (ETreeModel *etm,
 		str = camel_message_info_subject (msg_info);
 		return (gpointer)(str ? str : "");
 	case COL_SUBJECT_TRIMMED:
-		str = get_trimmed_subject (msg_info);
+		str = get_trimmed_subject (msg_info, message_list);
 		return (gpointer)(str ? str : "");
 	case COL_SUBJECT_NORM:
 		return (gpointer) get_normalised_string (message_list, msg_info, col);
@@ -2726,6 +2736,7 @@ message_list_dispose (GObject *object)
 	g_clear_object (&priv->session);
 	g_clear_object (&priv->folder);
 	g_clear_object (&priv->invisible);
+	g_clear_object (&priv->mail_settings);
 
 	g_clear_object (&message_list->extras);
 
@@ -2757,9 +2768,11 @@ message_list_finalize (GObject *object)
 	g_free (message_list->search);
 	g_free (message_list->frozen_search);
 	g_free (message_list->cursor_uid);
+	g_strfreev (message_list->priv->re_prefixes);
 
 	g_mutex_clear (&message_list->priv->regen_lock);
 	g_mutex_clear (&message_list->priv->thread_tree_lock);
+	g_mutex_clear (&message_list->priv->re_prefixes_lock);
 
 	clear_selection (message_list, &message_list->priv->clipboard);
 
@@ -3366,6 +3379,7 @@ message_list_init (MessageList *message_list)
 
 	g_mutex_init (&message_list->priv->regen_lock);
 	g_mutex_init (&message_list->priv->thread_tree_lock);
+	g_mutex_init (&message_list->priv->re_prefixes_lock);
 
 	/* TODO: Should this only get the selection if we're realised? */
 	p = message_list->priv;
@@ -3395,6 +3409,9 @@ message_list_init (MessageList *message_list)
 	/* FIXME This is currently unused. */
 	target_list = gtk_target_list_new (NULL, 0);
 	message_list->priv->paste_target_list = target_list;
+
+	message_list->priv->mail_settings = g_settings_new ("org.gnome.evolution.mail");
+	message_list->priv->re_prefixes = NULL;
 }
 
 static void
@@ -5866,6 +5883,7 @@ mail_regen_list (MessageList *message_list,
 	GCancellable *cancellable;
 	RegenData *new_regen_data;
 	RegenData *old_regen_data;
+	gchar *prefixes;
 
 	/* Report empty search as NULL, not as one/two-space string. */
 	if (search && (strcmp (search, " ") == 0 || strcmp (search, "  ") == 0))
@@ -5878,6 +5896,13 @@ mail_regen_list (MessageList *message_list,
 		return;
 	}
 
+	g_mutex_lock (&message_list->priv->re_prefixes_lock);
+	g_strfreev (message_list->priv->re_prefixes);
+	prefixes = g_settings_get_string (message_list->priv->mail_settings, "composer-localized-re");
+	message_list->priv->re_prefixes = g_strsplit (prefixes ? prefixes : "", ",", -1);
+	g_free (prefixes);
+	g_mutex_unlock (&message_list->priv->re_prefixes_lock);
+
 	g_mutex_lock (&message_list->priv->regen_lock);
 
 	old_regen_data = message_list->priv->regen_data;
diff --git a/modules/composer-autosave/e-composer-autosave.c b/modules/composer-autosave/e-composer-autosave.c
index 52c0cfb..7330ab6 100644
--- a/modules/composer-autosave/e-composer-autosave.c
+++ b/modules/composer-autosave/e-composer-autosave.c
@@ -171,7 +171,9 @@ composer_autosave_constructed (GObject *object)
 
 	extensible = e_extension_get_extensible (E_EXTENSION (object));
 
-	e_signal_connect_notify_swapped (
+	/* Do not use e_signal_connect_notify_swapped() here,
+	   this module relies on "false" change notifications. */
+	g_signal_connect_swapped (
 		extensible, "notify::changed",
 		G_CALLBACK (composer_autosave_changed_cb), object);
 }
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
index a93191c..84f4c13 100644
--- a/modules/mail/e-mail-shell-view-actions.c
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -467,6 +467,9 @@ mark_all_read_thread (GSimpleAsyncResult *simple,
 
 		camel_folder_thaw (folder);
 
+		/* Save changes to the server immediately. */
+		camel_folder_synchronize_sync (folder, FALSE, cancellable, &error);
+
 		camel_folder_free_uids (folder, uids);
 		g_object_unref (folder);
 	}
diff --git a/modules/tnef-attachment/e-mail-parser-tnef-attachment.c b/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
index 033c83d..b67f31f 100644
--- a/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
+++ b/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
@@ -71,7 +71,7 @@ G_DEFINE_DYNAMIC_TYPE (
 
 static const gchar *parser_mime_types[] = {
 	"application/vnd.ms-tnef",
-	"application/ms-tnefl",
+	"application/ms-tnef",
 	NULL
 };
 
diff --git a/plugins/mail-to-task/mail-to-task.c b/plugins/mail-to-task/mail-to-task.c
index 065df23..6de6729 100644
--- a/plugins/mail-to-task/mail-to-task.c
+++ b/plugins/mail-to-task/mail-to-task.c
@@ -824,7 +824,9 @@ do_manage_comp_idle (struct _manage_comp *mc)
 }
 
 typedef struct {
+	EClientCache *client_cache;
 	ESource *source;
+	const gchar *extension_name;
 	ECalClientSourceType source_type;
 	CamelFolder *folder;
 	GPtrArray *uids;
@@ -840,8 +842,8 @@ do_mail_to_event (AsyncData *data)
 	GPtrArray *uids = data->uids;
 	GError *error = NULL;
 
-	client = e_cal_client_connect_sync (
-		data->source, data->source_type, NULL, &error);
+	client = e_client_cache_get_client_sync (data->client_cache,
+		data->source, data->extension_name, NULL, &error);
 
 	/* Sanity check. */
 	g_return_val_if_fail (
@@ -1036,6 +1038,7 @@ do_mail_to_event (AsyncData *data)
 	g_ptr_array_unref (uids);
 	g_object_unref (folder);
 
+	g_object_unref (data->client_cache);
 	g_object_unref (data->source);
 	g_free (data->selected_text);
 	g_free (data);
@@ -1197,7 +1200,9 @@ mail_to_event (ECalClientSourceType source_type,
 
 		/* Fill the elements in AsynData */
 		data = g_new0 (AsyncData, 1);
+		data->client_cache = g_object_ref (e_shell_get_client_cache (shell));
 		data->source = g_object_ref (source);
+		data->extension_name = extension_name;
 		data->source_type = source_type;
 		data->folder = e_mail_reader_ref_folder (reader);
 		data->uids = g_ptr_array_ref (uids);
diff --git a/plugins/publish-calendar/publish-format-fb.c b/plugins/publish-calendar/publish-format-fb.c
index caa88c4..0a064a9 100644
--- a/plugins/publish-calendar/publish-format-fb.c
+++ b/plugins/publish-calendar/publish-format-fb.c
@@ -88,9 +88,11 @@ write_calendar (const gchar *uid,
 	source = e_source_registry_ref_source (registry, uid);
 
 	if (source != NULL) {
-		client = e_cal_client_connect_sync (
-			source, E_CAL_CLIENT_SOURCE_TYPE_EVENTS,
-			NULL, error);
+		EClientCache *client_cache;
+
+		client_cache = e_shell_get_client_cache (shell);
+		client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, NULL, error);
+
 		g_object_unref (source);
 	} else {
 		g_set_error (
diff --git a/plugins/publish-calendar/publish-format-ical.c b/plugins/publish-calendar/publish-format-ical.c
index 33cc45d..06215a6 100644
--- a/plugins/publish-calendar/publish-format-ical.c
+++ b/plugins/publish-calendar/publish-format-ical.c
@@ -91,9 +91,11 @@ write_calendar (const gchar *uid,
 	source = e_source_registry_ref_source (registry, uid);
 
 	if (source != NULL) {
-		client = e_cal_client_connect_sync (
-			source, E_CAL_CLIENT_SOURCE_TYPE_EVENTS,
-			NULL, error);
+		EClientCache *client_cache;
+
+		client_cache = e_shell_get_client_cache (shell);
+		client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, NULL, error);
+
 		g_object_unref (source);
 	} else {
 		g_set_error (
diff --git a/plugins/save-calendar/csv-format.c b/plugins/save-calendar/csv-format.c
index 650d01b..498f5e5 100644
--- a/plugins/save-calendar/csv-format.c
+++ b/plugins/save-calendar/csv-format.c
@@ -303,7 +303,7 @@ userstring_to_systemstring (const gchar *userstring)
 static void
 do_save_calendar_csv (FormatHandler *handler,
                       ESourceSelector *selector,
-                      ECalClientSourceType type,
+		      EClientCache *client_cache,
                       gchar *dest_uri)
 {
 
@@ -331,8 +331,8 @@ do_save_calendar_csv (FormatHandler *handler,
 
 	/* open source client */
 	primary_source = e_source_selector_ref_primary_selection (selector);
-	source_client = e_cal_client_connect_sync (
-		primary_source, type, NULL, &error);
+	source_client = e_client_cache_get_client_sync (client_cache,
+		primary_source, e_source_selector_get_extension_name (selector), NULL, &error);
 	g_object_unref (primary_source);
 
 	/* Sanity check. */
diff --git a/plugins/save-calendar/format-handler.h b/plugins/save-calendar/format-handler.h
index 88946e8..dd5ec64 100644
--- a/plugins/save-calendar/format-handler.h
+++ b/plugins/save-calendar/format-handler.h
@@ -37,7 +37,7 @@ struct _FormatHandler
 
 	void	(*save)		(FormatHandler *handler,
 				 ESourceSelector *selector,
-				 ECalClientSourceType type,
+				 EClientCache *client_cache,
 				 gchar *dest_uri);
 };
 
diff --git a/plugins/save-calendar/ical-format.c b/plugins/save-calendar/ical-format.c
index 617405f..fb79479 100644
--- a/plugins/save-calendar/ical-format.c
+++ b/plugins/save-calendar/ical-format.c
@@ -89,7 +89,7 @@ append_tz_to_comp (gpointer key,
 static void
 do_save_calendar_ical (FormatHandler *handler,
                        ESourceSelector *selector,
-                       ECalClientSourceType type,
+		       EClientCache *client_cache,
                        gchar *dest_uri)
 {
 	ESource *primary_source;
@@ -103,8 +103,8 @@ do_save_calendar_ical (FormatHandler *handler,
 
 	/* open source client */
 	primary_source = e_source_selector_ref_primary_selection (selector);
-	source_client = e_cal_client_connect_sync (
-		primary_source, type, NULL, &error);
+	source_client = e_client_cache_get_client_sync (client_cache,
+		primary_source, e_source_selector_get_extension_name (selector), NULL, &error);
 	g_object_unref (primary_source);
 
 	/* Sanity check. */
diff --git a/plugins/save-calendar/rdf-format.c b/plugins/save-calendar/rdf-format.c
index 50abdca..377b5df 100644
--- a/plugins/save-calendar/rdf-format.c
+++ b/plugins/save-calendar/rdf-format.c
@@ -173,7 +173,7 @@ add_string_to_rdf (xmlNodePtr node,
 static void
 do_save_calendar_rdf (FormatHandler *handler,
                       ESourceSelector *selector,
-                      ECalClientSourceType type,
+		      EClientCache *client_cache,
                       gchar *dest_uri)
 {
 
@@ -198,8 +198,8 @@ do_save_calendar_rdf (FormatHandler *handler,
 
 	/* open source client */
 	primary_source = e_source_selector_ref_primary_selection (selector);
-	source_client = e_cal_client_connect_sync (
-		primary_source, type, NULL, &error);
+	source_client = e_client_cache_get_client_sync (client_cache,
+		primary_source, e_source_selector_get_extension_name (selector), NULL, &error);
 	g_object_unref (primary_source);
 
 	/* Sanity check. */
diff --git a/plugins/save-calendar/save-calendar.c b/plugins/save-calendar/save-calendar.c
index c5d373e..723a1c2 100644
--- a/plugins/save-calendar/save-calendar.c
+++ b/plugins/save-calendar/save-calendar.c
@@ -110,7 +110,7 @@ format_handlers_foreach_free (gpointer data)
 
 static void
 ask_destination_and_save (ESourceSelector *selector,
-                          ECalClientSourceType type)
+			  EClientCache *client_cache)
 {
 	FormatHandler *handler = NULL;
 
@@ -219,7 +219,7 @@ ask_destination_and_save (ESourceSelector *selector,
 				dest_uri = temp;
 			}
 
-			handler->save (handler, selector, type, dest_uri);
+			handler->save (handler, selector, client_cache, dest_uri);
 		} else {
 			g_warn_if_reached ();
 		}
@@ -291,17 +291,20 @@ open_for_writing (GtkWindow *parent,
 }
 
 static void
-save_general (EShellView *shell_view,
-              ECalClientSourceType type)
+save_general (EShellView *shell_view)
 {
 	EShellSidebar *shell_sidebar;
+	EShellBackend *shell_backend;
+	EShell *shell;
 	ESourceSelector *selector = NULL;
 
+	shell_backend = e_shell_view_get_shell_backend (shell_view);
 	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	shell = e_shell_backend_get_shell (shell_backend);
 	g_object_get (shell_sidebar, "selector", &selector, NULL);
 	g_return_if_fail (selector != NULL);
 
-	ask_destination_and_save (selector, type);
+	ask_destination_and_save (selector, e_shell_get_client_cache (shell));
 
 	g_object_unref (selector);
 }
@@ -310,21 +313,21 @@ static void
 action_calendar_save_as_cb (GtkAction *action,
                             EShellView *shell_view)
 {
-	save_general (shell_view, E_CAL_CLIENT_SOURCE_TYPE_EVENTS);
+	save_general (shell_view);
 }
 
 static void
 action_memo_list_save_as_cb (GtkAction *action,
                              EShellView *shell_view)
 {
-	save_general (shell_view, E_CAL_CLIENT_SOURCE_TYPE_MEMOS);
+	save_general (shell_view);
 }
 
 static void
 action_task_list_save_as_cb (GtkAction *action,
                              EShellView *shell_view)
 {
-	save_general (shell_view, E_CAL_CLIENT_SOURCE_TYPE_TASKS);
+	save_general (shell_view);
 }
 
 gboolean
diff --git a/po/cs.po b/po/cs.po
index 8965467..a660d1c 100644
diff --git a/po/de.po b/po/de.po
index c66b8c1..254443b 100644
diff --git a/po/es.po b/po/es.po
index 043eee2..9247c0a 100644
diff --git a/po/fi.po b/po/fi.po
index d9d7ddb..0eb3c83 100644
diff --git a/po/fr.po b/po/fr.po
index f3a8abc..fc75467 100644
diff --git a/po/gl.po b/po/gl.po
index 0d5f552..a7bdb42 100644
diff --git a/po/lt.po b/po/lt.po
index b5d7139..d7f0d67 100644
diff --git a/po/nb.po b/po/nb.po
index 3644c63..8257359 100644
diff --git a/po/pt.po b/po/pt.po
index c5dd761..2c8d204 100644
diff --git a/shell/e-shell-switcher.c b/shell/e-shell-switcher.c
index a4d6394..a979919 100644
--- a/shell/e-shell-switcher.c
+++ b/shell/e-shell-switcher.c
@@ -53,6 +53,7 @@ struct _EShellSwitcherPrivate {
 	GtkSettings *settings;
 	gulong settings_handler_id;
 	gboolean toolbar_visible;
+	gint hpaned_handle_size;
 };
 
 enum {
@@ -115,7 +116,7 @@ shell_switcher_layout_actions (EShellSwitcher *switcher)
 	}
 
 	/* Figure out how many rows and columns we'll use. */
-	btns_per_row = MAX (1, allocation.width / (max_width + H_PADDING));
+	btns_per_row = MAX (1, (allocation.width - 1) / (max_width + H_PADDING + H_PADDING - switcher->priv->hpaned_handle_size));
 	if (!icons_only) {
 		/* If using text buttons, we want to try to have a
 		 * completely filled-in grid, but if we can't, we want
@@ -150,20 +151,22 @@ shell_switcher_layout_actions (EShellSwitcher *switcher)
 
 	/* Layout the buttons. */
 	for (i = row_last; i >= 0; i--) {
-		gint len, extra_width;
+		gint len, extra_width, left_width;
 
+		left_width = allocation.width - 1;
 		x = H_PADDING + allocation.x;
 		y -= max_height;
 		len = g_list_length (rows[i]);
-		if (!icons_only)
-			extra_width =
-				(allocation.width - (len * max_width) -
-				(len * H_PADDING)) / len;
-		else
-			extra_width = 0;
-		for (p = rows[i]; p != NULL; p = p->next) {
+		for (p = rows[i]; p != NULL; p = p->next, len--) {
 			GtkAllocation child_allocation;
 
+			if (!icons_only)
+				extra_width =
+					(left_width - (len * max_width) -
+					(len * H_PADDING + H_PADDING - switcher->priv->hpaned_handle_size)) / len;
+			else
+				extra_width = 0;
+
 			child_allocation.x = x;
 			child_allocation.y = y;
 			child_allocation.width = max_width + extra_width;
@@ -173,6 +176,7 @@ shell_switcher_layout_actions (EShellSwitcher *switcher)
 				GTK_WIDGET (p->data), &child_allocation);
 
 			x += child_allocation.width + H_PADDING;
+			left_width = left_width - child_allocation.width - H_PADDING;
 		}
 
 		y -= V_PADDING;
@@ -451,6 +455,31 @@ shell_switcher_style_changed (EShellSwitcher *switcher,
 	g_object_notify (G_OBJECT (switcher), "toolbar-style");
 }
 
+static void
+shell_switcher_read_handle_size (EShellSwitcher *switcher)
+{
+	GtkWidget *paned;
+
+	g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+	paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
+	gtk_widget_style_get (paned, "handle-size", &switcher->priv->hpaned_handle_size, NULL);
+	gtk_widget_destroy (paned);
+
+	if (switcher->priv->hpaned_handle_size < 0)
+		switcher->priv->hpaned_handle_size = 0;
+	else if (switcher->priv->hpaned_handle_size > H_PADDING)
+		switcher->priv->hpaned_handle_size = H_PADDING;
+}
+
+static void
+shell_switcher_style_updated_cb (EShellSwitcher *switcher)
+{
+	g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+	shell_switcher_read_handle_size (switcher);
+}
+
 static GtkIconSize
 shell_switcher_get_icon_size (GtkToolShell *shell)
 {
@@ -568,6 +597,12 @@ e_shell_switcher_init (EShellSwitcher *switcher)
 	gtk_widget_set_has_window (GTK_WIDGET (switcher), FALSE);
 
 	e_extensible_load_extensions (E_EXTENSIBLE (switcher));
+
+	switcher->priv->hpaned_handle_size = 5;
+
+	shell_switcher_read_handle_size (switcher);
+
+	g_signal_connect (switcher, "style-updated", G_CALLBACK (shell_switcher_style_updated_cb), NULL);
 }
 
 static void
diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c
index 9146b54..7b5bfea 100644
--- a/shell/e-shell-window-actions.c
+++ b/shell/e-shell-window-actions.c
@@ -40,7 +40,6 @@
 static const gchar *authors[] = {
 	"The Evolution Team",
 	"",
-	"Matthew Barnes <mbarnes@redhat.com>",
 	"Milan Crha <mcrha@redhat.com>",
 	"Fabiano Fid\xC3\xAAncio <fabiano@fidencio.org>",
 	"",

--- End Message ---
--- Begin Message ---
On Sun, 2014-11-30 at 22:46 +0100, Josselin Mouette wrote:
> Control: tags -1 -moreinfo
> 
> Le dimanche 30 novembre 2014 à 16:46 +0000, Adam D. Barratt a écrit :
> > Please go ahead, and ensure that the upload is in unstable before
> > December 5th, removing the "moreinfo" tag once the package has been
> > accepted.
> 
> It’s done.

Unblocked.

Regards,

Adam

--- End Message ---

Reply to: