diff -Nru geary-0.12.0/bindings/vapi/libsecret-1.vapi geary-0.12.4/bindings/vapi/libsecret-1.vapi --- geary-0.12.0/bindings/vapi/libsecret-1.vapi 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/bindings/vapi/libsecret-1.vapi 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* libsecret-1.vapi generated by vapigen-0.18 and hand-edited to add SCHEMA_COMPAT_NETWORK */ - -[CCode (cprefix = "Secret", gir_namespace = "Secret", gir_version = "1", lower_case_cprefix = "secret_")] -namespace Secret { - [CCode (cheader_filename = "libsecret/secret.h", cname = "SECRET_SCHEMA_COMPAT_NETWORK")] - public Secret.Schema SCHEMA_COMPAT_NETWORK; - - [CCode (cheader_filename = "libsecret/secret.h", copy_function = "g_boxed_copy", free_function = "g_boxed_free", type_id = "secret_schema_get_type ()")] - [Compact] - public class Schema { - [CCode (array_length = false, array_null_terminated = true)] - public weak Secret.SchemaAttribute[] attributes; - public Secret.SchemaFlags flags; - public weak string name; - [CCode (has_construct_function = false)] - public Schema (string name, Secret.SchemaFlags flags, ...); - [CCode (cname = "secret_schema_newv", has_construct_function = false)] - public Schema.newv (string name, Secret.SchemaFlags flags, GLib.HashTable attribute_names_and_types); - public Secret.Schema @ref (); - public void unref (); - } - [CCode (cheader_filename = "libsecret/secret.h", copy_function = "g_boxed_copy", free_function = "g_boxed_free", type_id = "secret_schema_attribute_get_type ()")] - [Compact] - public class SchemaAttribute { - public weak string name; - public Secret.SchemaAttributeType type; - } - [CCode (cheader_filename = "libsecret/secret.h", cprefix = "SECRET_ERROR_", has_type_id = false)] - public enum Error { - PROTOCOL, - IS_LOCKED, - NO_SUCH_OBJECT, - ALREADY_EXISTS; - public static GLib.Quark get_quark (); - } - [CCode (cheader_filename = "libsecret/secret.h", cprefix = "SECRET_SCHEMA_ATTRIBUTE_", has_type_id = false)] - public enum SchemaAttributeType { - STRING, - INTEGER, - BOOLEAN - } - [CCode (cheader_filename = "libsecret/secret.h", cprefix = "SECRET_SCHEMA_", has_type_id = false)] - [Flags] - public enum SchemaFlags { - NONE, - DONT_MATCH_NAME - } - [CCode (cheader_filename = "libsecret/secret.h", cname = "SECRET_COLLECTION_DEFAULT")] - public const string COLLECTION_DEFAULT; - [CCode (cheader_filename = "libsecret/secret.h", cname = "SECRET_COLLECTION_SESSION")] - public const string COLLECTION_SESSION; - [CCode (cheader_filename = "libsecret/secret.h")] - public static GLib.HashTable attributes_build (Secret.Schema schema, ...); - [CCode (cheader_filename = "libsecret/secret.h")] - public static GLib.HashTable attributes_buildv (Secret.Schema schema, va_list va); - [CCode (cheader_filename = "libsecret/secret.h")] - public static async bool password_clear (Secret.Schema schema, GLib.Cancellable? cancellable, ...) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h")] - public static bool password_clear_sync (Secret.Schema schema, GLib.Cancellable? cancellable = null, ...) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h", finish_name = "secret_password_clear_finish")] - public static async bool password_clearv (Secret.Schema schema, GLib.HashTable attributes, GLib.Cancellable? cancellable) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h")] - public static bool password_clearv_sync (Secret.Schema schema, GLib.HashTable attributes, GLib.Cancellable? cancellable = null) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h")] - public static async string password_lookup (Secret.Schema schema, GLib.Cancellable? cancellable, ...) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h")] - public static string password_lookup_sync (Secret.Schema schema, GLib.Cancellable? cancellable = null, ...) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h", finish_name = "secret_password_lookup_finish")] - public static async string password_lookupv (Secret.Schema schema, GLib.HashTable attributes, GLib.Cancellable? cancellable) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h")] - public static string password_lookupv_sync (Secret.Schema schema, GLib.HashTable attributes, GLib.Cancellable? cancellable = null) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h")] - public static async bool password_store (Secret.Schema schema, string? collection, string label, string password, GLib.Cancellable? cancellable, ...) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h")] - public static bool password_store_sync (Secret.Schema schema, string? collection, string label, string password, GLib.Cancellable? cancellable = null, ...) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h", finish_name = "secret_password_store_finish")] - public static async bool password_storev (Secret.Schema schema, GLib.HashTable attributes, string? collection, string label, string password, GLib.Cancellable? cancellable) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h")] - public static bool password_storev_sync (Secret.Schema schema, GLib.HashTable attributes, string? collection, string label, string password, GLib.Cancellable? cancellable = null) throws GLib.Error; - [CCode (cheader_filename = "libsecret/secret.h")] - public static void password_wipe (string? password); -} diff -Nru geary-0.12.0/CMakeLists.txt geary-0.12.4/CMakeLists.txt --- geary-0.12.0/CMakeLists.txt 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/CMakeLists.txt 2018-08-29 13:57:20.000000000 +0000 @@ -19,7 +19,7 @@ # set(GETTEXT_PACKAGE "geary") set(RELEASE_NAME "Lightweight email client for GNOME.") -set(VERSION "0.12-dev") +set(VERSION "0.12.4") set(VERSION_INFO "Release") set(LANGUAGE_SUPPORT_DIRECTORY ${CMAKE_INSTALL_PREFIX}/share/locale) diff -Nru geary-0.12.0/debian/changelog geary-0.12.4/debian/changelog --- geary-0.12.0/debian/changelog 2018-01-22 17:38:32.000000000 +0000 +++ geary-0.12.4/debian/changelog 2019-02-12 15:04:41.000000000 +0000 @@ -1,10 +1,64 @@ -geary (0.12.0-1ubuntu1) bionic; urgency=medium +geary (0.12.4-4~ubuntu18.04.1~ppa1) bionic; urgency=medium - * Sync with Debian. Remaining change: - - debian/control: Build-depend on libmessaging-menu-dev and - libunity-dev for better Unity integration. + * No-change backport to bionic - -- Jeremy Bicha Mon, 22 Jan 2018 12:38:32 -0500 + -- Amr Ibrahim Tue, 12 Feb 2019 16:04:41 +0100 + +geary (0.12.4-4) unstable; urgency=medium + + * Cherry-pick Actually-use-error-variable.patch: + - Fix build with latest vala + + -- Jeremy Bicha Mon, 24 Dec 2018 12:07:05 -0500 + +geary (0.12.4-3) unstable; urgency=medium + + * Add -Wl,-O1 to our LDFLAGS + * Bump Standards-Version to 4.3.0 + + -- Jeremy Bicha Mon, 24 Dec 2018 09:19:50 -0500 + +geary (0.12.4-2) unstable; urgency=medium + + * Cherry-pick 3 patches to fix build with webkit2gtk 2.22 + * Bump minimum libwebkit2gtk-4.0-dev to 2.22 + + -- Jeremy Bicha Sat, 15 Sep 2018 11:03:58 -0400 + +geary (0.12.4-1) unstable; urgency=medium + + * New upstream release (Closes: #904387, #907942) + * Opt in to Ubuntu language packs (LP: #1779574) + * Bump Standards-Version to 4.2.1 + + -- Jeremy Bicha Tue, 04 Sep 2018 21:42:43 -0400 + +geary (0.12.2-2) unstable; urgency=medium + + * Adjust ugly hack to use linux-firmware-free instead of openrc + * Bump Standards-Version to 4.1.4 + + -- Jeremy Bicha Sun, 13 May 2018 13:17:50 -0400 + +geary (0.12.2-1) unstable; urgency=medium + + * New upstream release + * Use an ugly hack to build-depend on libmessaging-menu-dev and + libunity-dev on Ubuntu but not on Debian since those packages + don't exist in Debian. + + -- Jeremy Bicha Sat, 12 May 2018 00:20:24 -0400 + +geary (0.12.1-1) unstable; urgency=medium + + [ Jeremy Bicha ] + * New upstream release + + [ Simon McVittie ] + * Update Vcs-* for migration from collab-maint svn to GNOME git + * debian/gbp.conf: Add + + -- Jeremy Bicha Sun, 18 Mar 2018 14:59:59 -0400 geary (0.12.0-1) unstable; urgency=medium diff -Nru geary-0.12.0/debian/control geary-0.12.4/debian/control --- geary-0.12.0/debian/control 2018-01-22 17:38:32.000000000 +0000 +++ geary-0.12.4/debian/control 2018-12-24 17:07:05.000000000 +0000 @@ -1,12 +1,11 @@ # This file is autogenerated. DO NOT EDIT! -# +# # Modifications should be made to debian/control.in instead. # This file is regenerated automatically in the clean target. Source: geary Section: mail Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian GNOME Maintainers +Maintainer: Debian GNOME Maintainers Uploaders: Jeremy Bicha Build-Depends: cmake (>= 2.8.0), debhelper (>= 11), @@ -22,18 +21,19 @@ libglib2.0-dev (>= 2.42.0), libgmime-2.6-dev (>= 2.6.14), libgtk-3-dev (>= 3.14.0), - libmessaging-menu-dev, - libunity-dev, + firmware-linux-free | libmessaging-menu-dev, + firmware-linux-free | libunity-dev, libnotify-dev (>= 0.7.5), libsecret-1-dev (>= 0.11), libsqlite3-dev (>= 3.7.4), - libwebkit2gtk-4.0-dev (>= 2.10), + libwebkit2gtk-4.0-dev (>= 2.22), libxml2-dev (>= 2.7.8), valac (>= 0.22.1) -Standards-Version: 4.1.3 -Vcs-Svn: svn://anonscm.debian.org/collab-maint/deb-maint/geary/trunk -Vcs-Browser: https://anonscm.debian.org/viewvc/collab-maint/deb-maint/geary/trunk +Standards-Version: 4.3.0 +X-Ubuntu-Use-Langpack: yes Homepage: https://wiki.gnome.org/Apps/Geary +Vcs-Git: https://salsa.debian.org/gnome-team/geary.git +Vcs-Browser: https://salsa.debian.org/gnome-team/geary Package: geary Architecture: any diff -Nru geary-0.12.0/debian/control.in geary-0.12.4/debian/control.in --- geary-0.12.0/debian/control.in 2018-01-22 17:38:10.000000000 +0000 +++ geary-0.12.4/debian/control.in 2018-12-24 17:07:05.000000000 +0000 @@ -1,8 +1,7 @@ Source: geary Section: mail Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian GNOME Maintainers +Maintainer: Debian GNOME Maintainers Uploaders: @GNOME_TEAM@ Build-Depends: cmake (>= 2.8.0), debhelper (>= 11), @@ -18,18 +17,19 @@ libglib2.0-dev (>= 2.42.0), libgmime-2.6-dev (>= 2.6.14), libgtk-3-dev (>= 3.14.0), - libmessaging-menu-dev, - libunity-dev, + firmware-linux-free | libmessaging-menu-dev, + firmware-linux-free | libunity-dev, libnotify-dev (>= 0.7.5), libsecret-1-dev (>= 0.11), libsqlite3-dev (>= 3.7.4), - libwebkit2gtk-4.0-dev (>= 2.10), + libwebkit2gtk-4.0-dev (>= 2.22), libxml2-dev (>= 2.7.8), valac (>= 0.22.1) -Standards-Version: 4.1.3 -Vcs-Svn: svn://anonscm.debian.org/collab-maint/deb-maint/geary/trunk -Vcs-Browser: https://anonscm.debian.org/viewvc/collab-maint/deb-maint/geary/trunk +Standards-Version: 4.3.0 +X-Ubuntu-Use-Langpack: yes Homepage: https://wiki.gnome.org/Apps/Geary +Vcs-Git: https://salsa.debian.org/gnome-team/geary.git +Vcs-Browser: https://salsa.debian.org/gnome-team/geary Package: geary Architecture: any diff -Nru geary-0.12.0/debian/gbp.conf geary-0.12.4/debian/gbp.conf --- geary-0.12.0/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/debian/gbp.conf 2018-12-24 17:07:05.000000000 +0000 @@ -0,0 +1,14 @@ +[DEFAULT] +pristine-tar = True +debian-branch = debian/master +upstream-branch = upstream/latest +upstream-vcs-tag = geary-%(version)s + +[buildpackage] +sign-tags = True + +[import-orig] +postimport = dch -v%(version)s New upstream release; git add debian/changelog; debcommit + +[pq] +patch-numbers = False diff -Nru geary-0.12.0/debian/patches/Actually-use-error-variable.patch geary-0.12.4/debian/patches/Actually-use-error-variable.patch --- geary-0.12.0/debian/patches/Actually-use-error-variable.patch 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/debian/patches/Actually-use-error-variable.patch 2018-12-24 17:07:05.000000000 +0000 @@ -0,0 +1,21 @@ +From: Rico Tzschichholz +Date: Tue, 27 Nov 2018 14:53:56 +0100 +Subject: Actually use error variable to check for IOError.CANCELLED + +--- + src/client/application/geary-controller.vala | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala +index d73afa3..f9a4565 100644 +--- a/src/client/application/geary-controller.vala ++++ b/src/client/application/geary-controller.vala +@@ -2522,7 +2522,7 @@ public class GearyController : Geary.BaseObject { + yield do_empty_folder_async(emptyable, cancellable); + } catch (Error err) { + // don't report to user if cancelled +- if (cancellable is IOError.CANCELLED) ++ if (err is IOError.CANCELLED) + return; + + ErrorDialog dialog = new ErrorDialog(main_window, diff -Nru geary-0.12.0/debian/patches/Adjust-to-upstream-javascriptcore-4.0-bindings.patch geary-0.12.4/debian/patches/Adjust-to-upstream-javascriptcore-4.0-bindings.patch --- geary-0.12.0/debian/patches/Adjust-to-upstream-javascriptcore-4.0-bindings.patch 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/debian/patches/Adjust-to-upstream-javascriptcore-4.0-bindings.patch 2018-12-24 17:07:05.000000000 +0000 @@ -0,0 +1,184 @@ +From: Rico Tzschichholz +Date: Mon, 23 Apr 2018 19:56:18 +0200 +Subject: Adjust to upstream javascriptcore-4.0 bindings + +--- + .../conversation-viewer/conversation-web-view.vala | 2 +- + src/client/util/util-webkit.vala | 10 ++++---- + src/client/web-process/web-process-extension.vala | 17 +++++------- + src/engine/util/util-js.vala | 30 +++++++++++++++------- + 4 files changed, 33 insertions(+), 26 deletions(-) + +diff --git a/src/client/conversation-viewer/conversation-web-view.vala b/src/client/conversation-viewer/conversation-web-view.vala +index 3d2ac5f..ef69f44 100644 +--- a/src/client/conversation-viewer/conversation-web-view.vala ++++ b/src/client/conversation-viewer/conversation-web-view.vala +@@ -183,7 +183,7 @@ public class ConversationWebView : ClientWebView { + + private void on_deceptive_link_clicked(WebKit.JavascriptResult result) { + try { +- JS.GlobalContext context = result.get_global_context(); ++ unowned JS.GlobalContext context = result.get_global_context(); + JS.Object details = WebKitUtil.to_object(result); + + uint reason = (uint) Geary.JS.to_number( +diff --git a/src/client/util/util-webkit.vala b/src/client/util/util-webkit.vala +index 319e28a..cba9eaf 100644 +--- a/src/client/util/util-webkit.vala ++++ b/src/client/util/util-webkit.vala +@@ -18,8 +18,8 @@ namespace WebKitUtil { + */ + public bool to_bool(WebKit.JavascriptResult result) + throws Geary.JS.Error { +- JS.GlobalContext context = result.get_global_context(); +- JS.Value value = result.get_value(); ++ unowned JS.GlobalContext context = result.get_global_context(); ++ unowned JS.Value value = result.get_value(); + if (!value.is_boolean(context)) { + throw new Geary.JS.Error.TYPE("Result is not a JS Boolean object"); + } +@@ -59,12 +59,12 @@ namespace WebKitUtil { + */ + public string as_string(WebKit.JavascriptResult result) + throws Geary.JS.Error { +- JS.GlobalContext context = result.get_global_context(); +- JS.Value js_str_value = result.get_value(); ++ unowned JS.GlobalContext context = result.get_global_context(); ++ unowned JS.Value js_str_value = result.get_value(); + JS.Value? err = null; + JS.String js_str = js_str_value.to_string_copy(context, out err); + Geary.JS.check_exception(context, err); +- return Geary.JS.to_string_released(js_str); ++ return Geary.JS.to_string_released((owned) js_str); + } + + /** +diff --git a/src/client/web-process/web-process-extension.vala b/src/client/web-process/web-process-extension.vala +index ee89139..1f478a6 100644 +--- a/src/client/web-process/web-process-extension.vala ++++ b/src/client/web-process/web-process-extension.vala +@@ -87,10 +87,9 @@ public class GearyWebExtension : Object { + bool should_load = false; + WebKit.Frame frame = page.get_main_frame(); + // Explicit cast fixes build on s390x/ppc64. Bug 783882 +- JS.GlobalContext context = (JS.GlobalContext) +- frame.get_javascript_global_context(); ++ unowned JS.GlobalContext context = frame.get_javascript_global_context(); + try { +- JS.Value ret = execute_script( ++ unowned JS.Value ret = execute_script( + context, "geary.allowRemoteImages", int.parse("__LINE__") + ); + should_load = ret.to_boolean(context); +@@ -106,8 +105,7 @@ public class GearyWebExtension : Object { + private void remote_image_load_blocked(WebKit.WebPage page) { + WebKit.Frame frame = page.get_main_frame(); + // Explicit cast fixes build on s390x/ppc64. Bug 783882 +- JS.GlobalContext context = (JS.GlobalContext) +- frame.get_javascript_global_context(); ++ unowned JS.GlobalContext context = frame.get_javascript_global_context(); + try { + execute_script( + context, "geary.remoteImageLoadBlocked();", int.parse("__LINE__") +@@ -123,8 +121,7 @@ public class GearyWebExtension : Object { + private void selection_changed(WebKit.WebPage page) { + WebKit.Frame frame = page.get_main_frame(); + // Explicit cast fixes build on s390x/ppc64. Bug 783882 +- JS.GlobalContext context = (JS.GlobalContext) +- frame.get_javascript_global_context(); ++ unowned JS.GlobalContext context = frame.get_javascript_global_context(); + try { + execute_script( + context, "geary.selectionChanged();", int.parse("__LINE__") +@@ -136,20 +133,18 @@ public class GearyWebExtension : Object { + + // Return type is nullable as a workaround for Bug 778046, it will + // never actually be null. +- private JS.Value? execute_script(JS.Context context, string script, int line) ++ private unowned JS.Value? execute_script(JS.Context context, string script, int line) + throws Geary.JS.Error { + JS.String js_script = new JS.String.create_with_utf8_cstring(script); + JS.String js_source = new JS.String.create_with_utf8_cstring("__FILE__"); + JS.Value? err = null; + try { +- JS.Value ret = context.evaluate_script( ++ unowned JS.Value ret = context.evaluate_script( + js_script, null, js_source, line, out err + ); + Geary.JS.check_exception(context, err); + return ret; + } finally { +- js_script.release(); +- js_source.release(); + } + } + +diff --git a/src/engine/util/util-js.vala b/src/engine/util/util-js.vala +index 4d22429..ea955e9 100644 +--- a/src/engine/util/util-js.vala ++++ b/src/engine/util/util-js.vala +@@ -10,6 +10,16 @@ + */ + namespace Geary.JS { + ++#if !VALA_0_42 ++ // Workaround broken version of this in the vala bindings. See Bug ++ // 788113. ++ [CCode (cname = "JSStringGetUTF8CString")] ++ private extern size_t js_string_get_utf8_cstring( ++ global::JS.String js, ++ [CCode (array_length_type = "gsize")] char[] buffer ++ ); ++#endif ++ + /** + * Errors produced by functions in {@link Geary.JS}. + */ +@@ -72,7 +82,7 @@ namespace Geary.JS { + global::JS.String js_str = value.to_string_copy(context, out err); + Geary.JS.check_exception(context, err); + +- return Geary.JS.to_string_released(js_str); ++ return Geary.JS.to_string_released((owned) js_str); + } + + /** +@@ -101,12 +111,15 @@ namespace Geary.JS { + /** + * Returns a JSC {@link JS.String} as a Vala {@link string}. + */ +- public inline string to_string_released(global::JS.String js) { +- int len = js.get_maximum_utf8_cstring_size(); +- string str = string.nfill(len, 0); +- js.get_utf8_cstring(str, len); +- js.release(); +- return str; ++ public inline string to_string_released(owned global::JS.String js) { ++ size_t len = js.get_maximum_utf8_cstring_size(); ++ uint8[] str = new uint8[len]; ++#if VALA_0_42 ++ js.get_utf8_cstring(str); ++#else ++ js_string_get_utf8_cstring(js, (char[]) str); ++#endif ++ return (string) str; + } + + /** +@@ -128,7 +141,6 @@ namespace Geary.JS { + try { + Geary.JS.check_exception(context, err); + } finally { +- js_name.release(); + } + return prop; + } +@@ -157,7 +169,7 @@ namespace Geary.JS { + + throw new Error.EXCEPTION( + "JS exception thrown [%s]: %s" +- .printf(err_type.to_string(), to_string_released(err_str)) ++ .printf(err_type.to_string(), to_string_released((owned) err_str)) + ); + } + } diff -Nru geary-0.12.0/debian/patches/bindings-Drop-custom-javascriptcore-4.0-and-webkit2gtk-4..patch geary-0.12.4/debian/patches/bindings-Drop-custom-javascriptcore-4.0-and-webkit2gtk-4..patch --- geary-0.12.0/debian/patches/bindings-Drop-custom-javascriptcore-4.0-and-webkit2gtk-4..patch 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/debian/patches/bindings-Drop-custom-javascriptcore-4.0-and-webkit2gtk-4..patch 2018-12-24 17:07:05.000000000 +0000 @@ -0,0 +1,327 @@ +From: Rico Tzschichholz +Date: Thu, 22 Jun 2017 15:01:19 +0200 +Subject: bindings: Drop custom javascriptcore-4.0 and webkit2gtk-4.0 vapi + +--- + bindings/metadata/Soup-2.4.metadata | 3 - + bindings/metadata/WebKit2-4.0.metadata | 15 -- + .../metadata/WebKit2WebExtension-4.0-custom.vala | 5 - + bindings/metadata/WebKit2WebExtension-4.0.metadata | 9 -- + bindings/vapi/javascriptcore-4.0.vapi | 155 --------------------- + src/CMakeLists.txt | 39 +----- + test/CMakeLists.txt | 2 +- + 7 files changed, 4 insertions(+), 224 deletions(-) + delete mode 100644 bindings/metadata/Soup-2.4.metadata + delete mode 100644 bindings/metadata/WebKit2-4.0.metadata + delete mode 100644 bindings/metadata/WebKit2WebExtension-4.0-custom.vala + delete mode 100644 bindings/metadata/WebKit2WebExtension-4.0.metadata + delete mode 100644 bindings/vapi/javascriptcore-4.0.vapi + +diff --git a/bindings/metadata/Soup-2.4.metadata b/bindings/metadata/Soup-2.4.metadata +deleted file mode 100644 +index f3e72e8..0000000 +--- a/bindings/metadata/Soup-2.4.metadata ++++ /dev/null +@@ -1,3 +0,0 @@ +-AuthDomain.accepts skip +-AuthDomain.challenge skip +- +diff --git a/bindings/metadata/WebKit2-4.0.metadata b/bindings/metadata/WebKit2-4.0.metadata +deleted file mode 100644 +index 3e3044f..0000000 +--- a/bindings/metadata/WebKit2-4.0.metadata ++++ /dev/null +@@ -1,15 +0,0 @@ +- +-JavascriptResult +- .get_global_context nullable=false unowned=true +- .get_value nullable=false unowned=true +- +-//Forward upstream +-Download +- .failed#signal.error type="WebKit.DownloadError" +-PrintOperation +- .failed#signal.error type="WebKit.PrintError" +-WebResource +- .failed#signal.error type="GLib.Error" +-WebView +- .load_failed#signal.error type="GLib.Error" +- .show_option_menu#signal skip +diff --git a/bindings/metadata/WebKit2WebExtension-4.0-custom.vala b/bindings/metadata/WebKit2WebExtension-4.0-custom.vala +deleted file mode 100644 +index a994a77..0000000 +--- a/bindings/metadata/WebKit2WebExtension-4.0-custom.vala ++++ /dev/null +@@ -1,5 +0,0 @@ +-namespace WebKit { +- namespace DOM { +- public delegate void EventTargetFunc (WebKit.DOM.EventTarget target, WebKit.DOM.Event event); +- } +-} +diff --git a/bindings/metadata/WebKit2WebExtension-4.0.metadata b/bindings/metadata/WebKit2WebExtension-4.0.metadata +deleted file mode 100644 +index c496dba..0000000 +--- a/bindings/metadata/WebKit2WebExtension-4.0.metadata ++++ /dev/null +@@ -1,9 +0,0 @@ +-DOM* parent="WebKit.DOM" name="DOM(.+)" +- +-DOMEventTarget.add_event_listener skip +-_ContextMenu skip +-_ContextMenuItem skip +- +-Frame.get_javascript_* nullable=false unowned=true +- +-DOMEventTarget.add_event_listener_with_closure.handler type="owned WebKit.DOM.EventTargetFunc" +diff --git a/bindings/vapi/javascriptcore-4.0.vapi b/bindings/vapi/javascriptcore-4.0.vapi +deleted file mode 100644 +index d152ce2..0000000 +--- a/bindings/vapi/javascriptcore-4.0.vapi ++++ /dev/null +@@ -1,155 +0,0 @@ +-/* +- * Copyright 2017 Michael Gratton +- * +- * This software is licensed under the GNU Lesser General Public License +- * (version 2.1 or later). See the COPYING file in this distribution. +- */ +- +-[CCode (cprefix = "JS", +- gir_namespace = "JavaScriptCore", +- gir_version = "4.0", +- lower_case_cprefix = "JS_", +- cheader_filename = "JavaScriptCore/JavaScript.h")] +-namespace JS { +- +- [CCode (cname = "JSContextRef")] +- [SimpleType] +- public struct Context { +- +- [CCode (cname = "JSEvaluateScript")] +- public Value evaluate_script(String script, +- Object? thisObject, +- String? sourceURL, +- int startingLineNumber, +- out Value? exception); +- +- [CCode (cname = "JSCheckScriptSyntax")] +- public Value check_script_syntax(String script, +- String? sourceURL, +- int startingLineNumber, +- out Value? exception); +- +- } +- +- [CCode (cname = "JSGlobalContextRef")] +- [SimpleType] +- public struct GlobalContext : Context { +- +- [CCode (cname = "JSGlobalContextRetain")] +- public bool retain(); +- +- [CCode (cname = "JSGlobalContextRelease")] +- public bool release(); +- +- } +- +- [CCode (cname = "JSType", has_type_id = false)] +- public enum Type { +- +- [CCode (cname = "kJSTypeUndefined")] +- UNDEFINED, +- +- [CCode (cname = "kJSTypeNull")] +- NULL, +- +- [CCode (cname = "kJSTypeBoolean")] +- BOOLEAN, +- +- [CCode (cname = "kJSTypeNumber")] +- NUMBER, +- +- [CCode (cname = "kJSTypeString")] +- STRING, +- +- [CCode (cname = "kJSTypeObject")] +- OBJECT +- } +- +- [CCode (cname = "JSObjectRef")] +- [SimpleType] +- public struct Object { +- +- [CCode (cname = "JSObjectMakeFunction")] +- public Object.make_function(String? name, +- [CCode (array_length_pos=1.5)] +- String[]? parameterNames, +- String body, +- String? sourceURL, +- int startingLineNumber, +- out Value? exception); +- +- [CCode (cname = "JSObjectCallAsFunction", instance_pos = 1.1)] +- public Value call_as_function(Context ctx, +- Object? thisObject, +- [CCode (array_length_pos=2.5)] +- Value[]? arguments, +- out Value? exception); +- +- [CCode (cname = "JSObjectHasProperty", instance_pos = 1.1)] +- public bool has_property(Context ctx, String property_name); +- +- [CCode (cname = "JSObjectGetProperty", instance_pos = 1.1)] +- public Value get_property(Context ctx, +- String property_name, +- out Value? exception); +- +- } +- +- [CCode (cname = "JSValueRef")] +- [SimpleType] +- public struct Value { +- +- [CCode (cname = "JSValueGetType", instance_pos = 1.1)] +- public Type get_type(Context context); +- +- [CCode (cname = "JSValueIsBoolean", instance_pos = 1.1)] +- public bool is_boolean(Context ctx); +- +- [CCode (cname = "JSValueIsNumber", instance_pos = 1.1)] +- public bool is_number(Context ctx); +- +- [CCode (cname = "JSValueIsObject", instance_pos = 1.1)] +- public bool is_object(Context ctx); +- +- [CCode (cname = "JSValueIsString", instance_pos = 1.1)] +- public bool is_string(Context ctx); +- +- [CCode (cname = "JSValueToBoolean", instance_pos = 1.1)] +- public bool to_boolean(Context ctx); +- +- [CCode (cname = "JSValueToNumber", instance_pos = 1.1)] +- public double to_number(Context ctx, out Value exception); +- +- [CCode (cname = "JSValueToObject", instance_pos = 1.1)] +- public Object to_object(Context ctx, out Value exception); +- +- [CCode (cname = "JSValueToStringCopy", instance_pos = 1.1)] +- public String to_string_copy(Context ctx, out Value exception); +- +- } +- +- [CCode (cname = "JSStringRef")] +- [SimpleType] +- public struct String { +- +- [CCode (cname = "JSStringCreateWithUTF8CString")] +- public String.create_with_utf8_cstring(string str); +- +- [CCode (cname = "JSStringGetLength")] +- public int String.get_length(); +- +- [CCode (cname = "JSStringGetMaximumUTF8CStringSize")] +- public int String.get_maximum_utf8_cstring_size(); +- +- [CCode (cname = "JSStringGetUTF8CString")] +- public void String.get_utf8_cstring(string* buffer, int bufferSize); +- +- [CCode (cname = "JSStringRetain")] +- public void String.retain(); +- +- [CCode (cname = "JSStringRelease")] +- public void String.release(); +- +- } +- +-} +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index bce938d..6793129 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -525,7 +525,7 @@ set(ENGINE_PACKAGES + gio-2.0 + glib-2.0 + gmime-2.6 +- javascriptcore-4.0 ++ javascriptcoregtk-4.0 + libxml-2.0 + posix + sqlite3 +@@ -550,7 +550,7 @@ set(WEB_PROCESS_PACKAGES + geary-engine + gee-0.8 + gtk+-3.0 +- javascriptcore-4.0 ++ javascriptcoregtk-4.0 + libsoup-2.4 + webkit2gtk-web-extension-4.0 + ) +@@ -617,7 +617,6 @@ add_definitions(${CFLAGS}) + set(VALAC_OPTIONS + --vapidir=${CMAKE_BINARY_DIR}/src + --vapidir=${CMAKE_SOURCE_DIR}/bindings/vapi +- --metadatadir=${CMAKE_SOURCE_DIR}/bindings/metadata + --target-glib=${TARGET_GLIB} + --thread + --debug +@@ -649,38 +648,6 @@ set_property( + ) + target_link_libraries(geary-engine m ${DEPS_LIBRARIES} sqlite3-unicodesn) + +-# WebKit2GTK VAPI generation +-################################################# +-add_custom_target(webkit2gtk-vapi +- DEPENDS +- "${CMAKE_BINARY_DIR}/src/webkit2gtk-4.0.vapi" +- "${CMAKE_BINARY_DIR}/src/webkit2gtk-web-extension-4.0.vapi" +- "${CMAKE_SOURCE_DIR}/bindings/vapi/javascriptcore-4.0.vapi" +-) +-add_custom_command( +- OUTPUT +- ${CMAKE_BINARY_DIR}/src/webkit2gtk-4.0.vapi +- DEPENDS +- "${CMAKE_SOURCE_DIR}/bindings/metadata/WebKit2-4.0.metadata" +- "${CMAKE_SOURCE_DIR}/bindings/vapi/javascriptcore-4.0.vapi" +- WORKING_DIRECTORY +- "${CMAKE_SOURCE_DIR}/bindings/metadata" +- COMMAND +- vapigen --library=webkit2gtk-4.0 --pkg gtk+-3.0 --pkg libsoup-2.4 --pkg javascriptcore-4.0 --vapidir=${CMAKE_SOURCE_DIR}/bindings/vapi --metadatadir=${CMAKE_SOURCE_DIR}/bindings/metadata --directory=${CMAKE_BINARY_DIR}/src `${PKG_CONFIG_EXECUTABLE} --variable=girdir gobject-introspection-1.0`/WebKit2-4.0.gir +-) +-add_custom_command( +- OUTPUT +- "${CMAKE_BINARY_DIR}/src/webkit2gtk-web-extension-4.0.vapi" +- DEPENDS +- "${CMAKE_SOURCE_DIR}/bindings/metadata/WebKit2WebExtension-4.0.metadata" +- "${CMAKE_SOURCE_DIR}/bindings/metadata/WebKit2WebExtension-4.0-custom.vala" +- "${CMAKE_SOURCE_DIR}/bindings/vapi/javascriptcore-4.0.vapi" +- WORKING_DIRECTORY +- "${CMAKE_SOURCE_DIR}/bindings/metadata" +- COMMAND +- vapigen --library=webkit2gtk-web-extension-4.0 --pkg gtk+-3.0 --pkg libsoup-2.4 --pkg javascriptcore-4.0 --vapidir=${CMAKE_SOURCE_DIR}/bindings/vapi --metadatadir=${CMAKE_SOURCE_DIR}/bindings/metadata --directory=${CMAKE_BINARY_DIR}/src `${PKG_CONFIG_EXECUTABLE} --variable=girdir gobject-introspection-1.0`/WebKit2WebExtension-4.0.gir WebKit2WebExtension-4.0-custom.vala +-) +- + # Client library (static lib used for building client and unit tests) + ################################################# + +@@ -697,7 +664,7 @@ OPTIONS + ) + + add_library(geary-client STATIC ${CLIENT_VALA_C}) +-add_dependencies(geary-client resource_copy webkit2gtk-vapi) ++add_dependencies(geary-client resource_copy) + target_link_libraries(geary-client m ${DEPS_LIBRARIES} geary-engine) + + # Main client application binary +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index f2d3866..6524cfb 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -58,7 +58,7 @@ set(TEST_PACKAGES + glib-2.0 + gmime-2.6 + gtk+-3.0 +- javascriptcore-4.0 ++ javascriptcoregtk-4.0 + libsoup-2.4 + webkit2gtk-4.0 + ) diff -Nru geary-0.12.0/debian/patches/Clean-up-JS-util-API-courtesy-the-new-bindings.patch geary-0.12.4/debian/patches/Clean-up-JS-util-API-courtesy-the-new-bindings.patch --- geary-0.12.0/debian/patches/Clean-up-JS-util-API-courtesy-the-new-bindings.patch 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/debian/patches/Clean-up-JS-util-API-courtesy-the-new-bindings.patch 2018-12-24 17:07:05.000000000 +0000 @@ -0,0 +1,66 @@ +From: Michael James Gratton +Date: Sun, 20 May 2018 19:07:56 +1000 +Subject: Clean up JS util API courtesy the new bindings. + +--- + src/client/util/util-webkit.vala | 2 +- + src/engine/util/util-js.vala | 12 +++++------- + 2 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/src/client/util/util-webkit.vala b/src/client/util/util-webkit.vala +index cba9eaf..45a27c4 100644 +--- a/src/client/util/util-webkit.vala ++++ b/src/client/util/util-webkit.vala +@@ -64,7 +64,7 @@ namespace WebKitUtil { + JS.Value? err = null; + JS.String js_str = js_str_value.to_string_copy(context, out err); + Geary.JS.check_exception(context, err); +- return Geary.JS.to_string_released((owned) js_str); ++ return Geary.JS.to_native_string(js_str); + } + + /** +diff --git a/src/engine/util/util-js.vala b/src/engine/util/util-js.vala +index ea955e9..a98d798 100644 +--- a/src/engine/util/util-js.vala ++++ b/src/engine/util/util-js.vala +@@ -82,7 +82,7 @@ namespace Geary.JS { + global::JS.String js_str = value.to_string_copy(context, out err); + Geary.JS.check_exception(context, err); + +- return Geary.JS.to_string_released((owned) js_str); ++ return to_native_string(js_str); + } + + /** +@@ -111,7 +111,7 @@ namespace Geary.JS { + /** + * Returns a JSC {@link JS.String} as a Vala {@link string}. + */ +- public inline string to_string_released(owned global::JS.String js) { ++ public inline string to_native_string(global::JS.String js) { + size_t len = js.get_maximum_utf8_cstring_size(); + uint8[] str = new uint8[len]; + #if VALA_0_42 +@@ -138,10 +138,8 @@ namespace Geary.JS { + global::JS.String js_name = new global::JS.String.create_with_utf8_cstring(name); + global::JS.Value? err = null; + global::JS.Value prop = object.get_property(context, js_name, out err); +- try { +- Geary.JS.check_exception(context, err); +- } finally { +- } ++ Geary.JS.check_exception(context, err); ++ + return prop; + } + +@@ -169,7 +167,7 @@ namespace Geary.JS { + + throw new Error.EXCEPTION( + "JS exception thrown [%s]: %s" +- .printf(err_type.to_string(), to_string_released((owned) err_str)) ++ .printf(err_type.to_string(), to_native_string(err_str)) + ); + } + } diff -Nru geary-0.12.0/debian/patches/series geary-0.12.4/debian/patches/series --- geary-0.12.0/debian/patches/series 2018-01-22 17:08:15.000000000 +0000 +++ geary-0.12.4/debian/patches/series 2018-12-24 17:07:05.000000000 +0000 @@ -0,0 +1,4 @@ +bindings-Drop-custom-javascriptcore-4.0-and-webkit2gtk-4..patch +Adjust-to-upstream-javascriptcore-4.0-bindings.patch +Clean-up-JS-util-API-courtesy-the-new-bindings.patch +Actually-use-error-variable.patch diff -Nru geary-0.12.0/debian/rules geary-0.12.4/debian/rules --- geary-0.12.0/debian/rules 2018-01-22 17:20:10.000000000 +0000 +++ geary-0.12.4/debian/rules 2018-12-24 17:07:05.000000000 +0000 @@ -1,8 +1,7 @@ #!/usr/bin/make -f --include /usr/share/gnome-pkg-tools/1/rules/gnome-get-source.mk export DEB_BUILD_MAINT_OPTIONS = hardening=+all -export DEB_LDFLAGS_MAINT_APPEND = -Wl,-z,defs -Wl,--as-needed +export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 -Wl,-z,defs -Wl,--as-needed %: dh $@ --buildsystem=cmake --with gnome diff -Nru geary-0.12.0/desktop/geary-autostart.desktop.in geary-0.12.4/desktop/geary-autostart.desktop.in --- geary-0.12.0/desktop/geary-autostart.desktop.in 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/desktop/geary-autostart.desktop.in 2018-08-29 13:57:20.000000000 +0000 @@ -4,7 +4,7 @@ _X-GNOME-FullName=Geary Mail _Comment=Send and receive email _Keywords=Email;E-mail;Mail; -Icon=geary +Icon=org.gnome.Geary TryExec=geary Exec=geary --hidden Type=Application diff -Nru geary-0.12.0/desktop/org.gnome.Geary.appdata.xml.in geary-0.12.4/desktop/org.gnome.Geary.appdata.xml.in --- geary-0.12.0/desktop/org.gnome.Geary.appdata.xml.in 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/desktop/org.gnome.Geary.appdata.xml.in 2018-08-29 13:57:20.000000000 +0000 @@ -35,7 +35,7 @@ https://wiki.gnome.org/Apps/Geary - https://wiki.gnome.org/Apps/Geary/Contact + https://wiki.gnome.org/Apps/Geary/Documentation https://wiki.gnome.org/Apps/Geary/FAQ https://wiki.gnome.org/Apps/Geary/ReportingABug https://wiki.gnome.org/Apps/Geary/Translating @@ -77,9 +77,102 @@ geary + + +

Bug fixes included in this release:

+
    +
  • Fix handling folder names with IMAP reserved characters, such as backslashes. Issue #40
  • +
  • Fix dialog windows not focused after being first shown. Issue #43
  • +
  • Actually include the fix for "Move to folder" selection bug. Issue #24
  • +
  • Fix build under vala >= 0.41. Issue #86
  • +
  • Fixes for miscellaneous crashers
  • +
+
+
+ + + +

Bug fixes included in this release:

+
    +
  • Not syncing mail using Turkish locale. Bug 795906
  • +
  • Fix crash saving an attachment with unknown content type
  • +
  • Fix crash in secret_collection_get_locked. Bug 795328
  • +
  • "Move to folder" selection bug. Issue #24
  • +
  • Subfolders with special folders not displayed in + list. Issue #11
  • +
  • Add OARS metadata for Flathub
  • +
+
+
+ + + +

Bug fixes included in this release:

+
    +
  • Fix being unable to remove attachments from a draft. Bug + 792555.
  • +
  • Ensure drafts are removed when composer from address + changes accounts. Bug 778976.
  • +
  • Workaround composer info label being too long. Bug + 790435.
  • +
  • Ensure embedded composer is always scrolled to when + opened. Bug 778027.
  • +
  • Don't display quote expander buttons when printing a + message. Bug 795216.
  • +
  • Fix composer detach button position and visibility. Bug + 793710.
  • +
  • Actually fix second multipart/digest message body not + being displayed. Bug 788637.
  • +
  • Ensure gnome-control-centre knows in advance Geary uses + notifications
  • +
  • Fix gnome-shell notifications missing an icon under + flatpak. Bug 790103.
  • +
  • Fix message body quote button styling under WebKitGTK + 2.20.
  • +
  • Don't show unused header widgets when showing a message + via notifications
  • +
  • Work around present() not actually raising windows under + Wayland. Bug 776881.
  • +
  • Reduce CPU use when idle. Bug 783025.
  • +
  • Fix some serious run-time memory leaks
  • +
  • Update translation files (es, ru, sr, sr@latin)
  • +
+
+
+ + + +

Bug fixes included in this release:

+
    +
  • Parts of multipart/digest message do not expand when + clicked upon. Bug 788637.
  • +
  • Geary does not unlock keyring at start. Bug 784300.
  • +
  • Syntax error in IMAP greeting from AliYun IMAP + server. Bug 781488.
  • +
  • Message body text caret (cursor) not initially + visible. Bug 788797.
  • +
  • Losing focus when clicking in empty part of the + composer. Bug 779369.
  • +
  • Line breaks lost when selecting and replying to certain + messages. Bug 781178.
  • +
  • Always display an in-window app-menu under Unity. Bug + 770618.
  • +
  • Crash in SoupCacheInputStream when cancelling a message + load. Bug 778720.
  • +
  • Do not show Labels on sidebar if no label is + present. Bug 754802.
  • +
  • Unable to use Ctrl+C shortcut to copy e-mail subject; + must use context menu instead. Bug 788494.
  • +
  • After clicking on mailto link in Geary, the body in the + composer is not writable. Bug 771504.
  • +
  • Editing message does not support RTL. Bug 713607.
  • +
+
+
+ -

Enhances included in this release:

+

Enhancements included in this release:

  • Insert images inline when composing rich text messages
  • Improved interface for inserting links in rich text messages
  • @@ -97,86 +190,36 @@
  • Numerous bug fixes and minor user interface improvements
  • Numerous user interface translation updates
-

Thanks to all who contributed code fixes and enhancements - to this release, in particular the many first-time - contributors:

-
    -
  • Alex Henrie
  • -
  • Colin Vidal
  • -
  • Federico Bruni
  • -
  • Gautier Pelloux-Prayer
  • -
  • Heiko Becker
  • -
  • Jeremy Bicha
  • -
  • Jiri Cerny
  • -
  • Kacper Bielecki
  • -
  • Leonardo Robol
  • -
  • Michael Gratton
  • -
  • Michael James Gratton
  • -
  • Niels De Graef
  • -
  • Oskar Viljasaar
  • -
  • Piotr Drąg
  • -
  • Ralph Plawetzki
  • -
  • Rico Tzschichholz
  • -
  • Timo Kluck
  • -
  • Ville Korhonen
  • -
  • Yosef Or Boczko
  • -
-

Thanks also to the many that contributed translations, for the user interface:

-
    -
  • Alan Mortensen (da)
  • -
  • Alexandre Franke (fr)
  • -
  • Anders Jonsson (sv)
  • -
  • Andika Triwidada (id)
  • -
  • Ask Hjorth Larsen (da)
  • -
  • Aurimas Černius (lt)
  • -
  • Balázs Meskó (hu)
  • -
  • Balázs Úr (hu)
  • -
  • Baurzhan Muftakhidinov (kk)
  • -
  • Benedikt M. Thoma (de)
  • -
  • Daniel Korostil (uk)
  • -
  • Daniel Mustieles (es)
  • -
  • Daniel Șerbănescu (ro)
  • -
  • Dušan Kazik (sk)
  • -
  • Emin Tufan Çetin (tr)
  • -
  • E T (tr)
  • -
  • Federico Bruni (it)
  • -
  • Flo H (de)
  • -
  • Gábor Kelemen (hu)
  • -
  • Hannie Dumoleyn (nl)
  • -
  • hanniedu (nl)
  • -
  • Jeremy Bicha (bs)
  • -
  • Jiri Grönroos (fi)
  • -
  • Jordi Mas (ca)
  • -
  • Josef Andersson (sv)
  • -
  • Kjartan Maraas (nb)
  • -
  • Laudivan Freire de Almeida (pt_BR)
  • -
  • Marek Černocký (cs)
  • -
  • Mario Blättermann (de)
  • -
  • Matej Urbančič (sl)
  • -
  • Muhammet Kara (tr)
  • -
  • Piotr Drąg (hi) (hu) (ja) (km) (ms) (pl) (nl) (sl) (sr@latin)
  • -
  • Rafael Fontenelle (pt_BR)
  • -
  • Ronan Arraes Jardim Chagas (pt_BR)
  • -
  • Stas Solovey (ru)
  • -
  • Tiago Santos (pt)
  • -
  • Wolfgang Stöggl (de)
  • -
  • Yosef Or Boczko (he)
  • -
  • Мирослав Николић (sr) (sr@latin)
  • -
-

And for the user manual:

-
    -
  • Anders Jonsson (sv)
  • -
  • Andre Klapper (el)
  • -
  • Christian Kirbach (de)
  • -
  • Daniel Mustieles (es)
  • -
  • Federico Bruni (it)
  • -
  • Josef Andersson (sv)
  • -
  • Marek Černocký (cs)
  • -
  • Mario Blättermann (de)
  • -
  • Piotr Drąg (pl)
  • -
  • Rafael Fontenelle (pt_BR)
  • -
+ + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + intense + none + none + none + intense + none + none + diff -Nru geary-0.12.0/desktop/org.gnome.Geary.desktop.in geary-0.12.4/desktop/org.gnome.Geary.desktop.in --- geary-0.12.0/desktop/org.gnome.Geary.desktop.in 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/desktop/org.gnome.Geary.desktop.in 2018-08-29 13:57:20.000000000 +0000 @@ -5,7 +5,7 @@ _Comment=Send and receive email # Translators: These are desktop search terms. Do not translate semicolons, end line with a semicolon. _Keywords=Mail;E-mail;IMAP;GMail;Yahoo;Hotmail;Outlook; -Icon=geary +Icon=org.gnome.Geary TryExec=geary Exec=geary %U Type=Application @@ -13,6 +13,7 @@ Categories=GNOME;GTK;Network;Email; MimeType=x-scheme-handler/mailto; StartupNotify=true +X-GNOME-UsesNotifications=true Actions=Compose; [Desktop Action Compose] diff -Nru geary-0.12.0/.gitlab-ci.yml geary-0.12.4/.gitlab-ci.yml --- geary-0.12.0/.gitlab-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/.gitlab-ci.yml 2018-08-29 13:57:20.000000000 +0000 @@ -0,0 +1,110 @@ +# +# Geary CI config. +# + +stages: + - build + +variables: + BUILD_DIR: build + CONFIG_CMD: ./configure + BUILD_CMD: make + TEST_CMD: xvfb-run make test + INSTALL_CMD: make install + FEDORA_BUILD_DEPS: gcc make + FEDORA_DEPS: vala gobject-introspection-devel intltool cmake + desktop-file-utils gnome-doc-utils libcanberra-devel + libgee-devel glib2-devel gmime-devel gtk3-devel + libnotify-devel sqlite-devel webkitgtk4-devel + libsecret-devel libxml2-devel vala-tools gcr-devel + enchant-devel + FEDORA_TEST_DEPS: Xvfb + DEBIAN_DEPS: valac libgirepository1.0-dev intltool cmake + desktop-file-utils gnome-doc-utils libcanberra-dev + libgee-0.8-dev libglib2.0-dev libgmime-2.6-dev + libgtk-3-dev libsecret-1-dev libxml2-dev libnotify-dev + libsqlite3-dev libwebkit2gtk-4.0-dev libgcr-3-dev + libenchant-dev + DEBIAN_TEST_DEPS: xauth xvfb + UBUNTU_DEPS: $DEBIAN_DEPS libunity-dev libmessaging-menu-dev + UBUNTU_TEST_DEPS: xauth xvfb + +# +# Stages +# + +fedora: + stage: build + image: fedora:latest + before_script: + - dnf update -y --nogpgcheck + - dnf install -y --nogpgcheck $FEDORA_BUILD_DEPS $FEDORA_DEPS $FEDORA_TEST_DEPS + script: + - $CONFIG_CMD + - $BUILD_CMD + - $TEST_CMD + - $INSTALL_CMD + +debian: + stage: build + image: debian:stable + before_script: + - apt-get update + - apt-get install -q -y --no-install-recommends $DEBIAN_DEPS $DEBIAN_TEST_DEPS + script: + - $CONFIG_CMD + - $BUILD_CMD + - $TEST_CMD + - $INSTALL_CMD + +ubuntu: + stage: build + image: ubuntu:xenial + before_script: + - apt-get update + - apt-get install -q -y --no-install-recommends $UBUNTU_DEPS $UBUNTU_TEST_DEPS + script: + - $CONFIG_CMD + - $BUILD_CMD + - $TEST_CMD + - $INSTALL_CMD + +deb-package: + stage: build + image: ubuntu:xenial + before_script: + - apt-get update + - apt-get install -q -y --no-install-recommends packaging-dev $UBUNTU_DEPS + script: + - dpkg-buildpackage -b -us -uc + +flatpak-package: + image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.28 + stage: build + + variables: + GIT_SUBMODULE_STRATEGY: normal + FLATPAK_ARTIFACT: geary-git.flatpak + + script: + - flatpak-builder flatpak-build org.gnome.Geary.json + - flatpak build-export flatpak-repo flatpak-build --update-appstream + - flatpak build-bundle flatpak-repo $FLATPAK_ARTIFACT + --runtime-repo=https://sdk.gnome.org/gnome-nightly.flatpakrepo + org.gnome.Geary + + artifacts: + paths: + - $FLATPAK_ARTIFACT + expire_in: 2 days + + cache: + # JOB_NAME - Each job will have it's own cache + # COMMIT_REF_SLUG = Lowercase name of the branch + # ^ Keep diffrerent caches for each branch + key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" + paths: + # Cache .flatpak-builder + - .flatpak-builder/cache/ + - .flatpak-builder/downloads/ + - .flatpak-builder/git/ diff -Nru geary-0.12.0/help/de/de.po geary-0.12.4/help/de/de.po --- geary-0.12.0/help/de/de.po 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/help/de/de.po 2018-08-29 13:57:20.000000000 +0000 @@ -10,22 +10,26 @@ msgid "" msgstr "" "Project-Id-Version: Geary master\n" -"POT-Creation-Date: 2017-03-26 00:20+0000\n" -"PO-Revision-Date: 2017-03-29 21:16+0200\n" +"POT-Creation-Date: 2017-10-20 05:56+0000\n" +"PO-Revision-Date: 2017-10-24 22:16+0200\n" "Last-Translator: Mario Blättermann \n" "Language-Team: Deutsch \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.0.3\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: C/write.page:9(title) msgid "Write a message" msgstr "Eine Nachricht schreiben" -#: C/write.page:12(p) +#: C/write.page:12(title) +msgid "Composing and replying" +msgstr "Verfassen und antworten" + +#: C/write.page:13(p) msgid "" "To compose a new message in Geary, press the New Message button " "on the toolbar." @@ -33,7 +37,7 @@ "Um eine neue Nachricht in Geary zu erstellen, klicken Sie auf den Knopf " "Neue Nachricht in der Werkzeugleiste." -#: C/write.page:15(p) +#: C/write.page:16(p) msgid "" "To reply to a message, open the message menu in the upper right corner of " "the message and choose Reply, Reply All or " @@ -48,11 +52,11 @@ "Antworten, Allen Antworten und Weiterleiten " "in der Werkzeugleiste antworten." -#: C/write.page:20(title) +#: C/write.page:21(title) msgid "Features" msgstr "Besonderheiten" -#: C/write.page:22(p) +#: C/write.page:23(p) msgid "" "Geary's email composer lets you adjust the font, size and color of text. You " "can also insert hyperlinks into messages." @@ -61,7 +65,7 @@ "Schriftgröße und die Textfarbe anzupassen. Außerdem ist es möglich, Verweise " "in Nachrichten einzufügen." -#: C/write.page:24(p) +#: C/write.page:25(p) msgid "" "Geary can also send plain text messages. In the drop-down menu, check or " "uncheck \"Rich Text\" to toggle between plain text and rich text mode." @@ -70,13 +74,13 @@ "deaktivieren Sie »Rich Text« im Auswahl-Menü, um zwischen einfachem Text- " "und Rich-Text-Modus zu wechseln." -#: C/write.page:27(p) +#: C/write.page:28(p) msgid "" "You can attach a file to a message you're writing in either of these ways:" msgstr "" "Sie können eine Datei an eine gerade verfasste Nachricht wie folgt anhängen:" -#: C/write.page:29(p) +#: C/write.page:30(p) msgid "" "Press the Attach File button at the lower left of the composer " "window, then select a file to attach." @@ -84,7 +88,7 @@ "Klicken Sie auf den Knopf Datei anhängen in der unteren linken " "Ecke des Editor-Fensters und wählen Sie anschließend die anzuhängende Datei." -#: C/write.page:31(p) +#: C/write.page:32(p) msgid "" "Drag the file from the Nautilus file manager to the composer window, and " "drop it either on the text fields at the top of the window or on the toolbar " @@ -94,7 +98,7 @@ "und legen Sie diese entweder im Textfeld oben im Fenster oder in der " "Werkzeugleiste im unteren Teil des Fensters ab." -#: C/write.page:35(p) +#: C/write.page:36(p) msgid "" "A number of keyboard shortcuts are available in the composer; see for details." @@ -102,7 +106,7 @@ "Im Editor stehen eine große Zahl von Tastaturkürzeln zur Verfügung; Details " "unter ." -#: C/write.page:37(p) +#: C/write.page:38(p) msgid "" "You may specify a signature to be inserted into the composer in the dialog." @@ -110,11 +114,11 @@ "Sie können im -Dialog eine Signatur angeben, welche " "dann im E-Mail-Editor eingefügt wird." -#: C/write.page:42(title) +#: C/write.page:43(title) msgid "Drafts" msgstr "Entwürfe" -#: C/write.page:44(p) +#: C/write.page:45(p) msgid "" "For mail servers that support drafts, Geary will automatically save the " "message as you type. If you close the composer without sending, Geary will " @@ -125,7 +129,7 @@ "ohne die Nachricht zu senden, fragt Geary, ob die Nachricht als Entwurf " "gespeichert oder verworfen werden soll." -#: C/write.page:47(p) +#: C/write.page:48(p) msgid "" "To edit an existing draft, select the Drafts folder in the folder list, " "select the message, and click \"Edit Draft\" in the message viewer." @@ -134,7 +138,7 @@ "Entwürfe-Ordner aus der Ordnerliste, wählen die Nachricht und wählen in der " "Nachrichten Ansicht Entwurf bearbeiten." -#: C/write.page:50(p) +#: C/write.page:51(p) msgid "Geary deletes the draft when you send the message." msgstr "Geary löscht den Entwurf, wenn die Nachricht gesendet wird." @@ -558,9 +562,6 @@ msgstr "Zur nächsten/vorigen Nachricht in einer Konversation wechseln" #: C/shortcuts.page:191(p) -#| msgid "" -#| "CtrlU or ShiftU" msgid "" "CtrlDown / CtrlUp" @@ -573,9 +574,6 @@ msgstr "Zur ersten/letzten Nachricht in einer Konversation wechseln" #: C/shortcuts.page:198(p) -#| msgid "" -#| "CtrlI or ShiftI" msgid "" "CtrlHome / CtrlEnd" @@ -1367,4 +1365,3 @@ "Frank Schiersner , 2014\n" "Simon Linden , 2017" - diff -Nru geary-0.12.0/icons/CMakeLists.txt geary-0.12.4/icons/CMakeLists.txt --- geary-0.12.0/icons/CMakeLists.txt 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/icons/CMakeLists.txt 2018-08-29 13:57:20.000000000 +0000 @@ -27,13 +27,13 @@ install(FILES ${ICON_FILES} DESTINATION ${ICONS_DEST}) # Application icon goes in theme directory -install(FILES "hicolor/16x16/apps/geary.png" DESTINATION share/icons/hicolor/16x16/apps) -install(FILES "hicolor/24x24/apps/geary.png" DESTINATION share/icons/hicolor/24x24/apps) -install(FILES "hicolor/32x32/apps/geary.png" DESTINATION share/icons/hicolor/32x32/apps) -install(FILES "hicolor/48x48/apps/geary.png" DESTINATION share/icons/hicolor/48x48/apps) -install(FILES "hicolor/256x256/apps/geary.png" DESTINATION share/icons/hicolor/256x256/apps) -install(FILES "hicolor/512x512/apps/geary.png" DESTINATION share/icons/hicolor/512x512/apps) -install(FILES "hicolor/symbolic/apps/geary-symbolic.svg" DESTINATION share/icons/hicolor/symbolic/apps) +install(FILES "hicolor/16x16/apps/org.gnome.Geary.png" DESTINATION share/icons/hicolor/16x16/apps) +install(FILES "hicolor/24x24/apps/org.gnome.Geary.png" DESTINATION share/icons/hicolor/24x24/apps) +install(FILES "hicolor/32x32/apps/org.gnome.Geary.png" DESTINATION share/icons/hicolor/32x32/apps) +install(FILES "hicolor/48x48/apps/org.gnome.Geary.png" DESTINATION share/icons/hicolor/48x48/apps) +install(FILES "hicolor/256x256/apps/org.gnome.Geary.png" DESTINATION share/icons/hicolor/256x256/apps) +install(FILES "hicolor/512x512/apps/org.gnome.Geary.png" DESTINATION share/icons/hicolor/512x512/apps) +install(FILES "hicolor/symbolic/apps/org.gnome.Geary-symbolic.svg" DESTINATION share/icons/hicolor/symbolic/apps) # Optional: update icon cache at install time. if (ICON_UPDATE) Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/16x16/apps/geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/16x16/apps/geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/16x16/apps/org.gnome.Geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/16x16/apps/org.gnome.Geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/24x24/apps/geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/24x24/apps/geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/24x24/apps/org.gnome.Geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/24x24/apps/org.gnome.Geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/256x256/apps/geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/256x256/apps/geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/256x256/apps/org.gnome.Geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/256x256/apps/org.gnome.Geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/32x32/apps/geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/32x32/apps/geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/32x32/apps/org.gnome.Geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/32x32/apps/org.gnome.Geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/48x48/apps/geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/48x48/apps/geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/48x48/apps/org.gnome.Geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/48x48/apps/org.gnome.Geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/512x512/apps/geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/512x512/apps/geary.png differ Binary files /tmp/tmpQNjySH/FQrDSyIa8K/geary-0.12.0/icons/hicolor/512x512/apps/org.gnome.Geary.png and /tmp/tmpQNjySH/wu7Z3OgpPX/geary-0.12.4/icons/hicolor/512x512/apps/org.gnome.Geary.png differ diff -Nru geary-0.12.0/icons/hicolor/symbolic/apps/geary-symbolic.svg geary-0.12.4/icons/hicolor/symbolic/apps/geary-symbolic.svg --- geary-0.12.0/icons/hicolor/symbolic/apps/geary-symbolic.svg 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/icons/hicolor/symbolic/apps/geary-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff -Nru geary-0.12.0/icons/hicolor/symbolic/apps/org.gnome.Geary-symbolic.svg geary-0.12.4/icons/hicolor/symbolic/apps/org.gnome.Geary-symbolic.svg --- geary-0.12.0/icons/hicolor/symbolic/apps/org.gnome.Geary-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/icons/hicolor/symbolic/apps/org.gnome.Geary-symbolic.svg 2018-08-29 13:57:20.000000000 +0000 @@ -0,0 +1,125 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff -Nru geary-0.12.0/NEWS geary-0.12.4/NEWS --- geary-0.12.0/NEWS 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/NEWS 2018-08-29 13:57:20.000000000 +0000 @@ -1,3 +1,105 @@ +Version 0.12.4 +~~~~~~~~~~~~~~ +Released: 2018-08-29 + +Bug fixes included in this release: + * Fix handling folder names with IMAP reserved characters, such as + backslashes. Issue #40 + * Fix dialog windows not focused after being first shown. Issue #43 + * Actually include the fix for "Move to folder" selection bug. Issue #24 + * Fix build under vala >= 0.41. Issue #86 + * Fixes for miscellaneous crashers + +Version 0.12.3 +~~~~~~~~~~~~~~ +Released: 2018-07-14 + +Bug fixes included in this release: + * Not syncing mail using Turkish locale. Bug 795906 + * Fix crash saving an attachment with unknown content type + * Fix crash in secret_collection_get_locked. Bug 795328 + * "Move to folder" selection bug. Issue #24 + * Subfolders with special folders not displayed in list. Issue #11 + * Add OARS metadata for Flathub + +Thanks to all who contributed code fixes and enhancements to this +release: + * Nick Richards + +Version 0.12.2 +~~~~~~~~~~~~~~ +Released: 2018-04-24 + +Bug fixes included in this release: + * Fix being unable to remove attachments from a draft. Bug 792555. + * Ensure drafts are removed when composer from address changes accounts. Bug + 778976. + * Workaround composer info label being too long. Bug 790435. + * Ensure embedded composer is always scrolled to when opened. Bug 778027. + * Don't display quote expander buttons when printing a message. Bug 795216. + * Fix composer detach button position and visibility. Bug 793710. + * Actually fix second multipart/digest message body not being displayed. Bug + 788637. + * Ensure gnome-control-centre knows in advance Geary uses notifications. + * Fix gnome-shell notifications missing an icon under flatpak. Bug 790103. + * Fix message body quote button styling under WebKitGTK 2.20. + * Don't show unused header widgets when showing a message via notifications. + * Work around present() not actually raising windows under Wayland. Bug + 776881. + * Reduce CPU use when idle. Bug 783025. + * Fix some serious run-time memory leaks. + +Thanks also to all who contributed translations, for the user +interface: + * Daniel Mustieles (es) + * Stas Solovey (ru) + * Мирослав Николић (sr) (sr@latin) + +Version 0.12.1 +~~~~~~~~~~~~~~ +Released: 2018-02-13 + +Bug fixes included in this release: + * Parts of multipart/digest message do not expand when clicked upon. Bug + 788637. + * Geary does not unlock keyring at start. Bug 784300. + * Syntax error in IMAP greeting from AliYun IMAP server. Bug 781488. + * Message body text caret (cursor) not initially visible. Bug 788797. + * Losing focus when clicking in empty part of the composer. Bug 779369. + * Line breaks lost when selecting and replying to certain messages. Bug + 781178. + * Always display an in-window app-menu under Unity. Bug 770618. + * Crash in SoupCacheInputStream when cancelling a message load. Bug 778720. + * Do not show Labels on sidebar if no label is present. Bug 754802. + * Unable to use Ctrl+C shortcut to copy e-mail subject; must use context menu + instead. Bug 788494. + * After clicking on mailto link in Geary, the body in the composer is not + writable. Bug 771504. + * Editing message does not support RTL. Bug 713607. + +Thanks to all who contributed code fixes and enhancements to this +release: + * Alex Henrie + * Gautier Pelloux-Prayer + * Kacper Bielecki + +Thanks also to all who contributed translations, for the user +interface: + * Anders Jonsson (sv) + * Ask Hjorth Larsen (da) + * Balázs Meskó (hu) + * Dušan Kazik (sk) + * Federico Bruni (it) + * Kukuh Syafaat (id) + * Marek Cernocky (cs) + * Mario Blättermann (de) + * Piotr Drąg (pl) + * Rafael Fontenelle (pt_BR) + * Stas Solovey (ru) + +And for the user manual: + * Mario Blättermann (de) + Version 0.12 ~~~~~~~~~~~~ Released: 2017-10-02 diff -Nru geary-0.12.0/org.gnome.Geary.json geary-0.12.4/org.gnome.Geary.json --- geary-0.12.0/org.gnome.Geary.json 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/org.gnome.Geary.json 2018-08-29 13:57:20.000000000 +0000 @@ -1,14 +1,11 @@ /* flatpak-builder config for Geary. */ { "app-id": "org.gnome.Geary", + "branch": "geary-0.12", "runtime": "org.gnome.Platform", - "runtime-version": "master", + "runtime-version": "3.28", "sdk": "org.gnome.Sdk", "command": "geary", - "tags": ["nightly"], - "desktop-file-name-prefix": "(Nightly) ", - "rename-icon": "geary", - "copy-icon": true, "finish-args": [ /* X11 + XShm access */ "--share=ipc", "--socket=x11", @@ -19,9 +16,6 @@ /* OpenGL access for WK2 */ "--device=dri", - /* Bus access */ - "--socket=session-bus", - /* Pulseaudio */ "--socket=pulseaudio", @@ -85,7 +79,7 @@ "sources": [ { "type": "git", - "url": "https://git.gnome.org/browse/libgee", + "url": "https://gitlab.gnome.org/GNOME/libgee.git", "tag": "0.20.0" } ] @@ -95,7 +89,7 @@ "sources": [ { "type": "git", - "url": "https://git.gnome.org/browse/gmime", + "url": "https://github.com/jstedfast/gmime.git", "branch": "gmime-2-6" } ] @@ -105,7 +99,8 @@ "sources": [ { "type": "git", - "url": "https://git.gnome.org/browse/geary" + "url": "https://gitlab.gnome.org/GNOME/geary.git", + "branch": "geary-0.12" } ] } diff -Nru geary-0.12.0/po/cs.po geary-0.12.4/po/cs.po --- geary-0.12.0/po/cs.po 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/po/cs.po 2018-08-29 13:57:20.000000000 +0000 @@ -9,11 +9,11 @@ # msgid "" msgstr "" -"Project-Id-Version: geary\n" +"Project-Id-Version: geary geary-0.12\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" "product=geary&keywords=I18N+L10N&component=internationalization\n" -"POT-Creation-Date: 2017-09-26 12:56+0000\n" -"PO-Revision-Date: 2017-09-26 20:05+0200\n" +"POT-Creation-Date: 2017-10-02 14:41+0000\n" +"PO-Revision-Date: 2017-10-02 17:20+0200\n" "Last-Translator: Marek Černocký \n" "Language-Team: čeština \n" "Language: cs\n" @@ -39,6 +39,7 @@ #: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Odesílejte a přijímejte e-maily" @@ -99,6 +100,7 @@ msgstr "Geary se zobrazeným editorem formátovaného textu" #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "E-mail" @@ -115,11 +117,6 @@ msgid "Compose Message" msgstr "Napsat zprávu" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Poštovní klient" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Pošta Geary" @@ -267,11 +264,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Copyright 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "© 2016 – 2017 Vývojářský tým aplikace Geary" + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Navštívit webové stránky Geary" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "O aplikaci %s" @@ -279,7 +280,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Petr Šimáček \n" @@ -352,17 +353,17 @@ msgid "Use %s to open a new composer window" msgstr "Použít %s k otevření nového okna pro psaní zprávy" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Připomínky, návrhy a chyby hlaste prosím na:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Nepodařilo se zpracovat přepínače příkazového řádku: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Nerozpoznaný přepínač příkazového řádku „%s“\n" diff -Nru geary-0.12.0/po/da.po geary-0.12.4/po/da.po --- geary-0.12.0/po/da.po 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/po/da.po 2018-08-29 13:57:20.000000000 +0000 @@ -13,8 +13,8 @@ "Project-Id-Version: geary-0.4.1\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" "product=geary&keywords=I18N+L10N&component=internationalization\n" -"POT-Creation-Date: 2017-09-26 12:56+0000\n" -"PO-Revision-Date: 2017-09-27 17:21+0200\n" +"POT-Creation-Date: 2017-10-24 20:18+0000\n" +"PO-Revision-Date: 2017-10-25 18:16+0200\n" "Last-Translator: Alan Mortensen \n" "Language-Team: Danish (http://www.transifex.com/projects/p/geary/language/" "da/)\n" @@ -41,6 +41,7 @@ #: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Send og modtag e-mail" @@ -101,6 +102,7 @@ msgstr "Geary som redigering af formateret tekst ser ud" #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "E-mail" @@ -118,11 +120,6 @@ msgid "Compose Message" msgstr "Skriv besked" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "E-mailklient" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Geary mail" @@ -270,11 +267,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Ophavsret 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Ophavsret 2016-2017 Gearys udviklerhold." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Besøg Gearys hjemmeside" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "Om %s" @@ -282,7 +283,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Nikolaj Holmquist Pedersen \n" @@ -359,20 +360,20 @@ msgid "Use %s to open a new composer window" msgstr "Brug %s for at åbne et nyt redigeringsvindue" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Send kommentarer, idéer og fejlrapporter til:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Kunne ikke genkende indstillingerne på kommandolinjen: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" -msgstr "Ukendt kommandolinje-indstilling \"%s\"\n" +msgstr "Ukendt kommandolinje-indstilling “%s”\n" #: ../src/client/application/geary-controller.vala:57 msgid "Delete conversation" @@ -506,11 +507,11 @@ #: ../src/client/application/geary-controller.vala:538 msgid "Empty _Spam…" -msgstr "Tøm _spam…" +msgstr "Tøm _spam …" #: ../src/client/application/geary-controller.vala:542 msgid "Empty _Trash…" -msgstr "Tøm _papirkurv…" +msgstr "Tøm _papirkurv …" #. No callback is connected, since we bind the toggle button to the search bar visibility #: ../src/client/application/geary-controller.vala:574 @@ -568,7 +569,7 @@ "please manually delete the email from your Outbox folder." msgstr "" "Geary stødte ind i en fejl under afsendelse af en e-mail. Hvis dette problem " -"fortsætter, bør du manuelt slette beskeden fra din \"Udbakke\"-mappe." +"fortsætter, bør du manuelt slette beskeden fra din “Udbakke”-mappe." #. Displayed in the space-limited status bar when a message fails to be uploaded #. to Sent Mail after being sent. @@ -632,7 +633,7 @@ #: ../src/client/application/geary-controller.vala:1178 #, c-format msgid "Unable to rebuild database for “%s”" -msgstr "Kunne ikke genopbygge databasen for \"%s\"" +msgstr "Kunne ikke genopbygge databasen for “%s”" #: ../src/client/application/geary-controller.vala:1179 #, c-format @@ -681,8 +682,8 @@ "Please install the latest version of Geary and try again." msgstr "" "Den lokale e-maildatabases versionsnummer er til en nyere version af Geary. " -"Desværre kan databasen ikke blive \"rullet tilbage\", så den virker med " -"denne version of Geary.\n" +"Desværre kan databasen ikke blive “rullet tilbage”, så den virker med denne " +"version of Geary.\n" "\n" "Installér venligst den nyeste version af Geary og prøv igen." @@ -698,15 +699,15 @@ "\n" "Tjek, at din internetforbindelse virker og genstart derefter Geary." -#: ../src/client/application/geary-controller.vala:1999 +#: ../src/client/application/geary-controller.vala:2008 msgid "Undo move (Ctrl+Z)" msgstr "Fortryd flyt (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2009 +#: ../src/client/application/geary-controller.vala:2018 msgid "Are you sure you want to open these attachments?" msgstr "Er du sikker på, at du vil åbne disse vedhæftede filer?" -#: ../src/client/application/geary-controller.vala:2010 +#: ../src/client/application/geary-controller.vala:2019 msgid "" "Attachments may cause damage to your system if opened. Only open files from " "trusted sources." @@ -714,79 +715,79 @@ "Vedhæftede filer kan skade dit system, når de åbnes. Åbn kun filer fra " "folk, du stoler på." -#: ../src/client/application/geary-controller.vala:2011 +#: ../src/client/application/geary-controller.vala:2020 msgid "Don’t _ask me again" msgstr "S_pørg mig ikke igen" -#: ../src/client/application/geary-controller.vala:2121 +#: ../src/client/application/geary-controller.vala:2130 #, c-format msgid "A file named “%s” already exists. Do you want to replace it?" -msgstr "Filen \"%s\" findes allerede. Vil du erstatte den?" +msgstr "Filen “%s” findes allerede. Vil du erstatte den?" -#: ../src/client/application/geary-controller.vala:2123 +#: ../src/client/application/geary-controller.vala:2132 #, c-format msgid "" "The file already exists in “%s”. Replacing it will overwrite its contents." msgstr "" -"Filen findes allerede i \"%s\". Hvis du erstatter den, overskrives dens " +"Filen findes allerede i “%s”. Hvis du erstatter den, overskrives dens " "indhold." -#: ../src/client/application/geary-controller.vala:2126 +#: ../src/client/application/geary-controller.vala:2135 msgid "_Replace" msgstr "_Erstat" #. Find out what to do with the inline composers. #. TODO: Remove this in favor of automatically saving drafts -#: ../src/client/application/geary-controller.vala:2374 +#: ../src/client/application/geary-controller.vala:2383 msgid "Close open draft messages?" msgstr "Luk åbne kladder?" -#: ../src/client/application/geary-controller.vala:2496 +#: ../src/client/application/geary-controller.vala:2505 #, c-format msgid "Empty all email from your %s folder?" msgstr "Tøm al e-mail fra din %s-mappe?" -#: ../src/client/application/geary-controller.vala:2497 +#: ../src/client/application/geary-controller.vala:2506 msgid "This removes the email from Geary and your email server." msgstr "Dette fjerner e-mail fra Geary samt din e-mailserver." -#: ../src/client/application/geary-controller.vala:2498 +#: ../src/client/application/geary-controller.vala:2507 msgid "This cannot be undone." msgstr "Dette kan ikke fortrydes." -#: ../src/client/application/geary-controller.vala:2499 +#: ../src/client/application/geary-controller.vala:2508 #, c-format msgid "Empty %s" msgstr "Tøm %s" -#: ../src/client/application/geary-controller.vala:2516 +#: ../src/client/application/geary-controller.vala:2525 #, c-format msgid "Error emptying %s" msgstr "Fejl ved tømning af %s" -#: ../src/client/application/geary-controller.vala:2546 +#: ../src/client/application/geary-controller.vala:2555 msgid "Do you want to permanently delete this message?" msgid_plural "Do you want to permanently delete these messages?" msgstr[0] "Ønsker du at slette denne besked permanent?" msgstr[1] "Ønsker du at slette disse beskeder permanent?" -#: ../src/client/application/geary-controller.vala:2548 +#: ../src/client/application/geary-controller.vala:2557 msgid "Delete" msgstr "Slet" -#: ../src/client/application/geary-controller.vala:2580 +#: ../src/client/application/geary-controller.vala:2589 msgid "Undo archive (Ctrl+Z)" msgstr "Fortryd arkivér (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2595 +#: ../src/client/application/geary-controller.vala:2604 msgid "Undo trash (Ctrl+Z)" msgstr "Fortryd smid i papirkurv (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2649 +#: ../src/client/application/geary-controller.vala:2658 msgid "Undo (Ctrl+Z)" msgstr "Fortryd (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2780 +#: ../src/client/application/geary-controller.vala:2789 msgid "Failed to open default text editor." msgstr "Kunne ikke åbne standardprogrammet til tekstredigéring." @@ -940,7 +941,7 @@ #: ../src/client/composer/composer-widget.vala:1515 #, c-format msgid "“%s” already attached for delivery." -msgstr "\"%s\" er allerede vedhæftet." +msgstr "“%s” er allerede vedhæftet." #. / In the composer, the filename followed by its filesize, i.e. "notes.txt (1.12KB)" #. Translators: The first argument will be a @@ -956,22 +957,22 @@ #: ../src/client/composer/composer-widget.vala:1560 #, c-format msgid "“%s” could not be found." -msgstr "\"%s\" blev ikke fundet." +msgstr "“%s” blev ikke fundet." #: ../src/client/composer/composer-widget.vala:1566 #, c-format msgid "“%s” is a folder." -msgstr "\"%s\" er en mappe." +msgstr "“%s” er en mappe." #: ../src/client/composer/composer-widget.vala:1572 #, c-format msgid "“%s” is an empty file." -msgstr "\"%s\" er en tom fil." +msgstr "“%s” er en tom fil." #: ../src/client/composer/composer-widget.vala:1585 #, c-format msgid "“%s” could not be opened for reading." -msgstr "\"%s\" kunne ikke åbnes til læsning." +msgstr "“%s” kunne ikke åbnes til læsning." #: ../src/client/composer/composer-widget.vala:1593 msgid "Cannot add attachment" @@ -1113,15 +1114,15 @@ "Selecting “Trust This Server” or “Always Trust This Server” may cause your " "username and password to be transmitted insecurely." msgstr "" -"Hvis du vælger \"Stol på serveren\" eller \"Stol altid på serveren\", kan " -"dit brugernavn og din adgangskode blive sendt uden sikkerhed." +"Hvis du vælger “Stol på serveren” eller “Stol altid på serveren”, kan dit " +"brugernavn og din adgangskode blive sendt uden sikkerhed." #: ../src/client/dialogs/certificate-warning-dialog.vala:52 msgid "" "Selecting “Don’t Trust This Server” will cause Geary not to access this " "server." msgstr "" -"Hvis du vælger \"Stol ikke på serveren\", vil Geary ikke forbinde til denne " +"Hvis du vælger “Stol ikke på serveren”, vil Geary ikke forbinde til denne " "server." #: ../src/client/dialogs/certificate-warning-dialog.vala:54 @@ -1133,7 +1134,7 @@ "Selecting “Don’t Trust This Server” will cause Geary to stop accessing this " "account." msgstr "" -"Hvis du vælger \"Stol ikke på serveren\", vil Geary holde op med at tilgå " +"Hvis du vælger “Stol ikke på serveren”, vil Geary holde op med at tilgå " "denne konto." #: ../src/client/dialogs/certificate-warning-dialog.vala:61 @@ -2475,7 +2476,7 @@ #: ../ui/login.glade.h:11 msgid "Addi_tional email addresses…" -msgstr "_Yderligere e-mailadresser…" +msgstr "_Yderligere e-mailadresser …" #: ../ui/login.glade.h:12 msgid "IMAP settings" @@ -2668,7 +2669,10 @@ #: ../ui/upgrade_dialog.glade.h:1 msgid "Geary update in progress…" -msgstr "Geary er ved at blive opgraderet…" +msgstr "Geary er ved at blive opgraderet …" + +#~ msgid "Mail Client" +#~ msgstr "E-mailklient" #~ msgid "_Inspect" #~ msgstr "_Undersøg" @@ -2699,7 +2703,7 @@ #~ msgstr "Tøm" #~ msgid "_Inspect..." -#~ msgstr "_Undersøg..." +#~ msgstr "_Undersøg …" #~ msgid "Copyright 2011-2014 Yorba Foundation" #~ msgstr "Copyright 2011-2014 Yorba Foundation" @@ -2742,12 +2746,12 @@ #~ msgstr "Vælg _besked" #~ msgid "_Save As..." -#~ msgstr "Gem _som..." +#~ msgstr "Gem _som …" #~ msgid "Save A_ttachment..." #~ msgid_plural "Save All A_ttachments..." -#~ msgstr[0] "Gem v_edhæftet fil..." -#~ msgstr[1] "Gem alle v_edhæftede filer..." +#~ msgstr[0] "Gem v_edhæftet fil …" +#~ msgstr[1] "Gem alle v_edhæftede filer …" #~ msgid "_Left" #~ msgstr "_Venstre" diff -Nru geary-0.12.0/po/de.po geary-0.12.4/po/de.po --- geary-0.12.0/po/de.po 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/po/de.po 2018-08-29 13:57:20.000000000 +0000 @@ -20,8 +20,8 @@ "Project-Id-Version: geary-0.4.1\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" "product=geary&keywords=I18N+L10N&component=internationalization\n" -"POT-Creation-Date: 2017-09-29 08:56+0000\n" -"PO-Revision-Date: 2017-10-02 10:35+0200\n" +"POT-Creation-Date: 2017-10-05 05:43+0000\n" +"PO-Revision-Date: 2017-10-05 20:38+0200\n" "Last-Translator: Mario Blättermann \n" "Language-Team: Deutsch \n" "Language: de\n" @@ -47,7 +47,7 @@ #: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 -#: ../src/client/application/geary-application.vala:22 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Senden und empfangen" @@ -270,15 +270,19 @@ msgid " • Username or password incorrect.\n" msgstr " • IMAP-Benutzername oder Passwort ungültig.\n" -#: ../src/client/application/geary-application.vala:21 +#: ../src/client/application/geary-application.vala:22 msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Copyright 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Copyright 2016-2017 Geary-Entwicklerteam." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Geary-Webseite besuchen" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "Info zu %s" @@ -286,7 +290,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Benjamin Steinwender \n" @@ -361,17 +365,17 @@ msgid "Use %s to open a new composer window" msgstr "Benutzen Sie %s, um ein neues »Verfassen«-Fenster zu öffnen" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Bitte melden Sie Kommentare, Vorschläge und Fehler an:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Die Befehlszeilenargumente konnten nicht interpretiert werden: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Unbekanntes Befehlszeilenargument »%s«\n" diff -Nru geary-0.12.0/po/es.po geary-0.12.4/po/es.po --- geary-0.12.0/po/es.po 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/po/es.po 2018-08-29 13:57:20.000000000 +0000 @@ -10,15 +10,15 @@ # pakitochus , 2012 # Revo , 2013 # Rodrigo Cares , 2012-2013 -# Daniel Mustieles , 2014-2015, 2015, 2016, 2017. +# Daniel Mustieles , 2014-2015, 2015, 2016, 2017, 2018. # msgid "" msgstr "" "Project-Id-Version: geary-0.4.1\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" "product=geary&keywords=I18N+L10N&component=internationalization\n" -"POT-Creation-Date: 2017-09-26 12:56+0000\n" -"PO-Revision-Date: 2017-09-26 16:49+0200\n" +"POT-Creation-Date: 2018-02-12 22:46+0000\n" +"PO-Revision-Date: 2018-02-26 11:36+0100\n" "Last-Translator: Daniel Mustieles \n" "Language-Team: es \n" "Language: es\n" @@ -44,6 +44,7 @@ #: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Envíe y reciba mensajes de correo electrónico" @@ -95,7 +96,6 @@ #. Translators: A screenshot description. #: ../desktop/org.gnome.Geary.appdata.xml.in.h:17 -#| msgid "_Display conversation preview" msgid "Geary displaying a conversation" msgstr "Geary mostrando una conversación" @@ -105,6 +105,7 @@ msgstr "Geary mostrando el editor de texto enriquecido" #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "Correo-e" @@ -121,11 +122,6 @@ msgid "Compose Message" msgstr "Redactar mensaje" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Cliente de correo" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Correo Geary" @@ -273,11 +269,16 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Copyright 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +#| msgid "Geary Development Team" +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Copyright 2016-2017 Equipo de desarrollo de Geary." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Visite el sitio web de Geary" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "Acerca de %s" @@ -285,7 +286,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Daniel Mustieles , 2015 - 2017\n" @@ -358,17 +359,17 @@ msgid "Use %s to open a new composer window" msgstr "Usar %s para abrir una ventana nueva del editor" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Envíe comentarios, sugerencias y errores a:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Falló al analizar las opciones de la línea de comandos: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Opción de la línea de comandos «%s» no reconocida\n" @@ -699,15 +700,15 @@ "\n" "Revise su conexión de red y reinicie Geary." -#: ../src/client/application/geary-controller.vala:1999 +#: ../src/client/application/geary-controller.vala:2010 msgid "Undo move (Ctrl+Z)" msgstr "Deshacer mover (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2009 +#: ../src/client/application/geary-controller.vala:2020 msgid "Are you sure you want to open these attachments?" msgstr "¿Está seguro de que quiere abrir estos adjuntos?" -#: ../src/client/application/geary-controller.vala:2010 +#: ../src/client/application/geary-controller.vala:2021 msgid "" "Attachments may cause damage to your system if opened. Only open files from " "trusted sources." @@ -715,79 +716,79 @@ "Los archivos adjuntos podrían causar daños a su sistema. Abra solo los " "archivos que provengan de fuentes fiables." -#: ../src/client/application/geary-controller.vala:2011 +#: ../src/client/application/geary-controller.vala:2022 msgid "Don’t _ask me again" msgstr "No volver a _preguntarme" -#: ../src/client/application/geary-controller.vala:2121 +#: ../src/client/application/geary-controller.vala:2126 #, c-format msgid "A file named “%s” already exists. Do you want to replace it?" msgstr "Ya existe un archivo llamado «%s». ¿Quiere reemplazarlo?" -#: ../src/client/application/geary-controller.vala:2123 +#: ../src/client/application/geary-controller.vala:2128 #, c-format msgid "" "The file already exists in “%s”. Replacing it will overwrite its contents." msgstr "" "El archivo ya existe en «%s». Si lo reemplaza sobrescribirá su contenido." -#: ../src/client/application/geary-controller.vala:2126 +#: ../src/client/application/geary-controller.vala:2131 msgid "_Replace" msgstr "_Reemplazar" #. Find out what to do with the inline composers. #. TODO: Remove this in favor of automatically saving drafts -#: ../src/client/application/geary-controller.vala:2374 +#: ../src/client/application/geary-controller.vala:2379 msgid "Close open draft messages?" msgstr "¿Quiere cerrar los mensajes en borrador abiertos?" -#: ../src/client/application/geary-controller.vala:2496 +#: ../src/client/application/geary-controller.vala:2501 #, c-format msgid "Empty all email from your %s folder?" msgstr "¿Quiere eliminar todos los mensajes de la carpeta «%s»?" -#: ../src/client/application/geary-controller.vala:2497 +#: ../src/client/application/geary-controller.vala:2502 msgid "This removes the email from Geary and your email server." msgstr "" "Esto eliminará el mensaje de Geary y del servidor de correo electrónico." -#: ../src/client/application/geary-controller.vala:2498 +#: ../src/client/application/geary-controller.vala:2503 msgid "This cannot be undone." msgstr "Esto no se puede deshacer." -#: ../src/client/application/geary-controller.vala:2499 +#: ../src/client/application/geary-controller.vala:2504 #, c-format msgid "Empty %s" msgstr "Vaciar %s" -#: ../src/client/application/geary-controller.vala:2516 +#: ../src/client/application/geary-controller.vala:2521 #, c-format msgid "Error emptying %s" msgstr "Error al vaciar «%s»" -#: ../src/client/application/geary-controller.vala:2546 +#: ../src/client/application/geary-controller.vala:2551 msgid "Do you want to permanently delete this message?" msgid_plural "Do you want to permanently delete these messages?" msgstr[0] "¿Quiere eliminar permanentemente este mensaje?" msgstr[1] "¿Quiere eliminar permanentemente estos mensajes?" -#: ../src/client/application/geary-controller.vala:2548 +#: ../src/client/application/geary-controller.vala:2553 msgid "Delete" msgstr "Eliminar" -#: ../src/client/application/geary-controller.vala:2580 +#: ../src/client/application/geary-controller.vala:2585 msgid "Undo archive (Ctrl+Z)" msgstr "Deshacer archivado (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2595 +#: ../src/client/application/geary-controller.vala:2600 msgid "Undo trash (Ctrl+Z)" msgstr "Deshacer envío a la papelera (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2649 +#: ../src/client/application/geary-controller.vala:2654 msgid "Undo (Ctrl+Z)" msgstr "Deshacer (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2780 +#: ../src/client/application/geary-controller.vala:2779 msgid "Failed to open default text editor." msgstr "Falló al abrir el editor de textos predeterminado." @@ -920,28 +921,28 @@ "adjuntar|adjuntando|adjunta|anexo|anexar|archivo|archivos|fichero|ficheros|" "adjunto|adjuntos|" -#: ../src/client/composer/composer-widget.vala:1122 -#: ../src/client/composer/composer-widget.vala:1141 +#: ../src/client/composer/composer-widget.vala:1129 +#: ../src/client/composer/composer-widget.vala:1148 msgid "Do you want to discard this message?" msgstr "¿Quiere descartar este mensaje?" -#: ../src/client/composer/composer-widget.vala:1245 +#: ../src/client/composer/composer-widget.vala:1252 msgid "Send message with an empty subject and body?" msgstr "¿Quiere enviar el mensaje sin asunto ni cuerpo?" -#: ../src/client/composer/composer-widget.vala:1247 +#: ../src/client/composer/composer-widget.vala:1254 msgid "Send message with an empty subject?" msgstr "¿Quiere enviar el mensaje sin asunto?" -#: ../src/client/composer/composer-widget.vala:1249 +#: ../src/client/composer/composer-widget.vala:1256 msgid "Send message with an empty body?" msgstr "¿Quiere enviar el mensaje sin cuerpo?" -#: ../src/client/composer/composer-widget.vala:1253 +#: ../src/client/composer/composer-widget.vala:1260 msgid "Send message without an attachment?" msgstr "¿Quiere enviar el mensaje sin el archivo adjunto?" -#: ../src/client/composer/composer-widget.vala:1515 +#: ../src/client/composer/composer-widget.vala:1522 #, c-format msgid "“%s” already attached for delivery." msgstr "Ya se ha adjuntado «%s» para enviarlo." @@ -951,73 +952,73 @@ #. description of the document type, the second will #. be a human-friendly size string. For example: #. Document (100.9MB) -#: ../src/client/composer/composer-widget.vala:1523 +#: ../src/client/composer/composer-widget.vala:1530 #: ../src/client/conversation-viewer/conversation-email.vala:138 #, c-format msgid "%s (%s)" msgstr "%s (%s)" -#: ../src/client/composer/composer-widget.vala:1560 +#: ../src/client/composer/composer-widget.vala:1567 #, c-format msgid "“%s” could not be found." msgstr "No se pudo encontrar «%s»." -#: ../src/client/composer/composer-widget.vala:1566 +#: ../src/client/composer/composer-widget.vala:1573 #, c-format msgid "“%s” is a folder." msgstr "«%s» es una carpeta." -#: ../src/client/composer/composer-widget.vala:1572 +#: ../src/client/composer/composer-widget.vala:1579 #, c-format msgid "“%s” is an empty file." msgstr "«%s» es un archivo vacío." -#: ../src/client/composer/composer-widget.vala:1585 +#: ../src/client/composer/composer-widget.vala:1592 #, c-format msgid "“%s” could not be opened for reading." msgstr "No se pudo abrir «%s» para lectura." -#: ../src/client/composer/composer-widget.vala:1593 +#: ../src/client/composer/composer-widget.vala:1600 msgid "Cannot add attachment" msgstr "No se puede adjuntar el archivo" -#: ../src/client/composer/composer-widget.vala:1645 +#: ../src/client/composer/composer-widget.vala:1652 msgid "To: " msgstr "Para: " -#: ../src/client/composer/composer-widget.vala:1648 +#: ../src/client/composer/composer-widget.vala:1655 msgid "Cc: " msgstr "Cc: " -#: ../src/client/composer/composer-widget.vala:1651 +#: ../src/client/composer/composer-widget.vala:1658 msgid "Bcc: " msgstr "Cco: " -#: ../src/client/composer/composer-widget.vala:1654 +#: ../src/client/composer/composer-widget.vala:1661 msgid "Reply-To: " msgstr "Responder a:" -#: ../src/client/composer/composer-widget.vala:1786 +#: ../src/client/composer/composer-widget.vala:1793 msgid "Select Color" msgstr "Seleccionar color" #. Displayed in the From dropdown to indicate an "alternate email address" #. for an account. The first printf argument will be the alternate email #. address, and the second will be the account's primary email address. -#: ../src/client/composer/composer-widget.vala:1986 +#: ../src/client/composer/composer-widget.vala:1993 #, c-format msgid "%1$s via %2$s" msgstr "%1$s mediante %2$s" #. Composer label (with mnemonic underscore) for the account selector #. when choosing what address to send a message from. -#: ../src/client/composer/composer-widget.vala:2028 +#: ../src/client/composer/composer-widget.vala:2035 msgid "_From:" msgstr "_De:" #. Translators: This is the name of the file chooser filter #. when inserting an image in the composer. -#: ../src/client/composer/composer-widget.vala:2252 +#: ../src/client/composer/composer-widget.vala:2259 msgid "Images" msgstr "Imágenes" @@ -1052,14 +1053,14 @@ #. Translators: This separates multiple 'from' #. addresses in the header preview for a message. -#: ../src/client/conversation-viewer/conversation-message.vala:586 +#: ../src/client/conversation-viewer/conversation-message.vala:585 msgid ", " msgstr ", " #. Translators: This string is used as the HTML IMG ALT #. attribute value when displaying an inline image in an email #. that did not specify a file name. E.g. Image\n" +"POT-Creation-Date: 2017-10-02 14:41+0000\n" +"PO-Revision-Date: 2017-10-25 12:27+0200\n" +"Last-Translator: Meskó Balázs \n" "Language-Team: Hungarian \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Lokalize 1.2\n" +"X-Generator: Poedit 2.0.4\n" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:1 +#. Translators: The application name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 #: ../desktop/org.gnome.Geary.desktop.in.h:1 #: ../desktop/geary-autostart.desktop.in.h:1 msgid "Geary" msgstr "Geary" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 +#. Translators: The development team's name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +msgid "Geary Development Team" +msgstr "Geary fejlesztőcsapat" + +#. Translators: The application's summary / tagline +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "E-mailek küldése és fogadása" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:3 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 msgid "" "Geary is an email application built around conversations, for the GNOME 3 " "desktop. It allows you to read, find and send email with a straightforward, " @@ -44,7 +52,7 @@ "GNOME 3 asztalhoz készült. Segítségével e-maileket olvashat, kereshet és " "küldhet egy lényegre törő és modern felületen." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 msgid "" "Conversations allow you to read a complete discussion without having to find " "and click from message to message." @@ -52,38 +60,48 @@ "A társalgások segítségével teljes beszélgetéseket olvashat el anélkül, hogy " "egyesével végig kellene kattintania a leveleken." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:5 -#| msgid "Geary's features include:" +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 msgid "Geary’s features include:" msgstr "A Geary néhány funkciója:" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 msgid "Quick email account setup" msgstr "Gyors e-mailfiók beállítás" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 msgid "Shows related messages together in conversations" msgstr "A kapcsolódó leveleket együtt jeleníti meg a beszélgetésekben" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:12 msgid "Fast, full text and keyword search" msgstr "Gyors, teljes szöveges és kulcsszavas keresés" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:13 msgid "Full-featured HTML and plain text message composer" msgstr "Teljes funkcionalitású HTML és egyszerű szöveges levélszerkesztő" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:14 msgid "Desktop notification of new mail" msgstr "Asztali értesítések új levél érkezésekor" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:15 msgid "Compatible with GMail, Yahoo! Mail, Outlook.com and other IMAP servers" msgstr "" "Kompatibilis a GMaillel, a Yahoo! Maillel, az Outlook.commal és más IMAP " "kiszolgálókkal" +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:17 +msgid "Geary displaying a conversation" +msgstr "Egy beszélgetés megjelenítése a Gearyben" + +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:19 +msgid "Geary showing the rich text composer" +msgstr "A Geary gazdag szövegszerkesztője" + #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "E-mail" @@ -100,11 +118,6 @@ msgid "Compose Message" msgstr "Levél írása" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Levelezőkliens" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Geary levelező" @@ -217,42 +230,34 @@ msgstr "Nem sikerült érvényesíteni:\n" #: ../src/client/accounts/add-edit-page.vala:794 -#| msgid " • Invalid account nickname.\n" msgid " • Invalid account nickname.\n" msgstr " • Érvénytelen fiók becenév.\n" #: ../src/client/accounts/add-edit-page.vala:797 -#| msgid " • Email address already added to Geary.\n" msgid " • Email address already added to Geary.\n" msgstr " • Az e-mail cím már hozzá lett adva a Geary programhoz.\n" #: ../src/client/accounts/add-edit-page.vala:801 -#| msgid " • IMAP connection error.\n" msgid " • IMAP connection error.\n" msgstr " • IMAP kapcsolódási hiba.\n" #: ../src/client/accounts/add-edit-page.vala:804 -#| msgid " • IMAP username or password incorrect.\n" msgid " • IMAP username or password incorrect.\n" msgstr " • Az IMAP felhasználónév vagy jelszó helytelen.\n" #: ../src/client/accounts/add-edit-page.vala:807 -#| msgid " • SMTP connection error.\n" msgid " • SMTP connection error.\n" msgstr " • SMTP kapcsolódási hiba.\n" #: ../src/client/accounts/add-edit-page.vala:810 -#| msgid " • SMTP username or password incorrect.\n" msgid " • SMTP username or password incorrect.\n" msgstr " • Az SMTP felhasználónév vagy jelszó helytelen.\n" #: ../src/client/accounts/add-edit-page.vala:814 -#| msgid " • Connection error.\n" msgid " • Connection error.\n" msgstr " • Kapcsolódási hiba.\n" #: ../src/client/accounts/add-edit-page.vala:818 -#| msgid " • Username or password incorrect.\n" msgid " • Username or password incorrect.\n" msgstr " • A felhasználónév vagy jelszó helytelen.\n" @@ -260,11 +265,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Copyright 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Copyright 2016-2017 Geary fejlesztőcsapat." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Keresse fel a Geary weboldalát" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "%s névjegye" @@ -272,12 +281,13 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Kelemen Gábor \n" "Lukács Bence \n" -"Úr Balázs " +"Úr Balázs \n" +"Meskó Balázs " #: ../src/client/application/geary-args.vala:10 msgid "Start Geary with hidden main window" @@ -346,19 +356,18 @@ msgid "Use %s to open a new composer window" msgstr "%s használata egy új levélíró ablak megnyitásához" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Kérjük írja le véleményét, észrevételeit és a hibákat ide:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "A parancssori kapcsolók feldolgozása meghiúsult: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format -#| msgid "Unrecognized command line option \"%s\"\n" msgid "Unrecognized command line option “%s”\n" msgstr "Ismeretlen parancssori kapcsoló: „%s”\n" @@ -431,7 +440,6 @@ msgstr "Beszélgetések áthelyezése" #: ../src/client/application/geary-controller.vala:450 -#| msgid "_Mark as..." msgid "_Mark as…" msgstr "_Megjelölés mint…" @@ -542,8 +550,8 @@ "Geary encountered an error while connecting to the server. Please try again " "in a few moments." msgstr "" -"A Geary hibába ütközött a kiszolgálóhoz történő kapcsolódáskor. Próbálja újra " -"néhány másodperc múlva." +"A Geary hibába ütközött a kiszolgálóhoz történő kapcsolódáskor. Próbálja " +"újra néhány másodperc múlva." #. / Displayed in the space-limited status bar when a message fails to be sent due to error. #: ../src/client/application/geary-controller.vala:1079 @@ -621,7 +629,6 @@ #: ../src/client/application/geary-controller.vala:1178 #, c-format -#| msgid "Unable to rebuild database for \"%s\"" msgid "Unable to rebuild database for “%s”" msgstr "Nem sikerült újjáépíteni az adatbázist ehhez: „%s”" @@ -665,12 +672,6 @@ "%s" #: ../src/client/application/geary-controller.vala:1212 -#| msgid "" -#| "The version number of the local mail database is formatted for a newer " -#| "version of Geary. Unfortunately, the database cannot be \"rolled back\" " -#| "to work with this version of Geary.\n" -#| "\n" -#| "Please install the latest version of Geary and try again." msgid "" "The version number of the local mail database is formatted for a newer " "version of Geary. Unfortunately, the database cannot be “rolled back” to " @@ -713,21 +714,16 @@ "megbízható forrásokból nyisson meg fájlokat." #: ../src/client/application/geary-controller.vala:2011 -#| msgid "Don't _ask me again" msgid "Don’t _ask me again" msgstr "Ne _kérdezze újra" #: ../src/client/application/geary-controller.vala:2121 #, c-format -#| msgid "A file named \"%s\" already exists. Do you want to replace it?" msgid "A file named “%s” already exists. Do you want to replace it?" msgstr "Már létezik „%s” nevű fájl. Le akarja cserélni?" #: ../src/client/application/geary-controller.vala:2123 #, c-format -#| msgid "" -#| "The file already exists in \"%s\". Replacing it will overwrite its " -#| "contents." msgid "" "The file already exists in “%s”. Replacing it will overwrite its contents." msgstr "" @@ -823,7 +819,6 @@ #. / Displayed in the space-limited status bar while a message is in the process of being sent. #: ../src/client/components/status-bar.vala:26 -#| msgid "Sending..." msgid "Sending…" msgstr "Küldés…" @@ -861,7 +856,6 @@ msgstr "_Beállítások" #: ../src/client/components/stock.vala:28 ../ui/conversation-email-menus.ui.h:7 -#| msgid "_Print..." msgid "_Print…" msgstr "_Nyomtatás…" @@ -886,7 +880,6 @@ msgstr "Érvénytelen hivatkozás URL" #: ../src/client/composer/composer-link-popover.vala:157 -#| msgid "Remove email address" msgid "Invalid email address" msgstr "Érvénytelen e-mail cím" @@ -952,7 +945,6 @@ #: ../src/client/composer/composer-widget.vala:1515 #, c-format -#| msgid "\"%s\" already attached for delivery." msgid "“%s” already attached for delivery." msgstr "„%s” már csatolva van a küldeményhez." @@ -969,25 +961,21 @@ #: ../src/client/composer/composer-widget.vala:1560 #, c-format -#| msgid "\"%s\" could not be found." msgid "“%s” could not be found." msgstr "„%s” nem található." #: ../src/client/composer/composer-widget.vala:1566 #, c-format -#| msgid "\"%s\" is a folder." msgid "“%s” is a folder." msgstr "„%s” egy mappa." #: ../src/client/composer/composer-widget.vala:1572 #, c-format -#| msgid "\"%s\" is an empty file." msgid "“%s” is an empty file." msgstr "„%s” egy üres fájl." #: ../src/client/composer/composer-widget.vala:1585 #, c-format -#| msgid "\"%s\" could not be opened for reading." msgid "“%s” could not be opened for reading." msgstr "„%s” nem nyitható meg olvasásra." @@ -1074,7 +1062,6 @@ #. attribute value when displaying an inline image in an email #. that did not specify a file name. E.g. Image\n" +"POT-Creation-Date: 2017-10-02 14:41+0000\n" +"PO-Revision-Date: 2017-10-04 17:26+0700\n" +"Last-Translator: Kukuh Syafaat \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/geary/" "language/id/)\n" "Language: id\n" @@ -21,21 +21,29 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 2.0.1\n" +"X-Generator: Poedit 2.0.3\n" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:1 +#. Translators: The application name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 #: ../desktop/org.gnome.Geary.desktop.in.h:1 #: ../desktop/geary-autostart.desktop.in.h:1 msgid "Geary" msgstr "Geary" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 +#. Translators: The development team's name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +msgid "Geary Development Team" +msgstr "Tim Pengembang Geary" + +#. Translators: The application's summary / tagline +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Kirim dan terima surel" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:3 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 msgid "" "Geary is an email application built around conversations, for the GNOME 3 " "desktop. It allows you to read, find and send email with a straightforward, " @@ -45,7 +53,7 @@ "desktop GNOME 3. Memungkinkan Anda membaca, mencari, dan mengirim surel " "dengan antar muka yang modern, mudah." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 msgid "" "Conversations allow you to read a complete discussion without having to find " "and click from message to message." @@ -53,36 +61,47 @@ "Percakapan memungkinkan Anda membaca diskusi lengkap tanpa perlu mencari dan " "mengklik dari pesan ke pesan." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:5 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 msgid "Geary’s features include:" msgstr "Fitur Geary termasuk:" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 msgid "Quick email account setup" msgstr "Penyiapan akun surel cepat" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 msgid "Shows related messages together in conversations" msgstr "Menampilkan pesan-pesan yang berhubungan bersama-sama dalam percakapan" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:12 msgid "Fast, full text and keyword search" msgstr "Pencarian kata kunci dan teks penuh yang cepat" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:13 msgid "Full-featured HTML and plain text message composer" msgstr "Penyusun pesan teks polos dan HTML berfitur lengkap" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:14 msgid "Desktop notification of new mail" msgstr "Pemberitahuan desktop atas surat baru" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:15 msgid "Compatible with GMail, Yahoo! Mail, Outlook.com and other IMAP servers" msgstr "" "Kompatibel dengan GMail, Yahoo! Mail, Outlook.com, dan server IMAP lain" +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:17 +msgid "Geary displaying a conversation" +msgstr "Geary menampilkan percakapan" + +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:19 +msgid "Geary showing the rich text composer" +msgstr "Geary menunjukkan penyusun rich text" + #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "Surel" @@ -99,11 +118,6 @@ msgid "Compose Message" msgstr "Susun Pesan" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Klien Surat" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Surat Geary" @@ -253,11 +267,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Hak Cipta 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Hak Cipta 2016-2017 Tim Pengembang Geary." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Kunjungi situs web Geary" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "Tentang %s" @@ -265,11 +283,12 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Andika Triwidada , 2012, 2013, 2016, 2017\n" -"Dani Pratomo , 2012." +"Dani Pratomo , 2012.\n" +"Kukuh Syafaat , 2017." #: ../src/client/application/geary-args.vala:10 msgid "Start Geary with hidden main window" @@ -338,17 +357,17 @@ msgid "Use %s to open a new composer window" msgstr "Pakai %s untuk membuka jendela penyusun baru" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Harap kirimkan komentar, saran, dan kutu ke:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Gagal mengurai opsi baris perintah: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Opsi baris perintah tidak dikenal \"%s\"\n" @@ -2627,3 +2646,6 @@ #: ../ui/upgrade_dialog.glade.h:1 msgid "Geary update in progress…" msgstr "Pemutakhiran Geary sedang berlangsung…" + +#~ msgid "Mail Client" +#~ msgstr "Klien Surat" diff -Nru geary-0.12.0/po/it.po geary-0.12.4/po/it.po --- geary-0.12.0/po/it.po 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/po/it.po 2018-08-29 13:57:20.000000000 +0000 @@ -12,15 +12,15 @@ # Piercarlo Bennici , 2013 # Vincenzo Cerminara , 2012 # Gianvito Cavasoli , 2016. -# Federico Bruni , 2013, 2014, 2015, 2016, 2017. +# Federico Bruni , 2013, 2014, 2015, 2016, 2017, 2018. # msgid "" msgstr "" "Project-Id-Version: geary master\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" "product=geary&keywords=I18N+L10N&component=internationalization\n" -"POT-Creation-Date: 2017-02-22 19:19+0000\n" -"PO-Revision-Date: 2017-03-03 13:13+0100\n" +"POT-Creation-Date: 2017-11-16 05:25+0000\n" +"PO-Revision-Date: 2018-01-28 11:07+0100\n" "Last-Translator: Federico Bruni \n" "Language-Team: Italiano <>\n" "Language: it\n" @@ -30,19 +30,27 @@ "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Gtranslator 2.91.7\n" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:1 +#. Translators: The application name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 #: ../desktop/org.gnome.Geary.desktop.in.h:1 #: ../desktop/geary-autostart.desktop.in.h:1 msgid "Geary" msgstr "Geary" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 +#. Translators: The development team's name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +msgid "Geary Development Team" +msgstr "Gruppo sviluppatori di Geary" + +#. Translators: The application's summary / tagline +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Invia e riceve email" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:3 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 msgid "" "Geary is an email application built around conversations, for the GNOME 3 " "desktop. It allows you to read, find and send email with a straightforward, " @@ -52,7 +60,7 @@ "l'ambiente desktop GNOME 3. Permette di leggere, trovare e inviare email con " "un'interfaccia semplice e moderna." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 msgid "" "Conversations allow you to read a complete discussion without having to find " "and click from message to message." @@ -60,42 +68,51 @@ "Le conversazioni permettono di leggere un'intera discussione senza dover " "cercare e fare clic su ogni messaggio." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:5 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 msgid "Geary’s features include:" msgstr "Le funzionalità di Geary comprendono:" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 msgid "Quick email account setup" msgstr "Rapida configurazione dell'account di posta" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 msgid "Shows related messages together in conversations" msgstr "Mostra messaggi correlati insieme in conversazioni" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:12 msgid "Fast, full text and keyword search" msgstr "Ricerca rapida \"full text\" e per parole chiave" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:13 msgid "Full-featured HTML and plain text message composer" msgstr "Compositore dei messaggi in HTML e testo semplice" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 -#| msgid "Show _notifications for new mail" +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:14 msgid "Desktop notification of new mail" msgstr "Notifiche desktop della nuova posta" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:15 msgid "Compatible with GMail, Yahoo! Mail, Outlook.com and other IMAP servers" msgstr "Compatibile con GMail, Yahoo! Mail, Outlook.com e altri server IMAP" +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:17 +#| msgid "_Display conversation preview" +msgid "Geary displaying a conversation" +msgstr "L'applicazione che mostra una conversazione" + +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:19 +msgid "Geary showing the rich text composer" +msgstr "L'applicazione che mostra il compositore di testo formattato" + #: ../desktop/org.gnome.Geary.desktop.in.h:2 -#| msgid "Gmail" +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "Email" #: ../desktop/org.gnome.Geary.desktop.in.h:3 -#| msgid "Geary Mail" msgid "Geary Email" msgstr "Geary Email" @@ -108,11 +125,6 @@ msgid "Compose Message" msgstr "Componi messaggio" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Client di posta" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Geary Mail" @@ -212,55 +224,47 @@ msgid "Preview" msgstr "Anteprima" -#: ../src/client/accounts/add-edit-page.vala:739 +#: ../src/client/accounts/add-edit-page.vala:751 msgid "Remem_ber passwords" msgstr "Ric_ordare le password" -#: ../src/client/accounts/add-edit-page.vala:746 ../ui/login.glade.h:7 +#: ../src/client/accounts/add-edit-page.vala:758 ../ui/login.glade.h:7 msgid "Remem_ber password" msgstr "Ric_ordare la password" -#: ../src/client/accounts/add-edit-page.vala:780 +#: ../src/client/accounts/add-edit-page.vala:792 msgid "Unable to validate:\n" msgstr "Impossibile da convalidare:\n" -#: ../src/client/accounts/add-edit-page.vala:782 -#| msgid " • Invalid account nickname.\n" +#: ../src/client/accounts/add-edit-page.vala:794 msgid " • Invalid account nickname.\n" msgstr " • Soprannome dell'account non valido.\n" -#: ../src/client/accounts/add-edit-page.vala:785 -#| msgid " • Email address already added to Geary.\n" +#: ../src/client/accounts/add-edit-page.vala:797 msgid " • Email address already added to Geary.\n" msgstr " • Indirizzo email già presente nell'applicazione.\n" -#: ../src/client/accounts/add-edit-page.vala:789 -#| msgid " • IMAP connection error.\n" +#: ../src/client/accounts/add-edit-page.vala:801 msgid " • IMAP connection error.\n" msgstr " • Errore di connessione IMAP.\n" -#: ../src/client/accounts/add-edit-page.vala:792 -#| msgid " • IMAP username or password incorrect.\n" +#: ../src/client/accounts/add-edit-page.vala:804 msgid " • IMAP username or password incorrect.\n" msgstr " • Nome utente o password IMAP non corretti.\n" -#: ../src/client/accounts/add-edit-page.vala:795 -#| msgid " • SMTP connection error.\n" +#: ../src/client/accounts/add-edit-page.vala:807 msgid " • SMTP connection error.\n" msgstr " • Errore di connessione SMTP.\n" -#: ../src/client/accounts/add-edit-page.vala:798 -#| msgid " • SMTP username or password incorrect.\n" +#: ../src/client/accounts/add-edit-page.vala:810 msgid " • SMTP username or password incorrect.\n" msgstr " • Nome utente o password SMTP non corretti.\n" -#: ../src/client/accounts/add-edit-page.vala:802 -#| msgid " • Connection error.\n" +#: ../src/client/accounts/add-edit-page.vala:814 msgid " • Connection error.\n" msgstr " • Errore di connessione.\n" -#: ../src/client/accounts/add-edit-page.vala:806 -#| msgid " • Username or password incorrect.\n" +#: ../src/client/accounts/add-edit-page.vala:818 msgid " • Username or password incorrect.\n" msgstr " • Nome utente o password non corretti.\n" @@ -268,11 +272,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Copyright 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Copyright 2016-2017 gruppo sviluppatori di Geary." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Visita il sito web di Geary" -#: ../src/client/application/geary-application.vala:445 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "Informazioni su %s" @@ -280,7 +288,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:449 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Daniele Napolitano\n" @@ -354,19 +362,18 @@ msgid "Use %s to open a new composer window" msgstr "Usa %s per aprire una nuova finestra di composizione" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Inviare commenti, suggerimenti e segnalazioni di bug a:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Analisi delle opzioni a riga di comando non riuscita: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format -#| msgid "Unrecognized command line option \"%s\"\n" msgid "Unrecognized command line option “%s”\n" msgstr "Opzione a riga di comando «%s» non riconosciuta\n" @@ -413,7 +420,7 @@ msgstr "Segna come non i_ndesiderata" #: ../src/client/application/geary-controller.vala:76 -#: ../src/client/application/geary-controller.vala:449 +#: ../src/client/application/geary-controller.vala:448 msgid "Mark conversation" msgstr "Segna conversazione" @@ -430,7 +437,7 @@ msgstr "Aggiunge etichetta alle conversazioni" #: ../src/client/application/geary-controller.vala:80 -#: ../src/client/application/geary-controller.vala:488 +#: ../src/client/application/geary-controller.vala:487 msgid "Move conversation" msgstr "Sposta conversazione" @@ -438,97 +445,95 @@ msgid "Move conversations" msgstr "Sposta conversazioni" -#: ../src/client/application/geary-controller.vala:451 -#| msgid "_Mark as..." +#: ../src/client/application/geary-controller.vala:450 msgid "_Mark as…" msgstr "_Segna come…" -#: ../src/client/application/geary-controller.vala:457 +#: ../src/client/application/geary-controller.vala:456 msgid "Mark as _Read" msgstr "Segna come _letto" -#: ../src/client/application/geary-controller.vala:463 +#: ../src/client/application/geary-controller.vala:462 msgid "Mark as _Unread" msgstr "Segna come _non letto" -#: ../src/client/application/geary-controller.vala:469 +#: ../src/client/application/geary-controller.vala:468 msgid "_Star" msgstr "_Speciale" -#: ../src/client/application/geary-controller.vala:474 +#: ../src/client/application/geary-controller.vala:473 msgid "U_nstar" msgstr "_Non speciale" -#: ../src/client/application/geary-controller.vala:484 +#: ../src/client/application/geary-controller.vala:483 msgid "Add label" msgstr "Aggiunge etichetta" -#: ../src/client/application/geary-controller.vala:485 +#: ../src/client/application/geary-controller.vala:484 msgid "_Label" msgstr "_Etichetta" -#: ../src/client/application/geary-controller.vala:489 +#: ../src/client/application/geary-controller.vala:488 msgid "_Move" msgstr "_Sposta" -#: ../src/client/application/geary-controller.vala:493 +#: ../src/client/application/geary-controller.vala:492 msgid "Compose new message (Ctrl+N, N)" msgstr "Compone un nuovo messaggio (Ctrl+N, N)" -#: ../src/client/application/geary-controller.vala:497 +#: ../src/client/application/geary-controller.vala:496 #: ../ui/conversation-email-menus.ui.h:1 msgid "_Reply" msgstr "_Rispondi" -#: ../src/client/application/geary-controller.vala:498 +#: ../src/client/application/geary-controller.vala:497 msgid "Reply (Ctrl+R, R)" msgstr "Risponde (Ctrl+R, R)" -#: ../src/client/application/geary-controller.vala:502 +#: ../src/client/application/geary-controller.vala:501 msgid "R_eply All" msgstr "R_ispondi a tutti" -#: ../src/client/application/geary-controller.vala:503 +#: ../src/client/application/geary-controller.vala:502 msgid "Reply all (Ctrl+Shift+R, Shift+R)" msgstr "Risponde a tutti (Ctrl+Maiusc+R, Maiusc+R)" -#: ../src/client/application/geary-controller.vala:508 +#: ../src/client/application/geary-controller.vala:507 #: ../ui/conversation-email-menus.ui.h:3 msgid "_Forward" msgstr "_Inoltra" -#: ../src/client/application/geary-controller.vala:509 +#: ../src/client/application/geary-controller.vala:508 msgid "Forward (Ctrl+L, F)" msgstr "Inoltra (Ctrl+L, F)" -#: ../src/client/application/geary-controller.vala:539 +#: ../src/client/application/geary-controller.vala:538 msgid "Empty _Spam…" msgstr "Svuota _indesiderata…" -#: ../src/client/application/geary-controller.vala:543 +#: ../src/client/application/geary-controller.vala:542 msgid "Empty _Trash…" msgstr "Svuota _cestino…" #. No callback is connected, since we bind the toggle button to the search bar visibility -#: ../src/client/application/geary-controller.vala:575 +#: ../src/client/application/geary-controller.vala:574 msgid "Toggle search bar" msgstr "Attiva/Disattiva barra di ricerca" #. No callback is connected, since we bind the toggle button to the find bar visibility -#: ../src/client/application/geary-controller.vala:580 -#| msgid "Toggle search bar" +#: ../src/client/application/geary-controller.vala:579 msgid "Toggle find bar" msgstr "Attiva/Disattiva barra di ricerca nella conversazione" -#: ../src/client/application/geary-controller.vala:758 +#: ../src/client/application/geary-controller.vala:757 msgid "Unable to store server trust exception" msgstr "Impossibile salvare l'eccezione di fiducia nel server" -#: ../src/client/application/geary-controller.vala:993 +#: ../src/client/application/geary-controller.vala:992 msgid "Your settings are insecure" msgstr "Le impostazioni non sono sicure" -#: ../src/client/application/geary-controller.vala:994 +#: ../src/client/application/geary-controller.vala:993 msgid "" "Your IMAP and/or SMTP settings do not specify SSL or TLS. This means your " "username and password could be read by another person on the network. Are " @@ -538,15 +543,15 @@ "che nome utente e password potrebbero essere letti da altre persone sulla " "rete. Sicuri di volerlo?" -#: ../src/client/application/geary-controller.vala:995 +#: ../src/client/application/geary-controller.vala:994 msgid "Co_ntinue" msgstr "Co_ntinua" -#: ../src/client/application/geary-controller.vala:1042 +#: ../src/client/application/geary-controller.vala:1041 msgid "Error connecting to the server" msgstr "Errore di connessione col server" -#: ../src/client/application/geary-controller.vala:1043 +#: ../src/client/application/geary-controller.vala:1042 msgid "" "Geary encountered an error while connecting to the server. Please try again " "in a few moments." @@ -555,12 +560,12 @@ "Riprovare in un secondo momento." #. / Displayed in the space-limited status bar when a message fails to be sent due to error. -#: ../src/client/application/geary-controller.vala:1080 +#: ../src/client/application/geary-controller.vala:1079 #: ../src/client/components/status-bar.vala:29 msgid "Error sending email" msgstr "Errore durante l'invio dell'email" -#: ../src/client/application/geary-controller.vala:1081 +#: ../src/client/application/geary-controller.vala:1080 msgid "" "Geary encountered an error sending an email. If the problem persists, " "please manually delete the email from your Outbox folder." @@ -570,12 +575,12 @@ #. Displayed in the space-limited status bar when a message fails to be uploaded #. to Sent Mail after being sent. -#: ../src/client/application/geary-controller.vala:1085 +#: ../src/client/application/geary-controller.vala:1084 #: ../src/client/components/status-bar.vala:33 msgid "Error saving sent mail" msgstr "Errore durante il salvataggio dell'email inviata" -#: ../src/client/application/geary-controller.vala:1086 +#: ../src/client/application/geary-controller.vala:1085 msgid "" "Geary encountered an error saving a sent message to Sent Mail. The message " "will stay in your Outbox folder until you delete it." @@ -584,19 +589,19 @@ "messaggio resterà nella cartella della posta in uscita finché non viene " "eliminato." -#: ../src/client/application/geary-controller.vala:1155 +#: ../src/client/application/geary-controller.vala:1154 msgid "Labels" msgstr "Etichette" #. give the user two options: reset the Account local store, or exit Geary. A third #. could be done to leave the Account in an unopened state, but we don't currently #. have provisions for that. -#: ../src/client/application/geary-controller.vala:1167 +#: ../src/client/application/geary-controller.vala:1166 #, c-format msgid "Unable to open the database for %s" msgstr "Impossibile aprire il database per %s" -#: ../src/client/application/geary-controller.vala:1168 +#: ../src/client/application/geary-controller.vala:1167 #, c-format msgid "" "There was an error opening the local mail database for this account. This is " @@ -622,21 +627,20 @@ "allegati. Tale operazione non ha effetti sulla posta presente sul server." "" -#: ../src/client/application/geary-controller.vala:1170 +#: ../src/client/application/geary-controller.vala:1169 msgid "_Rebuild" msgstr "_Ricostruisci" -#: ../src/client/application/geary-controller.vala:1170 +#: ../src/client/application/geary-controller.vala:1169 msgid "E_xit" msgstr "_Esci" -#: ../src/client/application/geary-controller.vala:1179 +#: ../src/client/application/geary-controller.vala:1178 #, c-format -#| msgid "Unable to rebuild database for \"%s\"" msgid "Unable to rebuild database for “%s”" msgstr "Impossibile ricostruire il database per «%s»" -#: ../src/client/application/geary-controller.vala:1180 +#: ../src/client/application/geary-controller.vala:1179 #, c-format msgid "" "Error during rebuild:\n" @@ -649,14 +653,14 @@ #. some other problem opening the account ... as with other flow path, can't run #. Geary today with an account in unopened state, so have to exit -#: ../src/client/application/geary-controller.vala:1202 -#: ../src/client/application/geary-controller.vala:1212 -#: ../src/client/application/geary-controller.vala:1223 +#: ../src/client/application/geary-controller.vala:1201 +#: ../src/client/application/geary-controller.vala:1211 +#: ../src/client/application/geary-controller.vala:1222 #, c-format msgid "Unable to open local mailbox for %s" msgstr "Impossibile aprire la casella di posta locale per %s" -#: ../src/client/application/geary-controller.vala:1203 +#: ../src/client/application/geary-controller.vala:1202 #, c-format msgid "" "There was an error opening the local mail database for this account. This is " @@ -675,13 +679,7 @@ "\n" "%s" -#: ../src/client/application/geary-controller.vala:1213 -#| msgid "" -#| "The version number of the local mail database is formatted for a newer " -#| "version of Geary. Unfortunately, the database cannot be \"rolled back\" " -#| "to work with this version of Geary.\n" -#| "\n" -#| "Please install the latest version of Geary and try again." +#: ../src/client/application/geary-controller.vala:1212 msgid "" "The version number of the local mail database is formatted for a newer " "version of Geary. Unfortunately, the database cannot be “rolled back” to " @@ -696,7 +694,7 @@ "\n" "Si consiglia di installare l'ultima versione dell'applicazione e riprovare." -#: ../src/client/application/geary-controller.vala:1224 +#: ../src/client/application/geary-controller.vala:1223 msgid "" "There was an error opening the local account. This is probably due to " "connectivity issues.\n" @@ -708,16 +706,15 @@ "\n" "Controllare la connessione di rete e riavviare l'applicazione." -#: ../src/client/application/geary-controller.vala:1999 +#: ../src/client/application/geary-controller.vala:2008 msgid "Undo move (Ctrl+Z)" msgstr "Annulla lo spostamento (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2009 -#| msgid "Are you sure you want to open \"%s\"?" +#: ../src/client/application/geary-controller.vala:2018 msgid "Are you sure you want to open these attachments?" msgstr "Sicuri di voler aprire questi allegati?" -#: ../src/client/application/geary-controller.vala:2010 +#: ../src/client/application/geary-controller.vala:2019 msgid "" "Attachments may cause damage to your system if opened. Only open files from " "trusted sources." @@ -725,83 +722,78 @@ "Gli allegati possono danneggiare il sistema se aperti. Aprire solo file " "provenienti da fonti fidate." -#: ../src/client/application/geary-controller.vala:2011 -#| msgid "Don't _ask me again" +#: ../src/client/application/geary-controller.vala:2020 msgid "Don’t _ask me again" msgstr "_Non chiederlo più" -#: ../src/client/application/geary-controller.vala:2146 +#: ../src/client/application/geary-controller.vala:2130 #, c-format -#| msgid "A file named \"%s\" already exists. Do you want to replace it?" msgid "A file named “%s” already exists. Do you want to replace it?" msgstr "Il file «%s» esiste già. Sostituirlo?" -#: ../src/client/application/geary-controller.vala:2148 +#: ../src/client/application/geary-controller.vala:2132 #, c-format -#| msgid "" -#| "The file already exists in \"%s\". Replacing it will overwrite its " -#| "contents." msgid "" "The file already exists in “%s”. Replacing it will overwrite its contents." msgstr "" "Il file esiste già in «%s». Sostituendolo il suo contenuto sarà sovrascritto." -#: ../src/client/application/geary-controller.vala:2151 +#: ../src/client/application/geary-controller.vala:2135 msgid "_Replace" msgstr "_Sostituisci" #. Find out what to do with the inline composers. #. TODO: Remove this in favor of automatically saving drafts -#: ../src/client/application/geary-controller.vala:2398 +#: ../src/client/application/geary-controller.vala:2383 msgid "Close open draft messages?" msgstr "Chiudere le bozze aperte?" -#: ../src/client/application/geary-controller.vala:2520 +#: ../src/client/application/geary-controller.vala:2505 #, c-format msgid "Empty all email from your %s folder?" msgstr "Svuotare tutte le email dalla cartella %s?" -#: ../src/client/application/geary-controller.vala:2521 +#: ../src/client/application/geary-controller.vala:2506 msgid "This removes the email from Geary and your email server." msgstr "Questo rimuoverà le email dall'applicazione e dal server di posta." -#: ../src/client/application/geary-controller.vala:2522 +#: ../src/client/application/geary-controller.vala:2507 msgid "This cannot be undone." msgstr "Impossibile annullare questa azione." -#: ../src/client/application/geary-controller.vala:2523 +#: ../src/client/application/geary-controller.vala:2508 #, c-format msgid "Empty %s" msgstr "Svuota %s" -#: ../src/client/application/geary-controller.vala:2540 +#: ../src/client/application/geary-controller.vala:2525 #, c-format msgid "Error emptying %s" msgstr "Errore nello svuotare %s" -#: ../src/client/application/geary-controller.vala:2570 +#: ../src/client/application/geary-controller.vala:2555 msgid "Do you want to permanently delete this message?" msgid_plural "Do you want to permanently delete these messages?" msgstr[0] "Eliminare permanentemente questo messaggio?" msgstr[1] "Eliminare permanentemente questi messaggi?" -#: ../src/client/application/geary-controller.vala:2572 +#: ../src/client/application/geary-controller.vala:2557 msgid "Delete" msgstr "Elimina" -#: ../src/client/application/geary-controller.vala:2604 +#: ../src/client/application/geary-controller.vala:2589 msgid "Undo archive (Ctrl+Z)" msgstr "Annulla l'archiviazione (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2619 +#: ../src/client/application/geary-controller.vala:2604 msgid "Undo trash (Ctrl+Z)" msgstr "Annulla lo spostamento nel cestino (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2673 +#: ../src/client/application/geary-controller.vala:2658 msgid "Undo (Ctrl+Z)" msgstr "Annulla (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2806 +#: ../src/client/application/geary-controller.vala:2789 msgid "Failed to open default text editor." msgstr "Apertura dell'editor di testo predefinito non riuscita." @@ -834,7 +826,6 @@ #. / Displayed in the space-limited status bar while a message is in the process of being sent. #: ../src/client/components/status-bar.vala:26 -#| msgid "Sending..." msgid "Sending…" msgstr "Invio…" @@ -872,7 +863,6 @@ msgstr "Preferen_ze" #: ../src/client/components/stock.vala:28 ../ui/conversation-email-menus.ui.h:7 -#| msgid "_Print..." msgid "_Print…" msgstr "Stam_pa…" @@ -899,7 +889,6 @@ msgstr "URL del collegamento non valido" #: ../src/client/composer/composer-link-popover.vala:157 -#| msgid "Remove email address" msgid "Invalid email address" msgstr "Indirizzo email non valido" @@ -936,30 +925,29 @@ "enclosing|encloses|enclosure|enclosures|allegato|allegati|allego|allega|" "allegare|allegando|includo" -#: ../src/client/composer/composer-widget.vala:1121 -#: ../src/client/composer/composer-widget.vala:1140 +#: ../src/client/composer/composer-widget.vala:1122 +#: ../src/client/composer/composer-widget.vala:1141 msgid "Do you want to discard this message?" msgstr "Scartare questo messaggio?" -#: ../src/client/composer/composer-widget.vala:1237 +#: ../src/client/composer/composer-widget.vala:1245 msgid "Send message with an empty subject and body?" msgstr "Inviare il messaggio senza l'oggetto e il testo?" -#: ../src/client/composer/composer-widget.vala:1239 +#: ../src/client/composer/composer-widget.vala:1247 msgid "Send message with an empty subject?" msgstr "Inviare il messaggio senza un oggetto?" -#: ../src/client/composer/composer-widget.vala:1241 +#: ../src/client/composer/composer-widget.vala:1249 msgid "Send message with an empty body?" msgstr "Inviare il messaggio senza il testo?" -#: ../src/client/composer/composer-widget.vala:1245 +#: ../src/client/composer/composer-widget.vala:1253 msgid "Send message without an attachment?" msgstr "Inviare il messaggio senza un allegato?" -#: ../src/client/composer/composer-widget.vala:1498 +#: ../src/client/composer/composer-widget.vala:1515 #, c-format -#| msgid "\"%s\" already attached for delivery." msgid "“%s” already attached for delivery." msgstr "«%s» è già allegato per l'invio." @@ -968,78 +956,73 @@ #. description of the document type, the second will #. be a human-friendly size string. For example: #. Document (100.9MB) -#: ../src/client/composer/composer-widget.vala:1506 -#: ../src/client/conversation-viewer/conversation-email.vala:135 +#: ../src/client/composer/composer-widget.vala:1523 +#: ../src/client/conversation-viewer/conversation-email.vala:138 #, c-format msgid "%s (%s)" msgstr "%s (%s)" -#: ../src/client/composer/composer-widget.vala:1543 +#: ../src/client/composer/composer-widget.vala:1560 #, c-format -#| msgid "\"%s\" could not be found." msgid "“%s” could not be found." msgstr "«%s» non può essere trovato." -#: ../src/client/composer/composer-widget.vala:1549 +#: ../src/client/composer/composer-widget.vala:1566 #, c-format -#| msgid "\"%s\" is a folder." msgid "“%s” is a folder." msgstr "«%s» è una cartella." -#: ../src/client/composer/composer-widget.vala:1555 +#: ../src/client/composer/composer-widget.vala:1572 #, c-format -#| msgid "\"%s\" is an empty file." msgid "“%s” is an empty file." msgstr "«%s» è un file vuoto." -#: ../src/client/composer/composer-widget.vala:1568 +#: ../src/client/composer/composer-widget.vala:1585 #, c-format -#| msgid "\"%s\" could not be opened for reading." msgid "“%s” could not be opened for reading." msgstr "«%s» non può essere aperto per la lettura." -#: ../src/client/composer/composer-widget.vala:1576 +#: ../src/client/composer/composer-widget.vala:1593 msgid "Cannot add attachment" msgstr "Impossibile aggiungere l'allegato" -#: ../src/client/composer/composer-widget.vala:1638 +#: ../src/client/composer/composer-widget.vala:1645 msgid "To: " msgstr "A: " -#: ../src/client/composer/composer-widget.vala:1641 +#: ../src/client/composer/composer-widget.vala:1648 msgid "Cc: " msgstr "Cc: " -#: ../src/client/composer/composer-widget.vala:1644 +#: ../src/client/composer/composer-widget.vala:1651 msgid "Bcc: " msgstr "Ccn: " -#: ../src/client/composer/composer-widget.vala:1647 +#: ../src/client/composer/composer-widget.vala:1654 msgid "Reply-To: " msgstr "Rispondi a:" -#: ../src/client/composer/composer-widget.vala:1778 +#: ../src/client/composer/composer-widget.vala:1786 msgid "Select Color" msgstr "Seleziona colore" #. Displayed in the From dropdown to indicate an "alternate email address" #. for an account. The first printf argument will be the alternate email #. address, and the second will be the account's primary email address. -#: ../src/client/composer/composer-widget.vala:1978 +#: ../src/client/composer/composer-widget.vala:1986 #, c-format msgid "%1$s via %2$s" msgstr "%1$s tramite %2$s" #. Composer label (with mnemonic underscore) for the account selector #. when choosing what address to send a message from. -#: ../src/client/composer/composer-widget.vala:2020 +#: ../src/client/composer/composer-widget.vala:2028 msgid "_From:" msgstr "_Da:" #. Translators: This is the name of the file chooser filter #. when inserting an image in the composer. -#: ../src/client/composer/composer-widget.vala:2243 -#| msgid "Show Images" +#: ../src/client/composer/composer-widget.vala:2252 msgid "Images" msgstr "Immagini" @@ -1061,73 +1044,68 @@ #. Translators: This is the file type displayed for #. attachments with unknown file types. -#: ../src/client/conversation-viewer/conversation-email.vala:121 +#: ../src/client/conversation-viewer/conversation-email.vala:124 msgid "Unknown" msgstr "Sconosciuto" #. Preview headers #. Translators: This is displayed in place of the from address #. when the message has no from address. -#: ../src/client/conversation-viewer/conversation-message.vala:330 +#: ../src/client/conversation-viewer/conversation-message.vala:331 msgid "No sender" msgstr "Nessun mittente" #. Translators: This separates multiple 'from' #. addresses in the header preview for a message. -#: ../src/client/conversation-viewer/conversation-message.vala:585 +#: ../src/client/conversation-viewer/conversation-message.vala:586 msgid ", " msgstr ", " #. Translators: This string is used as the HTML IMG ALT #. attribute value when displaying an inline image in an email #. that did not specify a file name. E.g. Image\n" "Language-Team: Polish \n" "Language: pl\n" @@ -43,6 +43,7 @@ #: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Wysyłanie i odbieranie poczty" @@ -104,6 +105,7 @@ msgstr "Okno tworzenia wiadomości z formatowaniem" #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "Poczta" @@ -122,11 +124,6 @@ msgid "Compose Message" msgstr "Utwórz wiadomość" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Klient poczty" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Klient poczty Geary" @@ -274,11 +271,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Copyright 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Copyright 2016-2017 Zespół programistów Geary" + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Witryna programu Geary" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "O programie %s" @@ -286,7 +287,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "scrx , 2012\n" @@ -368,18 +369,18 @@ msgid "Use %s to open a new composer window" msgstr "Należy użyć %s, aby otworzyć nowe okno tworzenia wiadomości" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "" "Komentarze, sugestie i błędy prosimy zgłaszać do (w języku angielskim):" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Przetworzenie opcji wiersza poleceń się nie powiodło: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Nieznana opcja wiersza poleceń „%s”\n" diff -Nru geary-0.12.0/po/POTFILES.in geary-0.12.4/po/POTFILES.in --- geary-0.12.0/po/POTFILES.in 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/po/POTFILES.in 2018-08-29 13:57:20.000000000 +0000 @@ -269,7 +269,6 @@ src/engine/imap/message/imap-flag.vala src/engine/imap/message/imap-flags.vala src/engine/imap/message/imap-internal-date.vala -src/engine/imap/message/imap-mailbox-parameter.vala src/engine/imap/message/imap-mailbox-specifier.vala src/engine/imap/message/imap-message-data.vala src/engine/imap/message/imap-message-flag.vala diff -Nru geary-0.12.0/po/pt_BR.po geary-0.12.4/po/pt_BR.po --- geary-0.12.0/po/pt_BR.po 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/po/pt_BR.po 2018-08-29 13:57:20.000000000 +0000 @@ -19,8 +19,8 @@ "Project-Id-Version: geary\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=geary&" "keywords=I18N+L10N&component=internationalization\n" -"POT-Creation-Date: 2017-09-26 12:56+0000\n" -"PO-Revision-Date: 2017-09-26 18:46-0200\n" +"POT-Creation-Date: 2017-10-02 14:41+0000\n" +"PO-Revision-Date: 2017-10-07 03:52-0200\n" "Last-Translator: Rafael Fontenelle \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" @@ -47,6 +47,7 @@ #: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Envie e receba e-mail" @@ -99,7 +100,6 @@ #. Translators: A screenshot description. #: ../desktop/org.gnome.Geary.appdata.xml.in.h:17 -#| msgid "_Display conversation preview" msgid "Geary displaying a conversation" msgstr "Geary exibindo uma conversa" @@ -109,6 +109,7 @@ msgstr "Geary mostrando um compositor de texto rico" #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "E-mail" @@ -125,11 +126,6 @@ msgid "Compose Message" msgstr "Escrever mensagem" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Cliente de e-mail" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Correio eletrônico - Geary" @@ -277,11 +273,16 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Copyright 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +#| msgid "Geary Development Team" +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Copyright 2016-2017 Equipe de Desenvolvimento do Geary." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Visite o website do Geary" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "Sobre %s" @@ -289,7 +290,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Leonardo Lemos \n" @@ -365,17 +366,17 @@ msgid "Use %s to open a new composer window" msgstr "Use %s para abrir uma nova janela do compositor" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Por favor, envie sugestões, comentários ou erros para:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Falha ao analisar as opções de linha de comando: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Opção de linha de comando não reconhecida “%s”\n" @@ -2674,6 +2675,9 @@ msgid "Geary update in progress…" msgstr "Atualização do Geary em progresso…" +#~ msgid "Mail Client" +#~ msgstr "Cliente de e-mail" + #~ msgid "none" #~ msgstr "nenhum" diff -Nru geary-0.12.0/po/ru.po geary-0.12.4/po/ru.po --- geary-0.12.0/po/ru.po 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/po/ru.po 2018-08-29 13:57:20.000000000 +0000 @@ -16,8 +16,8 @@ "Project-Id-Version: geary-0.4.1\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" "product=geary&keywords=I18N+L10N&component=internationalization\n" -"POT-Creation-Date: 2017-04-21 22:33+0000\n" -"PO-Revision-Date: 2017-04-22 01:42+0300\n" +"POT-Creation-Date: 2017-12-15 10:48+0000\n" +"PO-Revision-Date: 2018-04-12 22:48+0300\n" "Last-Translator: Stas Solovey \n" "Language-Team: Русский \n" "Language: ru\n" @@ -26,21 +26,29 @@ "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Poedit 2.0.1\n" +"X-Generator: Poedit 2.0.6\n" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:1 +#. Translators: The application name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 #: ../desktop/org.gnome.Geary.desktop.in.h:1 #: ../desktop/geary-autostart.desktop.in.h:1 msgid "Geary" msgstr "Geary" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 +#. Translators: The development team's name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +msgid "Geary Development Team" +msgstr "Команда разработчиков Geary" + +#. Translators: The application's summary / tagline +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Отправка и получение электронной почты" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:3 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 msgid "" "Geary is an email application built around conversations, for the GNOME 3 " "desktop. It allows you to read, find and send email with a straightforward, " @@ -50,7 +58,7 @@ "по принципу обмена сообщениями — беседами. Позволяет читать, находить и " "отправлять электронную почту с простым, современным интерфейсом." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 msgid "" "Conversations allow you to read a complete discussion without having to find " "and click from message to message." @@ -58,37 +66,48 @@ "Беседы позволяют читать переписку целиком без необходимости искать и " "переходить от сообщения к сообщению." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:5 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 msgid "Geary’s features include:" msgstr "К функциям Geary относятся:" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 msgid "Quick email account setup" msgstr "Быстрая настройка учётной записи электронной почты" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 msgid "Shows related messages together in conversations" msgstr "Отображение связанных сообщений в режиме беседы" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:12 msgid "Fast, full text and keyword search" msgstr "Быстрый полнотекстовый поиск и поиск по ключевым словам" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:13 msgid "Full-featured HTML and plain text message composer" msgstr "" "Полнофункциональный режим составления писем в виде простого текста, а также " "с HTML разметкой" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:14 msgid "Desktop notification of new mail" msgstr "Уведомления о новых сообщениях" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:15 msgid "Compatible with GMail, Yahoo! Mail, Outlook.com and other IMAP servers" msgstr "Совместим с GMail, Yahoo! Mail, Outlook.com и другими IMAP серверами" +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:17 +msgid "Geary displaying a conversation" +msgstr "Интерфейс обмена сообщениями Geary" + +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:19 +msgid "Geary showing the rich text composer" +msgstr "Интерфейс редактирования текста Geary" + #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "Электронная почта" @@ -105,11 +124,6 @@ msgid "Compose Message" msgstr "Новое сообщение" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Почтовый клиент" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Почтовый клиент Geary" @@ -257,11 +271,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Авторское право © 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Авторское право © 016-2017 Geary Development Team." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Посетить веб-сайт Geary" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "О %s" @@ -269,9 +287,9 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" -msgstr "Stas Solovey , 2015-2017" +msgstr "Stas Solovey , 2015-2017." #: ../src/client/application/geary-args.vala:10 msgid "Start Geary with hidden main window" @@ -341,17 +359,17 @@ msgid "Use %s to open a new composer window" msgstr "Используйте %s для открытия нового окна редактора" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Комментарии, пожелания и найденные ошибки отправляйте:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Не удалось разобрать параметры командной строки: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Неизвестный параметр командной строки «%s»\n" @@ -680,15 +698,15 @@ "\n" "Проверьте подключение к сети и перезапустите Geary." -#: ../src/client/application/geary-controller.vala:1999 +#: ../src/client/application/geary-controller.vala:2010 msgid "Undo move (Ctrl+Z)" msgstr "Отменить перемещение (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2009 +#: ../src/client/application/geary-controller.vala:2020 msgid "Are you sure you want to open these attachments?" msgstr "Действительно хотите открыть эти вложения?" -#: ../src/client/application/geary-controller.vala:2010 +#: ../src/client/application/geary-controller.vala:2021 msgid "" "Attachments may cause damage to your system if opened. Only open files from " "trusted sources." @@ -696,16 +714,16 @@ "Вложения при открытии могут нанести ущерб системе. Открывайте вложения " "только от надёжных источников." -#: ../src/client/application/geary-controller.vala:2011 +#: ../src/client/application/geary-controller.vala:2022 msgid "Don’t _ask me again" msgstr "Не _спрашивать снова" -#: ../src/client/application/geary-controller.vala:2121 +#: ../src/client/application/geary-controller.vala:2126 #, c-format msgid "A file named “%s” already exists. Do you want to replace it?" msgstr "Файл с именем «%s» уже существует. Заменить его?" -#: ../src/client/application/geary-controller.vala:2123 +#: ../src/client/application/geary-controller.vala:2128 #, c-format msgid "" "The file already exists in “%s”. Replacing it will overwrite its contents." @@ -713,63 +731,63 @@ "Файл уже существует в «%s». Его замена приведёт к полной перезаписи его " "содержимого." -#: ../src/client/application/geary-controller.vala:2126 +#: ../src/client/application/geary-controller.vala:2131 msgid "_Replace" msgstr "_Заменить" #. Find out what to do with the inline composers. #. TODO: Remove this in favor of automatically saving drafts -#: ../src/client/application/geary-controller.vala:2374 +#: ../src/client/application/geary-controller.vala:2379 msgid "Close open draft messages?" msgstr "Закрыть черновик?" -#: ../src/client/application/geary-controller.vala:2496 +#: ../src/client/application/geary-controller.vala:2501 #, c-format msgid "Empty all email from your %s folder?" msgstr "Очистить все письма папки %s?" -#: ../src/client/application/geary-controller.vala:2497 +#: ../src/client/application/geary-controller.vala:2502 msgid "This removes the email from Geary and your email server." msgstr "Удаляет все письма из Geary и почтового сервера." -#: ../src/client/application/geary-controller.vala:2498 +#: ../src/client/application/geary-controller.vala:2503 msgid "This cannot be undone." msgstr "Это не может быть отменено." -#: ../src/client/application/geary-controller.vala:2499 +#: ../src/client/application/geary-controller.vala:2504 #, c-format msgid "Empty %s" msgstr "Очистить %s" -#: ../src/client/application/geary-controller.vala:2516 +#: ../src/client/application/geary-controller.vala:2521 #, c-format msgid "Error emptying %s" msgstr "Ошибка очистки %s" -#: ../src/client/application/geary-controller.vala:2546 +#: ../src/client/application/geary-controller.vala:2551 msgid "Do you want to permanently delete this message?" msgid_plural "Do you want to permanently delete these messages?" msgstr[0] "Безвозвратно удалить это сообщение?" msgstr[1] "Безвозвратно удалить эти сообщения?" msgstr[2] "Безвозвратно удалить эти сообщения?" -#: ../src/client/application/geary-controller.vala:2548 +#: ../src/client/application/geary-controller.vala:2553 msgid "Delete" msgstr "_Удалить" -#: ../src/client/application/geary-controller.vala:2580 +#: ../src/client/application/geary-controller.vala:2585 msgid "Undo archive (Ctrl+Z)" msgstr "Отменить архивирование (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2595 +#: ../src/client/application/geary-controller.vala:2600 msgid "Undo trash (Ctrl+Z)" msgstr "Отменить перемещение в корзину (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2649 +#: ../src/client/application/geary-controller.vala:2654 msgid "Undo (Ctrl+Z)" msgstr "Отменить (Ctrl+Z)" -#: ../src/client/application/geary-controller.vala:2780 +#: ../src/client/application/geary-controller.vala:2785 msgid "Failed to open default text editor." msgstr "Не удалось запустить текстовый редактор по-умолчанию." @@ -900,28 +918,28 @@ "прикрепить|прикрепление|прикрепления|прикреплён|прикреплены|вложение|" "вложенные|вложения" -#: ../src/client/composer/composer-widget.vala:1122 -#: ../src/client/composer/composer-widget.vala:1141 +#: ../src/client/composer/composer-widget.vala:1129 +#: ../src/client/composer/composer-widget.vala:1148 msgid "Do you want to discard this message?" msgstr "Отказаться от этого сообщения?" -#: ../src/client/composer/composer-widget.vala:1245 +#: ../src/client/composer/composer-widget.vala:1252 msgid "Send message with an empty subject and body?" msgstr "Отправить сообщение с пустой темой и без текста?" -#: ../src/client/composer/composer-widget.vala:1247 +#: ../src/client/composer/composer-widget.vala:1254 msgid "Send message with an empty subject?" msgstr "Отправить сообщение с пустой темой?" -#: ../src/client/composer/composer-widget.vala:1249 +#: ../src/client/composer/composer-widget.vala:1256 msgid "Send message with an empty body?" msgstr "Отправить сообщение без текста?" -#: ../src/client/composer/composer-widget.vala:1253 +#: ../src/client/composer/composer-widget.vala:1260 msgid "Send message without an attachment?" msgstr "Отправить сообщение без прикреплённых файлов?" -#: ../src/client/composer/composer-widget.vala:1515 +#: ../src/client/composer/composer-widget.vala:1522 #, c-format msgid "“%s” already attached for delivery." msgstr "«%s» уже вложено в письмо." @@ -931,73 +949,73 @@ #. description of the document type, the second will #. be a human-friendly size string. For example: #. Document (100.9MB) -#: ../src/client/composer/composer-widget.vala:1523 +#: ../src/client/composer/composer-widget.vala:1530 #: ../src/client/conversation-viewer/conversation-email.vala:138 #, c-format msgid "%s (%s)" msgstr "%s (%s)" -#: ../src/client/composer/composer-widget.vala:1560 +#: ../src/client/composer/composer-widget.vala:1567 #, c-format msgid "“%s” could not be found." msgstr "Невозможно найти «%s»." -#: ../src/client/composer/composer-widget.vala:1566 +#: ../src/client/composer/composer-widget.vala:1573 #, c-format msgid "“%s” is a folder." msgstr "«%s» является каталогом." -#: ../src/client/composer/composer-widget.vala:1572 +#: ../src/client/composer/composer-widget.vala:1579 #, c-format msgid "“%s” is an empty file." msgstr "«%s» — пустой файл." -#: ../src/client/composer/composer-widget.vala:1585 +#: ../src/client/composer/composer-widget.vala:1592 #, c-format msgid "“%s” could not be opened for reading." msgstr "Невозможно открыть для чтения «%s»." -#: ../src/client/composer/composer-widget.vala:1593 +#: ../src/client/composer/composer-widget.vala:1600 msgid "Cannot add attachment" msgstr "Невозможно добавить вложение" -#: ../src/client/composer/composer-widget.vala:1645 +#: ../src/client/composer/composer-widget.vala:1652 msgid "To: " msgstr "Кому: " -#: ../src/client/composer/composer-widget.vala:1648 +#: ../src/client/composer/composer-widget.vala:1655 msgid "Cc: " msgstr "Копия: " -#: ../src/client/composer/composer-widget.vala:1651 +#: ../src/client/composer/composer-widget.vala:1658 msgid "Bcc: " msgstr "Скрытая копия: " -#: ../src/client/composer/composer-widget.vala:1654 +#: ../src/client/composer/composer-widget.vala:1661 msgid "Reply-To: " msgstr "Ответить: " -#: ../src/client/composer/composer-widget.vala:1786 +#: ../src/client/composer/composer-widget.vala:1793 msgid "Select Color" msgstr "Выбрать цвет" #. Displayed in the From dropdown to indicate an "alternate email address" #. for an account. The first printf argument will be the alternate email #. address, and the second will be the account's primary email address. -#: ../src/client/composer/composer-widget.vala:1986 +#: ../src/client/composer/composer-widget.vala:1993 #, c-format msgid "%1$s via %2$s" msgstr "%1$s через %2$s" #. Composer label (with mnemonic underscore) for the account selector #. when choosing what address to send a message from. -#: ../src/client/composer/composer-widget.vala:2028 +#: ../src/client/composer/composer-widget.vala:2035 msgid "_From:" msgstr "_От:" #. Translators: This is the name of the file chooser filter #. when inserting an image in the composer. -#: ../src/client/composer/composer-widget.vala:2252 +#: ../src/client/composer/composer-widget.vala:2259 msgid "Images" msgstr "Изображения" @@ -1032,14 +1050,14 @@ #. Translators: This separates multiple 'from' #. addresses in the header preview for a message. -#: ../src/client/conversation-viewer/conversation-message.vala:586 +#: ../src/client/conversation-viewer/conversation-message.vala:585 msgid ", " msgstr ", " #. Translators: This string is used as the HTML IMG ALT #. attribute value when displaying an inline image in an email #. that did not specify a file name. E.g. Image\n" "Language-Team: Slovak (http://www.transifex.com/projects/p/geary/language/" "sk/)\n" @@ -38,7 +38,7 @@ #: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 -#: ../src/client/application/geary-application.vala:22 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Odosiela a prijíma emaily" @@ -261,15 +261,20 @@ msgid " • Username or password incorrect.\n" msgstr " • Používateľské meno alebo heslo je nesprávne.\n" -#: ../src/client/application/geary-application.vala:21 +#: ../src/client/application/geary-application.vala:22 msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Autorské práva 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +#| msgid "Geary Development Team" +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Autorské práva 2016-2017 Tím vývojárov aplikácie Geary." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Navštívte webovú stránku aplikácie Geary" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "O %s" @@ -277,7 +282,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "Dušan Kazik " @@ -351,17 +356,17 @@ msgid "Use %s to open a new composer window" msgstr "Použite %s na otvorenie nového okna tvorcu správy" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Prosím, pridajte komentáre, nápady a chyby na:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Zlyhalo analyzovanie volieb príkazového riadka: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Nerozpoznaná voľba príkazového riadku „%s“\n" diff -Nru geary-0.12.0/po/sr@latin.po geary-0.12.4/po/sr@latin.po --- geary-0.12.0/po/sr@latin.po 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/po/sr@latin.po 2018-08-29 13:57:20.000000000 +0000 @@ -1,40 +1,48 @@ # Serbian translation of Geary email client -# Courtesy of Prevod.org team (http://prevod.org/) -- 2012—2017. +# Courtesy of Prevod.org team (http://prevod.org/) -- 2012—2018. # Copyright 2016 Software Freedom Conservancy Inc. # This file is distributed under the GNU LGPL, version 2.1. # igorpan , 2012 -# Miroslav Nikolić , 2014—2017. +# Miroslav Nikolić , 2014—2018. # Miloš Popović , 2015. msgid "" msgstr "" "Project-Id-Version: geary\n" -"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" -"product=geary&keywords=I18N+L10N&component=internationalization\n" -"POT-Creation-Date: 2017-02-26 06:52+0000\n" -"PO-Revision-Date: 2017-02-26 09:25+0200\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=geary&" +"keywords=I18N+L10N&component=internationalization\n" +"POT-Creation-Date: 2017-11-16 05:25+0000\n" +"PO-Revision-Date: 2018-03-03 08:12+0200\n" "Last-Translator: Miroslav Nikolić \n" -"Language-Team: Serbian <(nothing)>\n" +"Language-Team: srpski \n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n" -"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " +"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Project-Style: gnome\n" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:1 +#. Translators: The application name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 #: ../desktop/org.gnome.Geary.desktop.in.h:1 #: ../desktop/geary-autostart.desktop.in.h:1 msgid "Geary" msgstr "Geri" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 +#. Translators: The development team's name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +msgid "Geary Development Team" +msgstr "Razvojni tim Gerija" + +#. Translators: The application's summary / tagline +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Šalje i prima e-poštu" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:3 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 msgid "" "Geary is an email application built around conversations, for the GNOME 3 " "desktop. It allows you to read, find and send email with a straightforward, " @@ -44,7 +52,7 @@ "Omogućuje vam da čitate, nađete i šaljete e-poštu sa jasnim, savremenim " "sučeljem." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 msgid "" "Conversations allow you to read a complete discussion without having to find " "and click from message to message." @@ -52,36 +60,48 @@ "Razgovori vam omogućavaju da pročitate čitav razgovor a da ne morate da " "tražite i klikate od poruke do poruke." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:5 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 msgid "Geary’s features include:" msgstr "U Gerijeve funkcije spadaju:" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 msgid "Quick email account setup" msgstr "Brzo podešavanje naloga e-pošte" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 msgid "Shows related messages together in conversations" msgstr "Zajednički prikaz povezanih poruka u razgovoru" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:12 msgid "Fast, full text and keyword search" msgstr "Brza pretraga po čitavom tekstu i ključnoj reči" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:13 msgid "Full-featured HTML and plain text message composer" msgstr "Potpuno funkcionalan sastavljač poruke u HTML-u i običnom tekstu" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:14 msgid "Desktop notification of new mail" msgstr "Obaveštenje o novoj pošti na radnoj površi" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:15 msgid "Compatible with GMail, Yahoo! Mail, Outlook.com and other IMAP servers" msgstr "" "Saglasan je sa G-poštom, Jahu! poštom, Autlukom i drugim IMAP serverima" +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:17 +#| msgid "_Display conversation preview" +msgid "Geary displaying a conversation" +msgstr "Geri prikazuje razgovor" + +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:19 +msgid "Geary showing the rich text composer" +msgstr "Geri prikazuje sastavljač opširnog teksta" + #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "E-pošta" @@ -98,11 +118,6 @@ msgid "Compose Message" msgstr "Nova poruka" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Program za e-poštu" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Gerijeva pošta" @@ -250,11 +265,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Autorska prava 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Autorska prava 2016-2017 razvojni tim Gerija." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Posetite veb stranicu Gerija" -#: ../src/client/application/geary-application.vala:445 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "O programu „%s“" @@ -262,7 +281,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:449 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Miroslav Nikolić \n" @@ -338,17 +357,17 @@ msgid "Use %s to open a new composer window" msgstr "Koristite „%s“ za otvaranje novog prozora sastavljača" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Napomene, predloge i greške šaljite na:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Ne mogu da obradim opciju linije naredbi: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Nepoznata opcija linije naredbi „%s“\n" @@ -678,15 +697,15 @@ "\n" "Proverite vašu mrežu i ponovo pokrenite Gerija." -#: ../src/client/application/geary-controller.vala:1998 +#: ../src/client/application/geary-controller.vala:2008 msgid "Undo move (Ctrl+Z)" msgstr "Opozovi (Ktrl+Z)" -#: ../src/client/application/geary-controller.vala:2008 +#: ../src/client/application/geary-controller.vala:2018 msgid "Are you sure you want to open these attachments?" msgstr "Da li sigurno želite da otvorite ove priloge?" -#: ../src/client/application/geary-controller.vala:2009 +#: ../src/client/application/geary-controller.vala:2019 msgid "" "Attachments may cause damage to your system if opened. Only open files from " "trusted sources." @@ -694,56 +713,56 @@ "Priložene datoteke mogu da oštete sistem ako se otvore. Otvorite datoteke " "samo sa poverljivih izvora." -#: ../src/client/application/geary-controller.vala:2010 +#: ../src/client/application/geary-controller.vala:2020 msgid "Don’t _ask me again" msgstr "Ne pitaj me _ponovo" -#: ../src/client/application/geary-controller.vala:2145 +#: ../src/client/application/geary-controller.vala:2130 #, c-format msgid "A file named “%s” already exists. Do you want to replace it?" msgstr "Datoteka pod nazivom „%s“ već postoji. Da li želite da je zamenite?" -#: ../src/client/application/geary-controller.vala:2147 +#: ../src/client/application/geary-controller.vala:2132 #, c-format msgid "" "The file already exists in “%s”. Replacing it will overwrite its contents." msgstr "" "Datoteka već postoji u „%s“. Ukoliko je zamenite prepisaćete njen sadržaj." -#: ../src/client/application/geary-controller.vala:2150 +#: ../src/client/application/geary-controller.vala:2135 msgid "_Replace" msgstr "_Zameni" #. Find out what to do with the inline composers. #. TODO: Remove this in favor of automatically saving drafts -#: ../src/client/application/geary-controller.vala:2398 +#: ../src/client/application/geary-controller.vala:2383 msgid "Close open draft messages?" msgstr "Da zatvorim otvorene poruke s nacrtima?" -#: ../src/client/application/geary-controller.vala:2520 +#: ../src/client/application/geary-controller.vala:2505 #, c-format msgid "Empty all email from your %s folder?" msgstr "Da ispraznim e-poštu iz fascikle „%s“?" -#: ../src/client/application/geary-controller.vala:2521 +#: ../src/client/application/geary-controller.vala:2506 msgid "This removes the email from Geary and your email server." msgstr "Ovo će ukloniti poštu iz Gerija i na serverima vaše e-pošte." -#: ../src/client/application/geary-controller.vala:2522 +#: ../src/client/application/geary-controller.vala:2507 msgid "This cannot be undone." msgstr "Ne možete da opozovete ovu radnju." -#: ../src/client/application/geary-controller.vala:2523 +#: ../src/client/application/geary-controller.vala:2508 #, c-format msgid "Empty %s" msgstr "Isprazni „%s“" -#: ../src/client/application/geary-controller.vala:2540 +#: ../src/client/application/geary-controller.vala:2525 #, c-format msgid "Error emptying %s" msgstr "Greška prilikom pražnjenja „%s“" -#: ../src/client/application/geary-controller.vala:2570 +#: ../src/client/application/geary-controller.vala:2555 msgid "Do you want to permanently delete this message?" msgid_plural "Do you want to permanently delete these messages?" msgstr[0] "Da li želite trajno da obrišete ovu poruku?" @@ -751,23 +770,23 @@ msgstr[2] "Da li želite trajno da obrišete ove poruke?" msgstr[3] "Da li želite trajno da obrišete ovu poruku?" -#: ../src/client/application/geary-controller.vala:2572 +#: ../src/client/application/geary-controller.vala:2557 msgid "Delete" msgstr "Obriši" -#: ../src/client/application/geary-controller.vala:2604 +#: ../src/client/application/geary-controller.vala:2589 msgid "Undo archive (Ctrl+Z)" msgstr "Opozovi arhiviranje (Ktrl+Z)" -#: ../src/client/application/geary-controller.vala:2619 +#: ../src/client/application/geary-controller.vala:2604 msgid "Undo trash (Ctrl+Z)" msgstr "Opozovi brisanje (Ktrl+Z)" -#: ../src/client/application/geary-controller.vala:2673 +#: ../src/client/application/geary-controller.vala:2658 msgid "Undo (Ctrl+Z)" msgstr "Opozovi (Ktrl+Z)" -#: ../src/client/application/geary-controller.vala:2804 +#: ../src/client/application/geary-controller.vala:2789 msgid "Failed to open default text editor." msgstr "Ne mogu da otvorim podrazumevani urednik teksta." @@ -894,28 +913,28 @@ "enclosing|encloses|enclosure|enclosures" msgstr "prilog|priloži|prilogu|prilažem|prilaganja|prilozi|priloženo" -#: ../src/client/composer/composer-widget.vala:1121 -#: ../src/client/composer/composer-widget.vala:1140 +#: ../src/client/composer/composer-widget.vala:1122 +#: ../src/client/composer/composer-widget.vala:1141 msgid "Do you want to discard this message?" msgstr "Da li želite da odbacite ovu poruku?" -#: ../src/client/composer/composer-widget.vala:1237 +#: ../src/client/composer/composer-widget.vala:1245 msgid "Send message with an empty subject and body?" msgstr "Da pošaljem poruku sa praznim naslovom i tekstom?" -#: ../src/client/composer/composer-widget.vala:1239 +#: ../src/client/composer/composer-widget.vala:1247 msgid "Send message with an empty subject?" msgstr "Da pošaljem poruku sa praznim naslovom?" -#: ../src/client/composer/composer-widget.vala:1241 +#: ../src/client/composer/composer-widget.vala:1249 msgid "Send message with an empty body?" msgstr "Da pošaljem poruku bez ikakvog teksta?" -#: ../src/client/composer/composer-widget.vala:1245 +#: ../src/client/composer/composer-widget.vala:1253 msgid "Send message without an attachment?" msgstr "Da pošaljem poruku bez priloga?" -#: ../src/client/composer/composer-widget.vala:1498 +#: ../src/client/composer/composer-widget.vala:1515 #, c-format msgid "“%s” already attached for delivery." msgstr "„%s“ je već priloženo za isporuku." @@ -925,73 +944,73 @@ #. description of the document type, the second will #. be a human-friendly size string. For example: #. Document (100.9MB) -#: ../src/client/composer/composer-widget.vala:1506 +#: ../src/client/composer/composer-widget.vala:1523 #: ../src/client/conversation-viewer/conversation-email.vala:138 #, c-format msgid "%s (%s)" msgstr "%s (%s)" -#: ../src/client/composer/composer-widget.vala:1543 +#: ../src/client/composer/composer-widget.vala:1560 #, c-format msgid "“%s” could not be found." msgstr "Ne mogu da pronađem „%s“." -#: ../src/client/composer/composer-widget.vala:1549 +#: ../src/client/composer/composer-widget.vala:1566 #, c-format msgid "“%s” is a folder." msgstr "„%s“ je fascikla." -#: ../src/client/composer/composer-widget.vala:1555 +#: ../src/client/composer/composer-widget.vala:1572 #, c-format msgid "“%s” is an empty file." msgstr "„%s“ je prazna datoteka." -#: ../src/client/composer/composer-widget.vala:1568 +#: ../src/client/composer/composer-widget.vala:1585 #, c-format msgid "“%s” could not be opened for reading." msgstr "Ne mogu da otvorim „%s“ za čitanje." -#: ../src/client/composer/composer-widget.vala:1576 +#: ../src/client/composer/composer-widget.vala:1593 msgid "Cannot add attachment" msgstr "Ne mogu da dodam prilog" -#: ../src/client/composer/composer-widget.vala:1638 +#: ../src/client/composer/composer-widget.vala:1645 msgid "To: " msgstr "Prima: " -#: ../src/client/composer/composer-widget.vala:1641 +#: ../src/client/composer/composer-widget.vala:1648 msgid "Cc: " msgstr "Cc: " -#: ../src/client/composer/composer-widget.vala:1644 +#: ../src/client/composer/composer-widget.vala:1651 msgid "Bcc: " msgstr "Bcc: " -#: ../src/client/composer/composer-widget.vala:1647 +#: ../src/client/composer/composer-widget.vala:1654 msgid "Reply-To: " msgstr "Odgovor za: " -#: ../src/client/composer/composer-widget.vala:1778 +#: ../src/client/composer/composer-widget.vala:1786 msgid "Select Color" msgstr "Izaberite boju" #. Displayed in the From dropdown to indicate an "alternate email address" #. for an account. The first printf argument will be the alternate email #. address, and the second will be the account's primary email address. -#: ../src/client/composer/composer-widget.vala:1978 +#: ../src/client/composer/composer-widget.vala:1986 #, c-format msgid "%1$s via %2$s" msgstr "%1$s preko %2$s" #. Composer label (with mnemonic underscore) for the account selector #. when choosing what address to send a message from. -#: ../src/client/composer/composer-widget.vala:2020 +#: ../src/client/composer/composer-widget.vala:2028 msgid "_From:" msgstr "_Šalje:" #. Translators: This is the name of the file chooser filter #. when inserting an image in the composer. -#: ../src/client/composer/composer-widget.vala:2244 +#: ../src/client/composer/composer-widget.vala:2252 msgid "Images" msgstr "Slike" @@ -1034,36 +1053,35 @@ #. attribute value when displaying an inline image in an email #. that did not specify a file name. E.g. Image, 2012 -# Мирослав Николић , 2014—2017. +# Мирослав Николић , 2014—2018. # Милош Поповић , 2015. msgid "" msgstr "" "Project-Id-Version: geary\n" -"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" -"product=geary&keywords=I18N+L10N&component=internationalization\n" -"POT-Creation-Date: 2017-02-26 06:52+0000\n" -"PO-Revision-Date: 2017-02-26 09:25+0200\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=geary&" +"keywords=I18N+L10N&component=internationalization\n" +"POT-Creation-Date: 2017-11-16 05:25+0000\n" +"PO-Revision-Date: 2018-03-03 08:12+0200\n" "Last-Translator: Мирослав Николић \n" -"Language-Team: Serbian <(nothing)>\n" +"Language-Team: српски \n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n" -"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " +"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Project-Style: gnome\n" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:1 +#. Translators: The application name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 #: ../desktop/org.gnome.Geary.desktop.in.h:1 #: ../desktop/geary-autostart.desktop.in.h:1 msgid "Geary" msgstr "Гери" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 +#. Translators: The development team's name +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +msgid "Geary Development Team" +msgstr "Развојни тим Герија" + +#. Translators: The application's summary / tagline +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Шаље и прима е-пошту" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:3 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 msgid "" "Geary is an email application built around conversations, for the GNOME 3 " "desktop. It allows you to read, find and send email with a straightforward, " @@ -44,7 +52,7 @@ "Омогућује вам да читате, нађете и шаљете е-пошту са јасним, савременим " "сучељем." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:4 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 msgid "" "Conversations allow you to read a complete discussion without having to find " "and click from message to message." @@ -52,36 +60,48 @@ "Разговори вам омогућавају да прочитате читав разговор а да не морате да " "тражите и кликате од поруке до поруке." -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:5 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 msgid "Geary’s features include:" msgstr "У Геријеве функције спадају:" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 msgid "Quick email account setup" msgstr "Брзо подешавање налога е-поште" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:7 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 msgid "Shows related messages together in conversations" msgstr "Заједнички приказ повезаних порука у разговору" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:8 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:12 msgid "Fast, full text and keyword search" msgstr "Брза претрага по читавом тексту и кључној речи" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:9 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:13 msgid "Full-featured HTML and plain text message composer" msgstr "Потпуно функционалан састављач поруке у ХТМЛ-у и обичном тексту" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:10 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:14 msgid "Desktop notification of new mail" msgstr "Обавештење о новој пошти на радној површи" -#: ../desktop/org.gnome.Geary.appdata.xml.in.h:11 +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:15 msgid "Compatible with GMail, Yahoo! Mail, Outlook.com and other IMAP servers" msgstr "" "Сагласан је са Г-поштом, Јаху! поштом, Аутлуком и другим ИМАП серверима" +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:17 +#| msgid "_Display conversation preview" +msgid "Geary displaying a conversation" +msgstr "Гери приказује разговор" + +#. Translators: A screenshot description. +#: ../desktop/org.gnome.Geary.appdata.xml.in.h:19 +msgid "Geary showing the rich text composer" +msgstr "Гери приказује састављач опширног текста" + #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "Е-пошта" @@ -98,11 +118,6 @@ msgid "Compose Message" msgstr "Нова порука" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "Програм за е-пошту" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Геријева пошта" @@ -250,11 +265,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Ауторска права 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Ауторска права 2016-2017 развојни тим Герија." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Посетите веб страницу Герија" -#: ../src/client/application/geary-application.vala:445 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "О програму „%s“" @@ -262,7 +281,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:449 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Мирослав Николић \n" @@ -338,17 +357,17 @@ msgid "Use %s to open a new composer window" msgstr "Користите „%s“ за отварање новог прозора састављача" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Напомене, предлоге и грешке шаљите на:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Не могу да обрадим опцију линије наредби: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Непозната опција линије наредби „%s“\n" @@ -678,15 +697,15 @@ "\n" "Проверите вашу мрежу и поново покрените Герија." -#: ../src/client/application/geary-controller.vala:1998 +#: ../src/client/application/geary-controller.vala:2008 msgid "Undo move (Ctrl+Z)" msgstr "Опозови (Ктрл+Z)" -#: ../src/client/application/geary-controller.vala:2008 +#: ../src/client/application/geary-controller.vala:2018 msgid "Are you sure you want to open these attachments?" msgstr "Да ли сигурнo желите да отворите ове прилоге?" -#: ../src/client/application/geary-controller.vala:2009 +#: ../src/client/application/geary-controller.vala:2019 msgid "" "Attachments may cause damage to your system if opened. Only open files from " "trusted sources." @@ -694,56 +713,56 @@ "Приложене датотеке могу да оштете систем ако се отворе. Отворите датотеке " "само са поверљивих извора." -#: ../src/client/application/geary-controller.vala:2010 +#: ../src/client/application/geary-controller.vala:2020 msgid "Don’t _ask me again" msgstr "Не питај ме _поново" -#: ../src/client/application/geary-controller.vala:2145 +#: ../src/client/application/geary-controller.vala:2130 #, c-format msgid "A file named “%s” already exists. Do you want to replace it?" msgstr "Датотека под називом „%s“ већ постоји. Да ли желите да је замените?" -#: ../src/client/application/geary-controller.vala:2147 +#: ../src/client/application/geary-controller.vala:2132 #, c-format msgid "" "The file already exists in “%s”. Replacing it will overwrite its contents." msgstr "" "Датотека већ постоји у „%s“. Уколико је замените преписаћете њен садржај." -#: ../src/client/application/geary-controller.vala:2150 +#: ../src/client/application/geary-controller.vala:2135 msgid "_Replace" msgstr "_Замени" #. Find out what to do with the inline composers. #. TODO: Remove this in favor of automatically saving drafts -#: ../src/client/application/geary-controller.vala:2398 +#: ../src/client/application/geary-controller.vala:2383 msgid "Close open draft messages?" msgstr "Да затворим отворене поруке с нацртима?" -#: ../src/client/application/geary-controller.vala:2520 +#: ../src/client/application/geary-controller.vala:2505 #, c-format msgid "Empty all email from your %s folder?" msgstr "Да испразним е-пошту из фасцикле „%s“?" -#: ../src/client/application/geary-controller.vala:2521 +#: ../src/client/application/geary-controller.vala:2506 msgid "This removes the email from Geary and your email server." msgstr "Ово ће уклонити пошту из Герија и на серверима ваше е-поште." -#: ../src/client/application/geary-controller.vala:2522 +#: ../src/client/application/geary-controller.vala:2507 msgid "This cannot be undone." msgstr "Не можете да опозовете ову радњу." -#: ../src/client/application/geary-controller.vala:2523 +#: ../src/client/application/geary-controller.vala:2508 #, c-format msgid "Empty %s" msgstr "Испразни „%s“" -#: ../src/client/application/geary-controller.vala:2540 +#: ../src/client/application/geary-controller.vala:2525 #, c-format msgid "Error emptying %s" msgstr "Грешка приликом пражњења „%s“" -#: ../src/client/application/geary-controller.vala:2570 +#: ../src/client/application/geary-controller.vala:2555 msgid "Do you want to permanently delete this message?" msgid_plural "Do you want to permanently delete these messages?" msgstr[0] "Да ли желите трајно да обришете ову поруку?" @@ -751,23 +770,23 @@ msgstr[2] "Да ли желите трајно да обришете ове поруке?" msgstr[3] "Да ли желите трајно да обришете ову поруку?" -#: ../src/client/application/geary-controller.vala:2572 +#: ../src/client/application/geary-controller.vala:2557 msgid "Delete" msgstr "Обриши" -#: ../src/client/application/geary-controller.vala:2604 +#: ../src/client/application/geary-controller.vala:2589 msgid "Undo archive (Ctrl+Z)" msgstr "Опозови архивирање (Ктрл+Z)" -#: ../src/client/application/geary-controller.vala:2619 +#: ../src/client/application/geary-controller.vala:2604 msgid "Undo trash (Ctrl+Z)" msgstr "Опозови брисање (Ктрл+Z)" -#: ../src/client/application/geary-controller.vala:2673 +#: ../src/client/application/geary-controller.vala:2658 msgid "Undo (Ctrl+Z)" msgstr "Опозови (Ктрл+Z)" -#: ../src/client/application/geary-controller.vala:2804 +#: ../src/client/application/geary-controller.vala:2789 msgid "Failed to open default text editor." msgstr "Не могу да отворим подразумевани уредник текста." @@ -894,28 +913,28 @@ "enclosing|encloses|enclosure|enclosures" msgstr "прилог|приложи|прилогу|прилажем|прилагања|прилози|приложено" -#: ../src/client/composer/composer-widget.vala:1121 -#: ../src/client/composer/composer-widget.vala:1140 +#: ../src/client/composer/composer-widget.vala:1122 +#: ../src/client/composer/composer-widget.vala:1141 msgid "Do you want to discard this message?" msgstr "Да ли желите да одбаците ову поруку?" -#: ../src/client/composer/composer-widget.vala:1237 +#: ../src/client/composer/composer-widget.vala:1245 msgid "Send message with an empty subject and body?" msgstr "Да пошаљем поруку са празним насловом и текстом?" -#: ../src/client/composer/composer-widget.vala:1239 +#: ../src/client/composer/composer-widget.vala:1247 msgid "Send message with an empty subject?" msgstr "Да пошаљем поруку са празним насловом?" -#: ../src/client/composer/composer-widget.vala:1241 +#: ../src/client/composer/composer-widget.vala:1249 msgid "Send message with an empty body?" msgstr "Да пошаљем поруку без икаквог текста?" -#: ../src/client/composer/composer-widget.vala:1245 +#: ../src/client/composer/composer-widget.vala:1253 msgid "Send message without an attachment?" msgstr "Да пошаљем поруку без прилога?" -#: ../src/client/composer/composer-widget.vala:1498 +#: ../src/client/composer/composer-widget.vala:1515 #, c-format msgid "“%s” already attached for delivery." msgstr "„%s“ је већ приложено за испоруку." @@ -925,73 +944,73 @@ #. description of the document type, the second will #. be a human-friendly size string. For example: #. Document (100.9MB) -#: ../src/client/composer/composer-widget.vala:1506 +#: ../src/client/composer/composer-widget.vala:1523 #: ../src/client/conversation-viewer/conversation-email.vala:138 #, c-format msgid "%s (%s)" msgstr "%s (%s)" -#: ../src/client/composer/composer-widget.vala:1543 +#: ../src/client/composer/composer-widget.vala:1560 #, c-format msgid "“%s” could not be found." msgstr "Не могу да пронађем „%s“." -#: ../src/client/composer/composer-widget.vala:1549 +#: ../src/client/composer/composer-widget.vala:1566 #, c-format msgid "“%s” is a folder." msgstr "„%s“ је фасцикла." -#: ../src/client/composer/composer-widget.vala:1555 +#: ../src/client/composer/composer-widget.vala:1572 #, c-format msgid "“%s” is an empty file." msgstr "„%s“ је празна датотека." -#: ../src/client/composer/composer-widget.vala:1568 +#: ../src/client/composer/composer-widget.vala:1585 #, c-format msgid "“%s” could not be opened for reading." msgstr "Не могу да отворим „%s“ за читање." -#: ../src/client/composer/composer-widget.vala:1576 +#: ../src/client/composer/composer-widget.vala:1593 msgid "Cannot add attachment" msgstr "Не могу да додам прилог" -#: ../src/client/composer/composer-widget.vala:1638 +#: ../src/client/composer/composer-widget.vala:1645 msgid "To: " msgstr "Прима: " -#: ../src/client/composer/composer-widget.vala:1641 +#: ../src/client/composer/composer-widget.vala:1648 msgid "Cc: " msgstr "Цц: " -#: ../src/client/composer/composer-widget.vala:1644 +#: ../src/client/composer/composer-widget.vala:1651 msgid "Bcc: " msgstr "Бцц: " -#: ../src/client/composer/composer-widget.vala:1647 +#: ../src/client/composer/composer-widget.vala:1654 msgid "Reply-To: " msgstr "Одговор за: " -#: ../src/client/composer/composer-widget.vala:1778 +#: ../src/client/composer/composer-widget.vala:1786 msgid "Select Color" msgstr "Изаберите боју" #. Displayed in the From dropdown to indicate an "alternate email address" #. for an account. The first printf argument will be the alternate email #. address, and the second will be the account's primary email address. -#: ../src/client/composer/composer-widget.vala:1978 +#: ../src/client/composer/composer-widget.vala:1986 #, c-format msgid "%1$s via %2$s" msgstr "%1$s преко %2$s" #. Composer label (with mnemonic underscore) for the account selector #. when choosing what address to send a message from. -#: ../src/client/composer/composer-widget.vala:2020 +#: ../src/client/composer/composer-widget.vala:2028 msgid "_From:" msgstr "_Шаље:" #. Translators: This is the name of the file chooser filter #. when inserting an image in the composer. -#: ../src/client/composer/composer-widget.vala:2244 +#: ../src/client/composer/composer-widget.vala:2252 msgid "Images" msgstr "Слике" @@ -1034,36 +1053,35 @@ #. attribute value when displaying an inline image in an email #. that did not specify a file name. E.g. Image\n" "Language-Team: Swedish \n" "Language: sv\n" @@ -28,7 +28,7 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.3\n" +"X-Generator: Poedit 2.0.4\n" #. Translators: The application name #: ../desktop/org.gnome.Geary.appdata.xml.in.h:2 @@ -46,6 +46,7 @@ #: ../desktop/org.gnome.Geary.appdata.xml.in.h:6 #: ../desktop/org.gnome.Geary.desktop.in.h:4 #: ../desktop/geary-autostart.desktop.in.h:4 +#: ../src/client/application/geary-application.vala:21 msgid "Send and receive email" msgstr "Skicka och ta emot e-post" @@ -106,6 +107,7 @@ msgstr "Geary visande rich text-redigeraren" #: ../desktop/org.gnome.Geary.desktop.in.h:2 +#: ../desktop/geary-autostart.desktop.in.h:2 msgid "Email" msgstr "E-post" @@ -122,11 +124,6 @@ msgid "Compose Message" msgstr "Skriv meddelande" -#: ../desktop/geary-autostart.desktop.in.h:2 -#: ../src/client/application/geary-application.vala:21 -msgid "Mail Client" -msgstr "E-postklient" - #: ../desktop/geary-autostart.desktop.in.h:3 msgid "Geary Mail" msgstr "Geary Mail" @@ -274,11 +271,15 @@ msgid "Copyright 2016 Software Freedom Conservancy Inc." msgstr "Copyright 2016 Software Freedom Conservancy Inc." -#: ../src/client/application/geary-application.vala:24 +#: ../src/client/application/geary-application.vala:23 +msgid "Copyright 2016-2017 Geary Development Team." +msgstr "Copyright 2016-2017 Gearys utvecklingsgrupp." + +#: ../src/client/application/geary-application.vala:25 msgid "Visit the Geary web site" msgstr "Besök Gearys webbplats" -#: ../src/client/application/geary-application.vala:464 +#: ../src/client/application/geary-application.vala:466 #, c-format msgid "About %s" msgstr "Om %s" @@ -286,7 +287,7 @@ #. Translators: add your name and email address to receive #. credit in the About dialog For example: Yamada Taro #. -#: ../src/client/application/geary-application.vala:468 +#: ../src/client/application/geary-application.vala:470 msgid "translator-credits" msgstr "" "Joachim Johansson \n" @@ -362,17 +363,17 @@ msgid "Use %s to open a new composer window" msgstr "Använd %s för att öppna ett nytt redigerarfönster" -#: ../src/client/application/geary-args.vala:54 +#: ../src/client/application/geary-args.vala:56 msgid "Please report comments, suggestions and bugs to:" msgstr "Rapportera fel, eller kom med förslag och kommentarer, på:" #. i18n: Command line arguments are invalid -#: ../src/client/application/geary-args.vala:61 +#: ../src/client/application/geary-args.vala:63 #, c-format msgid "Failed to parse command line options: %s\n" msgstr "Kunde ej tyda kommandoradsalternativ: %s\n" -#: ../src/client/application/geary-args.vala:72 +#: ../src/client/application/geary-args.vala:74 #, c-format msgid "Unrecognized command line option “%s”\n" msgstr "Felaktigt kommandoradsalternativ: ”%s”\n" @@ -2666,6 +2667,9 @@ msgid "Geary update in progress…" msgstr "Geary-uppgradering pågår…" +#~ msgid "Mail Client" +#~ msgstr "E-postklient" + #~ msgid "none" #~ msgstr "inget" diff -Nru geary-0.12.0/src/client/application/geary-application.vala geary-0.12.4/src/client/application/geary-application.vala --- geary-0.12.0/src/client/application/geary-application.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/application/geary-application.vala 2018-08-29 13:57:20.000000000 +0000 @@ -195,8 +195,12 @@ Geary.Logging.init(); Date.init(); + // Calls Gtk.init(), amongst other things base.startup(); + // Ensure all geary windows have an icon + Gtk.Window.set_default_icon_name(APP_ID); + add_action_entries(action_entries, this); } @@ -226,7 +230,16 @@ // When the app is started hidden, show_all() never gets // called, do so here to prevent an empty window appearing. controller.main_window.show_all(); - controller.main_window.present(); + + // Use present_with_time and a synthesised time so the present + // actually works, as a work around for Bug 766284 + // . + // Subtract 10ms from the current time to avoid the main + // window stealing the focus when presented just before + // showing a dialog (issue #43). + this.controller.main_window.present_with_time( + (uint32) (get_monotonic_time() / 1000) - 10 + ); return true; } @@ -419,19 +432,14 @@ int64 delta_usec = get_monotonic_time() - start_usec; if (delta_usec >= FORCE_SHUTDOWN_USEC) { debug("Forcing shutdown of Geary, %ss passed...", (delta_usec / USEC_PER_SEC).to_string()); - - break; + Posix.exit(2); } } - - if (Gtk.main_level() > 0) - Gtk.main_quit(); - else - Posix.exit(exitcode); - + + quit(); Date.terminate(); } - + /** * A callback for GearyApplication.exiting should return cancel_exit() to prevent the * application from exiting. @@ -459,7 +467,7 @@ "authors", AUTHORS, "copyright", string.join("\n", COPYRIGHT_1, COPYRIGHT_2), "license-type", Gtk.License.LGPL_2_1, - "logo-icon-name", "geary", + "logo-icon-name", APP_ID, "version", VERSION, "website", WEBSITE, "website-label", WEBSITE_LABEL, diff -Nru geary-0.12.0/src/client/application/geary-config.vala geary-0.12.4/src/client/application/geary-config.vala --- geary-0.12.0/src/client/application/geary-config.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/application/geary-config.vala 2018-08-29 13:57:20.000000000 +0000 @@ -55,11 +55,11 @@ public DesktopEnvironment desktop_environment { get { - switch (Environment.get_variable("XDG_CURRENT_DESKTOP")) { - case "Unity": - return DesktopEnvironment.UNITY; - default: - return DesktopEnvironment.UNKNOWN; + string? xdg_current_desktop = Environment.get_variable("XDG_CURRENT_DESKTOP"); + if (xdg_current_desktop != null && xdg_current_desktop.has_prefix("Unity")) { + return DesktopEnvironment.UNITY; + } else { + return DesktopEnvironment.UNKNOWN; } } } diff -Nru geary-0.12.0/src/client/application/geary-controller.vala geary-0.12.4/src/client/application/geary-controller.vala --- geary-0.12.0/src/client/application/geary-controller.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/application/geary-controller.vala 2018-08-29 13:57:20.000000000 +0000 @@ -171,9 +171,6 @@ // custom icons) IconFactory.instance.init(); - // Ensure all geary windows have an icon - Gtk.Window.set_default_icon_name("geary"); - apply_app_menu_fix(); // Setup actions. @@ -1485,15 +1482,24 @@ private void on_conversation_count_changed() { if (this.current_conversations != null) { + ConversationViewer viewer = this.main_window.conversation_viewer; int count = this.current_conversations.get_conversation_count(); if (count == 0) { // Let the user know if there's no available conversations if (this.current_folder is Geary.SearchFolder) { - this.main_window.conversation_viewer.show_empty_search(); + viewer.show_empty_search(); } else { - this.main_window.conversation_viewer.show_empty_folder(); + viewer.show_empty_folder(); } enable_message_buttons(false); + } else { + // When not doing autoselect, we never get + // conversations_selected firing from the convo list, + // so we need to stop the loading spinner here + if (!this.application.config.autoselect) { + viewer.show_none_selected(); + enable_message_buttons(false); + } } conversation_count_changed(count); } @@ -1510,14 +1516,14 @@ if (conversation != null) main_window.conversation_list_view.select_conversation(conversation); } - + private void on_indicator_activated_application(uint32 timestamp) { // When the app is started hidden, show_all() never gets // called, do so here to prevent an empty window appearing. main_window.show_all(); - main_window.present_with_time(timestamp); + this.application.present(); } - + private void on_indicator_activated_composer(uint32 timestamp) { on_indicator_activated_application(timestamp); on_new_message(); @@ -1560,6 +1566,8 @@ viewer.load_conversation.begin( Geary.Collection.get_first(selected), this.current_folder, + this.application.config, + this.avatar_session, (obj, ret) => { try { viewer.load_conversation.end(ret); @@ -1598,12 +1606,23 @@ ); } - private void on_special_folder_type_changed(Geary.Folder folder, Geary.SpecialFolderType old_type, - Geary.SpecialFolderType new_type) { + private void on_special_folder_type_changed(Geary.Folder folder, + Geary.SpecialFolderType old_type, + Geary.SpecialFolderType new_type) { main_window.folder_list.remove_folder(folder); main_window.folder_list.add_folder(folder); + // Since removing the folder will also remove its children, we + // need to check for any and re-add them. See isssue #11. + try { + foreach (Geary.Folder child in + folder.account.list_matching_folders(folder.path)) { + main_window.folder_list.add_folder(child); + } + } catch (Error err) { + // Oh well + } } - + private void on_engine_opened() { // Locate the first account so we can select its inbox when available. try { @@ -2086,12 +2105,6 @@ #endif if (!Geary.String.is_empty(filename)) dialog.set_current_name(filename); - dialog.set_do_overwrite_confirmation(true); - dialog.confirm_overwrite.connect((chooser) => { - return do_overwrite_confirmation(chooser.get_file()) - ? Gtk.FileChooserConfirmation.ACCEPT_FILENAME - : Gtk.FileChooserConfirmation.SELECT_AGAIN; - }); bool accepted = (dialog.run() == Gtk.ResponseType.ACCEPT); string? accepted_filename = dialog.get_filename(); @@ -2370,7 +2383,7 @@ // Find out what to do with the inline composers. // TODO: Remove this in favor of automatically saving drafts - main_window.present(); + this.application.present(); ConfirmationDialog dialog = new ConfirmationDialog(main_window, _("Close open draft messages?"), null, Stock._CLOSE, "destructive-action"); if (dialog.run() == Gtk.ResponseType.OK) { @@ -2539,17 +2552,17 @@ && !current_folder.properties.is_local_only && current_account != null && (current_folder as Geary.FolderSupport.Move) != null); } - + public bool confirm_delete(int num_messages) { - main_window.present(); + this.application.present(); ConfirmationDialog dialog = new ConfirmationDialog(main_window, ngettext( "Do you want to permanently delete this message?", "Do you want to permanently delete these messages?", num_messages), null, _("Delete"), "destructive-action"); - + return (dialog.run() == Gtk.ResponseType.OK); } - + private async void archive_or_delete_selection_async(bool archive, bool trash, Cancellable? cancellable) throws Error { if (!can_switch_conversation_view()) @@ -2739,13 +2752,7 @@ ); }); foreach (ConversationMessage msg_view in view) { - msg_view.link_activated.connect((link) => { - if (link.down().has_prefix(Geary.ComposedEmail.MAILTO_SCHEME)) { - compose_mailto(link); - } else { - open_uri(link); - } - }); + msg_view.link_activated.connect(on_link_activated); msg_view.save_image.connect((url, alt_text, buf) => { on_save_image_extended(view, url, alt_text, buf); }); @@ -2972,6 +2979,14 @@ } } + private void on_link_activated(string uri) { + if (uri.down().has_prefix(Geary.ComposedEmail.MAILTO_SCHEME)) { + compose_mailto(uri); + } else { + open_uri(uri); + } + } + private void on_save_image_extended(ConversationEmail view, string url, string? alt_text, diff -Nru geary-0.12.0/src/client/application/main.vala geary-0.12.4/src/client/application/main.vala --- geary-0.12.0/src/client/application/main.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/application/main.vala 2018-08-29 13:57:20.000000000 +0000 @@ -17,7 +17,7 @@ // // Packages can disable this fix with the --disable-poodle-ssl3 configure option. #if !DISABLE_POODLE - Environment.set_variable("G_TLS_GNUTLS_PRIORITY", "NORMAL:%COMPAT:%LATEST_RECORD_VERSION:!VERS-SSL3.0", false); + Environment.set_variable("G_TLS_GNUTLS_PRIORITY", "NORMAL:%COMPAT:!VERS-SSL3.0", false); #endif // Disable WebKit2 accelerated compositing here while we can't diff -Nru geary-0.12.0/src/client/application/secret-mediator.vala geary-0.12.4/src/client/application/secret-mediator.vala --- geary-0.12.0/src/client/application/secret-mediator.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/application/secret-mediator.vala 2018-08-29 13:57:20.000000000 +0000 @@ -20,6 +20,20 @@ null ); + // See Bug 697681 + private static Secret.Schema compat_schema = new Secret.Schema( + "org.gnome.keyring.NetworkPassword", + Secret.SchemaFlags.NONE, + "user", Secret.SchemaAttributeType.STRING, + "domain", Secret.SchemaAttributeType.STRING, + "object", Secret.SchemaAttributeType.STRING, + "protocol", Secret.SchemaAttributeType.STRING, + "port", Secret.SchemaAttributeType.INTEGER, + "server", Secret.SchemaAttributeType.STRING, + "authtype", Secret.SchemaAttributeType.STRING, + null + ); + private Geary.Nonblocking.Mutex dialog_mutex = new Geary.Nonblocking.Mutex(); @@ -27,6 +41,8 @@ Geary.AccountInformation account, Cancellable? cancellable = null) throws Error { + yield check_unlocked(cancellable); + string? password = yield Secret.password_lookupv( SecretMediator.schema, new_attrs(service, account), cancellable ); @@ -45,6 +61,8 @@ Geary.AccountInformation account, Cancellable? cancellable = null) throws Error { + yield check_unlocked(cancellable); + Geary.Credentials credentials = get_credentials(service, account); try { yield do_store(service, account, credentials.pass, cancellable); @@ -58,6 +76,8 @@ Geary.AccountInformation account, Cancellable? cancellable = null) throws Error { + yield check_unlocked(cancellable); + Geary.Credentials credentials = get_credentials(service, account); yield Secret.password_clearv(SecretMediator.schema, new_attrs(service, account), @@ -66,13 +86,13 @@ // Remove legacy formats // <= 0.11 yield Secret.password_clear( - Secret.SCHEMA_COMPAT_NETWORK, + compat_schema, cancellable, "user", get_legacy_user(service, account.primary_mailbox.address) ); // <= 0.6 yield Secret.password_clear( - Secret.SCHEMA_COMPAT_NETWORK, + compat_schema, cancellable, "user", get_legacy_user(service, credentials.user) ); @@ -94,7 +114,7 @@ Gtk.Window? main_window = GearyApplication.instance.controller.main_window; if (main_window != null && !main_window.visible) { main_window.show_all(); - main_window.present_with_time(Gdk.CURRENT_TIME); + GearyApplication.instance.present(); } PasswordDialog password_dialog = new PasswordDialog(main_window, services.has_smtp(), @@ -128,6 +148,38 @@ return true; } + // Ensure the default collection unlocked. Try to unlock it since + // the user may be running in a limited environment and it would + // prevent us from prompting the user multiple times in one + // session. See Bug 784300. + private async void check_unlocked(Cancellable? cancellable = null) + throws Error { + Secret.Service service = yield Secret.Service.get( + Secret.ServiceFlags.OPEN_SESSION, cancellable + ); + Secret.Collection? collection = yield Secret.Collection.for_alias( + service, + Secret.COLLECTION_DEFAULT, + Secret.CollectionFlags.NONE, + cancellable + ); + + // For custom desktop setups, it is possible that the current + // session has a service responding on DBus but no password + // keyring. There's no much we can do in this case except just + // check for the collection being null so we don't crash. See + // Bug 795328. + if (collection != null && collection.get_locked()) { + List to_lock = new List(); + to_lock.append(collection); + List unlocked; + yield service.unlock(to_lock, cancellable, out unlocked); + if (unlocked.length() != 0) { + // XXX + } + } + } + private async void do_store(Geary.Service service, Geary.AccountInformation account, string password, @@ -190,7 +242,7 @@ throws Error { // <= 0.11 string? password = yield Secret.password_lookup( - Secret.SCHEMA_COMPAT_NETWORK, + compat_schema, cancellable, "user", get_legacy_user(service, account.primary_mailbox.address) ); @@ -200,7 +252,7 @@ Geary.Credentials creds = get_credentials(service, account); string user = get_legacy_user(service, creds.user); password = yield Secret.password_lookup( - Secret.SCHEMA_COMPAT_NETWORK, + compat_schema, cancellable, "user", user ); @@ -208,7 +260,7 @@ // Clear the old password if (password != null) { yield Secret.password_clear( - Secret.SCHEMA_COMPAT_NETWORK, + compat_schema, cancellable, "user", user ); diff -Nru geary-0.12.0/src/client/components/client-web-view.vala geary-0.12.4/src/client/components/client-web-view.vala --- geary-0.12.0/src/client/components/client-web-view.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/components/client-web-view.vala 2018-08-29 13:57:20.000000000 +0000 @@ -14,7 +14,7 @@ * integration, Inspector support, and remote and inline image * handling. */ -public class ClientWebView : WebKit.WebView { +public class ClientWebView : WebKit.WebView, Geary.BaseInterface { /** URI Scheme and delimiter for internal resource loads. */ @@ -25,6 +25,8 @@ /** URI Scheme and delimiter for images loaded by Content-ID. */ public const string CID_URL_PREFIX = "cid:"; + + private const string CONTENT_LOADED = "contentLoaded"; private const string PREFERRED_HEIGHT_CHANGED = "preferredHeightChanged"; private const string REMOTE_IMAGE_LOAD_BLOCKED = "remoteImageLoadBlocked"; private const string SELECTION_CHANGED = "selectionChanged"; @@ -172,6 +174,22 @@ /** Delegate for UserContentManager message callbacks. */ public delegate void JavaScriptMessageHandler(WebKit.JavascriptResult js_result); + /** + * Determines if the view's content has been fully loaded. + * + * This property is updated immediately before the {@link + * content_loaded} signal is fired, and is triggered by the + * PageState JavaScript object completing its load + * handler. I.e. This will be true after the in-page JavaScript has + * finished making any modifications to the page content. + * + * This will likely be fired after WebKitGTK sets the `is-loading` + * property to `FALSE` and emits `load-changed` with + * `WebKitLoadEvent.LOAD_FINISHED`, since they are related to + * network resource loading, not page content. + */ + public bool is_content_loaded { get; private set; default = false; } + /** Determines if the view has any selected text */ public bool has_selection { get; private set; default = false; } @@ -216,6 +234,17 @@ private Gee.Map internal_resources = new Gee.HashMap(); + private Gee.List registered_message_handlers = + new Gee.LinkedList(); + + + /** + * Emitted when the view's content has finished loaded. + * + * See {@link is_content_loaded} for detail about when this is + * emitted. + */ + public signal void content_loaded(); /** Emitted when the view's selection has changed. */ public signal void selection_changed(bool has_selection); @@ -256,6 +285,7 @@ user_content_manager: content_manager, settings: setts ); + base_ref(); // XXX get the allow prefix from the extension somehow @@ -266,6 +296,9 @@ }); register_message_handler( + CONTENT_LOADED, on_content_loaded + ); + register_message_handler( PREFERRED_HEIGHT_CHANGED, on_preferred_height_changed ); register_message_handler( @@ -273,7 +306,7 @@ ); register_message_handler( SELECTION_CHANGED, on_selection_changed - ); + ); // Manage zoom level config.bind(Configuration.CONVERSATION_VIEWER_ZOOM_KEY, this, "zoom_level"); @@ -287,6 +320,18 @@ "monospace-font", SettingsBindFlags.DEFAULT); } + ~ClientWebView() { + base_unref(); + } + + public override void destroy() { + foreach (ulong id in this.registered_message_handlers) { + this.user_content_manager.disconnect(id); + } + this.registered_message_handlers.clear(); + base.destroy(); + } + /** * Loads a message HTML body into the view. */ @@ -379,11 +424,16 @@ */ protected inline void register_message_handler(string name, JavaScriptMessageHandler handler) { - // XXX cant use the delegate directly: b.g.o Bug 604781 - this.user_content_manager.script_message_received[name].connect( + // XXX cant use the delegate directly, see b.g.o Bug + // 604781. However the workaround below creates a circular + // reference, causing ClientWebView instances to leak. So to + // work around that we need to record handler ids and + // disconnect them when being destroyed. + ulong id = this.user_content_manager.script_message_received[name].connect( (result) => { handler(result); } ); - if (!get_user_content_manager().register_script_message_handler(name)) { + this.registered_message_handlers.add(id); + if (!this.user_content_manager.register_script_message_handler(name)) { debug("Failed to register script message handler: %s", name); } } @@ -440,8 +490,17 @@ case WebKit.NavigationType.LINK_CLICKED: // Let the app know a user activated a link, but don't // try to load it ourselves. - link_activated(nav_policy.request.uri); + + // We need to call ignore() before emitting the signal + // to unblock the WebKit WebProcess, otherwise the + // call chain for mailto links will cause the + // WebProcess to deadlock, and the resulting composer + // will be useless. See Geary Bug 771504 + // + // and WebKitGTK Bug 182528 + // policy.ignore(); + link_activated(nav_policy.request.uri); break; default: @@ -500,6 +559,11 @@ remote_image_load_blocked(); } + private void on_content_loaded(WebKit.JavascriptResult result) { + this.is_content_loaded = true; + content_loaded(); + } + private void on_selection_changed(WebKit.JavascriptResult result) { try { bool has_selection = WebKitUtil.to_bool(result); @@ -518,4 +582,3 @@ // XXX this needs to be moved into the libsoup bindings extern string soup_uri_decode(string part); - diff -Nru geary-0.12.0/src/client/components/folder-popover.vala geary-0.12.4/src/client/components/folder-popover.vala --- geary-0.12.0/src/client/components/folder-popover.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/components/folder-popover.vala 2018-08-29 13:57:20.000000000 +0000 @@ -107,6 +107,9 @@ [GtkCallback] private void on_search_entry_search_changed() { invalidate_filter(); + if (this.search_entry.get_text() != "") { + this.list_box.unselect_all(); + } } private void invalidate_filter() { diff -Nru geary-0.12.0/src/client/components/main-toolbar.vala geary-0.12.4/src/client/components/main-toolbar.vala --- geary-0.12.0/src/client/components/main-toolbar.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/components/main-toolbar.vala 2018-08-29 13:57:20.000000000 +0000 @@ -154,7 +154,11 @@ private void setup_button(Gtk.Button b, string action_name, bool show_label = false) { Gtk.Action related_action = action_group.get_action(action_name); - b.focus_on_click = false; + // Explicitly call set_focus_on_click() here to work around + // linker error for gtk_widget_set_focus_on_click that would + // otherwise get generated when compiling vala >= 0.34 against + // GTK+ < 3.20 + b.set_focus_on_click(false); b.use_underline = true; b.tooltip_text = related_action.tooltip; related_action.notify["tooltip"].connect(() => { b.tooltip_text = related_action.tooltip; }); diff -Nru geary-0.12.0/src/client/components/main-window.vala geary-0.12.4/src/client/components/main-window.vala --- geary-0.12.0/src/client/components/main-window.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/components/main-window.vala 2018-08-29 13:57:20.000000000 +0000 @@ -7,7 +7,7 @@ */ [GtkTemplate (ui = "/org/gnome/Geary/main-window.ui")] -public class MainWindow : Gtk.ApplicationWindow { +public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface { private const int STATUS_BAR_HEIGHT = 18; public new GearyApplication application { @@ -57,6 +57,7 @@ public MainWindow(GearyApplication application) { Object(application: application); + base_ref(); // GTK+ 3.14 (and others?) ignores this property in the UI // file, so set it explicitly here to avoid having a menubar @@ -79,6 +80,10 @@ on_change_orientation(); } + ~MainWindow() { + base_unref(); + } + private void load_config(Configuration config) { // This code both loads AND saves the pane positions with live updating. This is more // resilient against crashes because the value in dconf changes *immediately*, and diff -Nru geary-0.12.0/src/client/composer/composer-container.vala geary-0.12.4/src/client/composer/composer-container.vala --- geary-0.12.0/src/client/composer/composer-container.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/composer/composer-container.vala 2018-08-29 13:57:20.000000000 +0000 @@ -25,7 +25,12 @@ public abstract Gtk.ApplicationWindow top_window { get; } public virtual void present() { - this.top_window.present(); + // Use present_with_time and a synthesised time so the present + // actually works, as a work around for Bug 766284 + // . + this.top_window.present_with_time( + (uint32) (get_monotonic_time() / 1000) + ); } public virtual unowned Gtk.Widget get_focus() { diff -Nru geary-0.12.0/src/client/composer/composer-embed.vala geary-0.12.4/src/client/composer/composer-embed.vala --- geary-0.12.0/src/client/composer/composer-embed.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/composer/composer-embed.vala 2018-08-29 13:57:20.000000000 +0000 @@ -186,10 +186,6 @@ return ret; } - public void present() { - top_window.present(); - } - public void vanish() { hide(); this.composer.state = ComposerWidget.ComposerState.DETACHED; diff -Nru geary-0.12.0/src/client/composer/composer-headerbar.vala geary-0.12.4/src/client/composer/composer-headerbar.vala --- geary-0.12.0/src/client/composer/composer-headerbar.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/composer/composer-headerbar.vala 2018-08-29 13:57:20.000000000 +0000 @@ -46,8 +46,10 @@ bind_property("show-pending-attachments", conversation_attach_buttons, "visible", BindingFlags.SYNC_CREATE); - notify["decoration-layout"].connect(set_detach_button_side); - realize.connect(set_detach_button_side); + set_detach_button_side(); + Gtk.Settings.get_default().notify["gtk-decoration-layout"].connect( + () => { set_detach_button_side(); } + ); } public void set_recipients(string label, string tooltip) { diff -Nru geary-0.12.0/src/client/composer/composer-web-view.vala geary-0.12.4/src/client/composer/composer-web-view.vala --- geary-0.12.0/src/client/composer/composer-web-view.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/composer/composer-web-view.vala 2018-08-29 13:57:20.000000000 +0000 @@ -144,17 +144,17 @@ string quote, bool top_posting, bool is_draft) { - const string HTML_PRE = """"""; + const string HTML_PRE = """"""; const string HTML_POST = """"""; const string BODY_PRE = """ -
"""; +
"""; const string BODY_POST = """
"""; const string SIGNATURE = """ -
%s
+
%s
"""; const string QUOTE = """ -

%s
+

%s
"""; const string CURSOR = "

"; const string SPACER = "

"; diff -Nru geary-0.12.0/src/client/composer/composer-widget.vala geary-0.12.4/src/client/composer/composer-widget.vala --- geary-0.12.0/src/client/composer/composer-widget.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/composer/composer-widget.vala 2018-08-29 13:57:20.000000000 +0000 @@ -352,6 +352,7 @@ private Gee.Map cid_files = new Gee.HashMap(); private Geary.App.DraftManager? draft_manager = null; + private GLib.Cancellable? draft_manager_opening = null; private Geary.EmailFlags draft_flags = new Geary.EmailFlags.with(Geary.EmailFlags.DRAFT); private Geary.TimeoutManager draft_timer; private bool is_draft_saved = false; @@ -474,6 +475,7 @@ // TODO: also listen for account updates to allow adding identities while writing an email bind_property("toolbar-text", this.info_label, "label", BindingFlags.SYNC_CREATE); + bind_property("toolbar-text", this.info_label, "tooltip-text", BindingFlags.SYNC_CREATE); this.from = new Geary.RFC822.MailboxAddresses.single(account.information.primary_mailbox); @@ -517,6 +519,10 @@ public override void destroy() { this.draft_timer.reset(); + if (this.draft_manager_opening != null) { + this.draft_manager_opening.cancel(); + this.draft_manager_opening = null; + } if (this.draft_manager != null) close_draft_manager_async.begin(null); base.destroy(); @@ -599,6 +605,7 @@ update_composer_view(); update_attachments_view(); + update_pending_attachments(this.pending_include, true); string signature = yield load_signature(cancellable); this.editor.load_html( @@ -665,7 +672,8 @@ Gee.Set emails = email_map.get_keys(); Geary.Email? email = null; foreach (Geary.Email candidate in emails) { - if (candidate.message_id.equal_to(mid)) { + if (candidate.message_id != null && + mid.equal_to(candidate.message_id)) { email = candidate; break; } @@ -711,40 +719,6 @@ } } - /** - * Creates and opens the composer's draft manager. - */ - private async void open_draft_manager_async( - Geary.EmailIdentifier? editing_draft_id = null, - Cancellable? cancellable = null) - throws Error { - if (!this.account.information.save_drafts) { - this.header.save_and_close_button.hide(); - return; - } - - this.draft_manager = new Geary.App.DraftManager(account); - try { - yield this.draft_manager.open_async(editing_draft_id, cancellable); - debug("Draft manager opened"); - } catch (Error err) { - debug("Unable to open draft manager %s: %s", - this.draft_manager.to_string(), err.message); - this.draft_manager = null; - throw err; - } - - update_draft_state(); - get_action(ACTION_CLOSE_AND_SAVE).set_enabled(true); - this.header.save_and_close_button.show(); - - this.draft_manager.notify[Geary.App.DraftManager.PROP_DRAFT_STATE] - .connect(on_draft_state_changed); - this.draft_manager.notify[Geary.App.DraftManager.PROP_CURRENT_DRAFT_ID] - .connect(on_draft_id_changed); - this.draft_manager.fatal.connect(on_draft_manager_fatal); - } - // Copies the addresses (e.g. From/To/CC) and content from referred into this one private string fill_in_from_referred(Geary.Email referred, string? quote) { string referred_quote = ""; @@ -810,8 +784,15 @@ this.to_entry.grab_focus(); else if (not_compact && Geary.String.is_empty(subject)) this.subject_entry.grab_focus(); - else - this.editor.grab_focus(); + else { + // Need to grab the focus after the content has finished + // loading otherwise the text caret will not be visible. + if (this.editor.is_content_loaded) { + this.editor.grab_focus(); + } else { + this.editor.content_loaded.connect(() => { this.editor.grab_focus(); }); + } + } } // Initializes all actions and adds them to the action group @@ -1169,9 +1150,10 @@ private void on_detach() { if (this.state == ComposerState.DETACHED) return; - Gtk.Widget? focus = this.container.top_window.get_focus(); + + Gtk.Widget? focused_widget = this.container.top_window.get_focus(); this.container.remove_composer(); - ComposerWindow window = new ComposerWindow(this); + ComposerWindow new_window = new ComposerWindow(this); // Workaround a GTK+ crasher, Bug 771812. When the composer is // re-parented, its menu_button's popover keeps a reference to @@ -1187,11 +1169,19 @@ this.state = ComposerWidget.ComposerState.DETACHED; this.header.detached(); update_composer_view(); - if (focus != null && focus.parent.visible) { - ComposerWindow focus_win = focus.get_toplevel() as ComposerWindow; - if (focus_win != null && focus_win == window) - focus.grab_focus(); - } else { + + // If the previously focused widget is in the new composer + // window then focus that, else focus something useful. + bool refocus = true; + if (focused_widget != null) { + ComposerWindow? focused_window = + focused_widget.get_toplevel() as ComposerWindow; + if (new_window == focused_window) { + focused_widget.grab_focus(); + refocus = false; + } + } + if (refocus) { set_focus(); } } @@ -1297,44 +1287,85 @@ } /** + * Creates and opens the composer's draft manager. + */ + private async void + open_draft_manager_async(Geary.EmailIdentifier? editing_draft_id = null) + throws Error { + if (!this.account.information.save_drafts) { + this.header.save_and_close_button.hide(); + return; + } + + // Cancel any existing opening first + if (this.draft_manager_opening != null) { + this.draft_manager_opening.cancel(); + } + this.draft_manager_opening = new GLib.Cancellable(); + + Geary.App.DraftManager new_manager = new Geary.App.DraftManager(account); + try { + yield new_manager.open_async(editing_draft_id, this.draft_manager_opening); + debug("Draft manager opened"); + } catch (Error err) { + debug("Unable to open draft manager %s: %s", + new_manager.to_string(), err.message); + throw err; + } + + new_manager.notify[Geary.App.DraftManager.PROP_DRAFT_STATE] + .connect(on_draft_state_changed); + new_manager.notify[Geary.App.DraftManager.PROP_CURRENT_DRAFT_ID] + .connect(on_draft_id_changed); + new_manager.fatal.connect(on_draft_manager_fatal); + + this.draft_manager_opening = null; + this.draft_manager = new_manager; + + update_draft_state(); + get_action(ACTION_CLOSE_AND_SAVE).set_enabled(true); + this.header.save_and_close_button.show(); + + } + + /** * Closes current draft manager, if any, then opens a new one. */ - private async void reopen_draft_manager_async(Cancellable? cancellable) + private async void reopen_draft_manager_async() throws Error { if (this.draft_manager != null) { - yield close_draft_manager_async(cancellable); + // Discard the draft, if any, since it may be on a + // different account + discard_draft(); + this.draft_manager.discard_on_close = true; + yield close_draft_manager_async(null); } - // XXX Need to work out what do to with any existing draft in - // this case. See Bug 713533. - yield open_draft_manager_async(null); + yield open_draft_manager_async(); } private async void close_draft_manager_async(Cancellable? cancellable) throws Error { this.draft_save_text = ""; get_action(ACTION_CLOSE_AND_SAVE).set_enabled(false); - disconnect_from_draft_manager(); + + Geary.App.DraftManager old_manager = this.draft_manager; + this.draft_manager = null; + + old_manager.notify[Geary.App.DraftManager.PROP_DRAFT_STATE] + .disconnect(on_draft_state_changed); + old_manager.notify[Geary.App.DraftManager.PROP_CURRENT_DRAFT_ID] + .disconnect(on_draft_id_changed); + old_manager.fatal.disconnect(on_draft_manager_fatal); // drop ref even if close failed try { - yield this.draft_manager.close_async(cancellable); - } finally { - this.draft_manager = null; + yield old_manager.close_async(cancellable); + } catch (Error err) { + debug("Error closing draft manager: %s", err.message); } debug("Draft manager closed"); } - // This code is in a separate method due to https://bugzilla.gnome.org/show_bug.cgi?id=742621 - // connect_to_draft_manager() is simply for symmetry. When above bug is fixed, this code can - // be moved back into open/close methods - private void disconnect_from_draft_manager() { - this.draft_manager.notify[Geary.App.DraftManager.PROP_DRAFT_STATE] - .disconnect(on_draft_state_changed); - this.draft_manager.notify[Geary.App.DraftManager.PROP_CURRENT_DRAFT_ID] - .disconnect(on_draft_id_changed); - this.draft_manager.fatal.disconnect(on_draft_manager_fatal); - } - private void update_draft_state() { switch (this.draft_manager.draft_state) { case Geary.App.DraftManager.DraftState.STORED: @@ -1446,8 +1477,6 @@ attachments_box.show_all(); else attachments_box.hide(); - - update_pending_attachments(this.pending_include, true); } // Both adds pending attachments and updates the UI if there are @@ -1597,15 +1626,16 @@ private void remove_attachment(File file, Gtk.Box box) { if (!this.attached_files.remove(file)) return; - + foreach (weak Gtk.Widget child in this.attachments_box.get_children()) { if (child == box) { this.attachments_box.remove(box); break; } } - + update_attachments_view(); + update_pending_attachments(this.pending_include, false); } private bool check_send_on_return(Gdk.EventKey event) { @@ -2058,25 +2088,21 @@ return !set_active; } - private bool update_from_account() throws Error { + private void update_from_account() throws Error { int index = this.from_multiple.get_active(); - if (index < 0) - return false; - - assert(this.from_list.size > index); - - Geary.Account new_account = this.from_list.get(index).account; - from = this.from_list.get(index).from; - if (new_account == this.account) - return false; - - this.account = new_account; - this.load_signature.begin(null, (obj, res) => { - this.editor.update_signature(this.load_signature.end(res)); - }); - load_entry_completions.begin(); - - return true; + if (index >= 0) { + FromAddressMap selected = this.from_list.get(index); + this.from = selected.from; + + if (selected.account != this.account) { + this.account = selected.account; + this.load_signature.begin(null, (obj, res) => { + this.editor.update_signature(this.load_signature.end(res)); + }); + load_entry_completions.begin(); + reopen_draft_manager_async.begin(); + } + } } private async string load_signature(Cancellable? cancellable = null) { @@ -2149,20 +2175,11 @@ } private void on_from_changed() { - bool changed = false; try { - changed = update_from_account(); + update_from_account(); } catch (Error err) { debug("Unable to update From: Account in composer: %s", err.message); } - - // if the Geary.Account didn't change and the drafts manager - // is open(ing), do nothing more; need to check for the drafts - // manager because opening it in the case of multiple From: is - // handled here alone, so if changed open it if not already - if (changed || this.draft_manager == null) { - reopen_draft_manager_async.begin(null); - } } private bool on_button_release(Gdk.Event event) { diff -Nru geary-0.12.0/src/client/composer/contact-list-store.vala geary-0.12.4/src/client/composer/contact-list-store.vala --- geary-0.12.0/src/client/composer/contact-list-store.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/composer/contact-list-store.vala 2018-08-29 13:57:20.000000000 +0000 @@ -4,7 +4,7 @@ * (version 2.1 or later). See the COPYING file in this distribution. */ -public class ContactListStore : Gtk.ListStore { +public class ContactListStore : Gtk.ListStore, Geary.BaseInterface { // Minimum visibility for the contact to appear in autocompletion. private const Geary.ContactImportance CONTACT_VISIBILITY_THRESHOLD = Geary.ContactImportance.TO_TO; @@ -67,8 +67,9 @@ } public Geary.ContactStore contact_store { get; private set; } - + public ContactListStore(Geary.ContactStore contact_store) { + base_ref(); set_column_types(Column.get_types()); this.contact_store = contact_store; contact_store.contact_added.connect(on_contact_added); @@ -78,6 +79,7 @@ ~ContactListStore() { this.contact_store.contact_added.disconnect(on_contact_added); this.contact_store.contact_updated.disconnect(on_contact_updated); + base_unref(); } /** diff -Nru geary-0.12.0/src/client/conversation-list/conversation-list-view.vala geary-0.12.4/src/client/conversation-list/conversation-list-view.vala --- geary-0.12.0/src/client/conversation-list/conversation-list-view.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/conversation-list/conversation-list-view.vala 2018-08-29 13:57:20.000000000 +0000 @@ -4,7 +4,7 @@ * (version 2.1 or later). See the COPYING file in this distribution. */ -public class ConversationListView : Gtk.TreeView { +public class ConversationListView : Gtk.TreeView, Geary.BaseInterface { const int LOAD_MORE_HEIGHT = 100; private bool enable_load_more = true; @@ -37,6 +37,7 @@ public ConversationListView() { + base_ref(); set_show_expanders(false); set_headers_visible(false); @@ -75,6 +76,10 @@ this.selection_update.priority = Geary.IdleManager.Priority.LOW; } + ~ConversationListView() { + base_unref(); + } + public override void destroy() { this.selection_update.reset(); base.destroy(); diff -Nru geary-0.12.0/src/client/conversation-viewer/conversation-email.vala geary-0.12.4/src/client/conversation-viewer/conversation-email.vala --- geary-0.12.0/src/client/conversation-viewer/conversation-email.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/conversation-viewer/conversation-email.vala 2018-08-29 13:57:20.000000000 +0000 @@ -16,7 +16,7 @@ * ConversationMessage}. */ [GtkTemplate (ui = "/org/gnome/Geary/conversation-email.ui")] -public class ConversationEmail : Gtk.Box { +public class ConversationEmail : Gtk.Box, Geary.BaseInterface { // This isn't a Gtk.Grid since when added to a Gtk.ListBoxRow the // hover style isn't applied to it. @@ -27,7 +27,7 @@ private class MessageViewIterator : Gee.Traversable, Gee.Iterator, - Object { + Geary.BaseObject { public bool read_only { @@ -47,15 +47,14 @@ } public bool next() { - if (!has_next()) { - return false; - } - if (this.pos == -1) { - this.pos = 0; + bool has_next = false; + this.pos += 1; + if (this.pos == 0) { + has_next = true; } else { - this.attached_views.next(); + has_next = this.attached_views.next(); } - return true; + return has_next; } public bool has_next() { @@ -68,7 +67,6 @@ assert_not_reached(); case 0: - this.pos = 1; return this.parent_view.primary_message; default: @@ -81,12 +79,12 @@ } public new bool foreach(Gee.ForallFunc f) { - this.pos = 1; - bool ret = f(this.parent_view.primary_message); - if (ret) { - ret = this.attached_views.foreach(f); + bool cont = true; + while (cont && has_next()) { + next(); + cont = f(get()); } - return ret; + return cont; } } @@ -249,14 +247,12 @@ public Gee.List attached_messages { owned get { return this._attached_messages.read_only_view; } } + private Gee.List _attached_messages = + new Gee.LinkedList(); /** Determines if all message's web views have finished loading. */ public bool message_bodies_loaded { get; private set; default = false; } - // Backing for attached_messages - private Gee.List _attached_messages = - new Gee.LinkedList(); - // Contacts for the email's account private Geary.ContactStore contact_store; @@ -363,6 +359,7 @@ Configuration config, bool is_sent, bool is_draft) { + base_ref(); this.email = email; this.contact_store = contact_store; this.config = config; @@ -496,6 +493,10 @@ } } + ~ConversationEmail() { + base_unref(); + } + /** * Starts loading the complete email. * @@ -503,16 +504,14 @@ * primary message and any attached messages, as well as * attachment names, types and icons. */ - public async void start_loading(Cancellable load_cancelled) { + public async void start_loading(ConversationListBox.AvatarStore avatars, + Cancellable load_cancelled) { foreach (ConversationMessage view in this) { if (load_cancelled.is_cancelled()) { break; } - yield primary_message.load_message_body(load_cancelled); - view.load_avatar.begin( - GearyApplication.instance.controller.avatar_session, - load_cancelled - ); + yield view.load_message_body(load_cancelled); + view.load_avatar.begin(avatars, load_cancelled); } // Only load attachments once the web views have finished diff -Nru geary-0.12.0/src/client/conversation-viewer/conversation-list-box.vala geary-0.12.4/src/client/conversation-viewer/conversation-list-box.vala --- geary-0.12.0/src/client/conversation-viewer/conversation-list-box.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/conversation-viewer/conversation-list-box.vala 2018-08-29 13:57:20.000000000 +0000 @@ -18,7 +18,7 @@ * ConversationListBox sorts by the {@link Geary.Email.date} field * (the Date: header), as that's the date displayed to the user. */ -public class ConversationListBox : Gtk.ListBox { +public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface { /** Fields that must be available for display as a conversation. */ private const Geary.Email.Field REQUIRED_FIELDS = @@ -33,18 +33,18 @@ // Offset from the top of the list box which emails views will // scrolled to, so the user can see there are additional messages - // above it. XXX This is currently approx 1.5 times the height of + // above it. XXX This is currently approx 0.5 times the height of // a collapsed ConversationEmail, it should probably calculated // somehow so that differences user's font size are taken into // account. - private const int EMAIL_TOP_OFFSET = 92; + private const int EMAIL_TOP_OFFSET = 32; // Loading spinner timeout private const int LOADING_TIMEOUT_MSEC = 150; // Base class for list rows it the list box - private abstract class ConversationRow : Gtk.ListBoxRow { + private abstract class ConversationRow : Gtk.ListBoxRow, Geary.BaseInterface { protected const string EXPANDED_CLASS = "geary-expanded"; @@ -111,6 +111,7 @@ public ConversationRow(Geary.Email? email) { + base_ref(); this.email = email; show(); @@ -122,6 +123,10 @@ #endif } + ~ConversationRow() { + base_unref(); + } + // Request the row be expanded, if supported. public virtual new void expand() { // Not supported by default @@ -247,6 +252,106 @@ } + + /** + * Email address avatar loader and cache. + */ + public class AvatarStore { + + + private Soup.Session session; + private Gee.Map loaders = + new Gee.HashMap(); + + + internal AvatarStore(Soup.Session session) { + this.session = session; + } + + internal async Gdk.Pixbuf? load(Geary.RFC822.MailboxAddress address, + int pixel_size, + Cancellable load_cancelled) + throws Error { + string key = address.to_string(); + AvatarLoader loader = this.loaders.get(key); + if (loader == null) { + // Haven't started loading the avatar, so do it now + loader = new AvatarLoader(address, pixel_size); + this.loaders.set(key, loader); + yield loader.load(this.session, load_cancelled); + } else { + // Load has already started, so wait for it to finish + yield loader.lock.wait_async(); + } + return loader.avatar; + } + + } + + + // Initiates and manages an avatar load + private class AvatarLoader : Geary.BaseObject { + + + internal Gdk.Pixbuf? avatar = null; + internal Geary.Nonblocking.Semaphore lock = + new Geary.Nonblocking.Semaphore(); + + private Geary.RFC822.MailboxAddress address; + private int pixel_size; + + + internal AvatarLoader(Geary.RFC822.MailboxAddress address, + int pixel_size) { + this.address = address; + this.pixel_size = pixel_size; + } + + internal async void load(Soup.Session session, + Cancellable load_cancelled) + throws Error { + Soup.Message message = new Soup.Message( + "GET", + Gravatar.get_image_uri( + this.address, + Gravatar.Default.NOT_FOUND, + this.pixel_size + ) + ); + + Error? workaround_err = null; + try { + // We want to just pass load_cancelled to send_async + // here, but per Bug 778720 this is causing some + // crashy race in libsoup's cache implementation, so + // for now just let the load go through and manually + // check to see if the load has been cancelled before + // setting the avatar + InputStream data = yield session.send_async( + message, + null // should be 'load_cancelled' + ); + if (message.status_code == 200 && + data != null && + !load_cancelled.is_cancelled()) { + this.avatar = yield new Gdk.Pixbuf.from_stream_at_scale_async( + data, pixel_size, pixel_size, true, load_cancelled + ); + } + } catch (Error err) { + workaround_err = err; + } + + this.lock.blind_notify(); + + if (workaround_err != null) { + throw workaround_err; + } + } + + } + + static construct { // Set up custom keybindings unowned Gtk.BindingSet bindings = Gtk.BindingSet.by_class( @@ -317,7 +422,10 @@ // Contacts for the account this conversation exists in private Geary.ContactStore contact_store; - // Contacts for the account this conversation exists in + // Avatars for this conversation + private AvatarStore avatar_store; + + // Account this conversation belongs to private Geary.AccountInformation account_info; // Was this conversation loaded from the drafts folder? @@ -333,7 +441,7 @@ private ConversationEmail? body_selected_view = null; // Maps displayed emails to their corresponding rows. - private Gee.HashMap email_rows = + private Gee.Map email_rows = new Gee.HashMap(); // The id of the draft referred to by the current composer. @@ -416,11 +524,14 @@ Geary.AccountInformation account_info, bool is_draft_folder, Configuration config, + Soup.Session avatar_session, Gtk.Adjustment adjustment) { + base_ref(); this.conversation = conversation; this.location = location; this.email_store = email_store; this.contact_store = contact_store; + this.avatar_store = new AvatarStore(avatar_session); this.account_info = account_info; this.is_draft_folder = is_draft_folder; this.config = config; @@ -458,6 +569,10 @@ }); } + ~ConversationListBox() { + base_unref(); + } + public override void destroy() { if (this.loading_timeout_id != 0) { Source.remove(this.loading_timeout_id); @@ -507,7 +622,9 @@ // Start the first expanded row loading before any others, // scroll the view to it when its done - yield first_expanded_row.view.start_loading(this.cancellable); + yield first_expanded_row.view.start_loading( + this.avatar_store, this.cancellable + ); first_expanded_row.should_scroll.connect(scroll_to); first_expanded_row.enable_should_scroll(); @@ -516,7 +633,9 @@ if (!this.cancellable.is_cancelled()) { EmailRow? row = child as EmailRow; if (row != null && row != first_expanded_row) { - row.view.start_loading.begin(this.cancellable); + row.view.start_loading.begin( + this.avatar_store, this.cancellable + ); } } }); @@ -773,7 +892,7 @@ if (!this.cancellable.is_cancelled()) { EmailRow row = add_email(full_email); update_first_last_row(); - yield row.view.start_loading(this.cancellable); + yield row.view.start_loading(this.avatar_store, this.cancellable); } } @@ -863,11 +982,8 @@ y = alloc.y - EMAIL_TOP_OFFSET; } - // XXX This doesn't always quite work right, maybe since it's - // hard getting a reliable height out of WebKitGTK, or maybe - // because we stop calling this method when the email message - // body has finished loading, but attachments and sub-messages - // may still be loading. Or both? + // Use set_value rather than clamp_value since we want to + // scroll to the top of the window. get_adjustment().set_value(y); } diff -Nru geary-0.12.0/src/client/conversation-viewer/conversation-message.vala geary-0.12.4/src/client/conversation-viewer/conversation-message.vala --- geary-0.12.0/src/client/conversation-viewer/conversation-message.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/conversation-viewer/conversation-message.vala 2018-08-29 13:57:20.000000000 +0000 @@ -15,7 +15,7 @@ * embeds at least one instance of this class. */ [GtkTemplate (ui = "/org/gnome/Geary/conversation-message.ui")] -public class ConversationMessage : Gtk.Grid { +public class ConversationMessage : Gtk.Grid, Geary.BaseInterface { private const string FROM_CLASS = "geary-from"; @@ -263,7 +263,7 @@ /** - * Constructs a new view to display an RFC 823 message headers and body. + * Constructs a new view to display an RFC 822 message headers and body. * * This method sets up most of the user interface for displaying * the message, but does not attempt any possibly long-running @@ -272,6 +272,7 @@ public ConversationMessage(Geary.RFC822.Message message, Configuration config, bool load_remote_images) { + base_ref(); this.message = message; this.is_loading_images = load_remote_images; @@ -404,6 +405,10 @@ ); } + ~ConversationMessage() { + base_unref(); + } + public override void destroy() { this.show_progress_timeout.reset(); this.hide_progress_timeout.reset(); @@ -433,35 +438,34 @@ /** * Starts loading the avatar for the message's sender. */ - public async void load_avatar(Soup.Session session, Cancellable load_cancelled) { + public async void load_avatar(ConversationListBox.AvatarStore loader, + Cancellable load_cancelled) { + const int PIXEL_SIZE = 32; Geary.RFC822.MailboxAddress? primary = message.get_primary_originator(); if (primary != null) { int window_scale = get_scale_factor(); - int pixel_size = this.avatar.get_pixel_size(); - Soup.Message message = new Soup.Message( - "GET", - Gravatar.get_image_uri( - primary, Gravatar.Default.NOT_FOUND, pixel_size * window_scale - ) - ); - + // We occasionally get crashes calling as below + // Gtk.Image.get_pixel_size() when the image is + // null. There's perhaps some race going on there. So we + // need to hard-code the size and keep it in sync with + // ui/conversation-message.ui. :( + // + //int pixel_size = this.avatar.get_pixel_size() * window_scale; + int pixel_size = PIXEL_SIZE * window_scale; try { - // We want to just pass load_cancelled to send_async - // here, but per Bug 778720 this is causing some - // crashy race in libsoup's cache implementation, so - // for now just let the load go through and manually - // check to see if the load has been cancelled before - // setting the avatar - InputStream data = yield session.send_async( - message, - null // should be 'load_cancelled' + Gdk.Pixbuf? avatar_buf = yield loader.load( + primary, pixel_size, load_cancelled ); - if (!load_cancelled.is_cancelled() && - data != null && message.status_code == 200) { - yield set_avatar(data, load_cancelled); + if (avatar_buf != null) { + this.avatar.set_from_surface( + Gdk.cairo_surface_create_from_pixbuf( + avatar_buf, window_scale, get_window() + ) + ); } } catch (Error err) { - debug("Error loading Gravatar response: %s", err.message); + debug("Avatar load failed for %s: %s", + primary.to_string(), err.message); } } } @@ -654,28 +658,6 @@ } } - private async void set_avatar(InputStream data, - Cancellable load_cancelled) - throws Error { - Gdk.Pixbuf avatar_buf = - yield new Gdk.Pixbuf.from_stream_async(data, load_cancelled); - - if (avatar_buf != null && !load_cancelled.is_cancelled()) { - int window_scale = get_scale_factor(); - int avatar_size = this.avatar.pixel_size * window_scale; - if (avatar_buf.width != avatar_size) { - avatar_buf = avatar_buf.scale_simple( - avatar_size, avatar_size, Gdk.InterpType.BILINEAR - ); - } - this.avatar.set_from_surface( - Gdk.cairo_surface_create_from_pixbuf( - avatar_buf, window_scale, get_window() - ) - ); - } - } - // This delegate is called from within Geary.RFC822.Message.get_body while assembling the plain // or HTML document when a non-text MIME part is encountered within a multipart/mixed container. // If this returns null, the MIME part is dropped from the final returned document; otherwise, diff -Nru geary-0.12.0/src/client/conversation-viewer/conversation-viewer.vala geary-0.12.4/src/client/conversation-viewer/conversation-viewer.vala --- geary-0.12.0/src/client/conversation-viewer/conversation-viewer.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/conversation-viewer/conversation-viewer.vala 2018-08-29 13:57:20.000000000 +0000 @@ -10,7 +10,7 @@ * Displays the messages in a conversation and in-window composers. */ [GtkTemplate (ui = "/org/gnome/Geary/conversation-viewer.ui")] -public class ConversationViewer : Gtk.Stack { +public class ConversationViewer : Gtk.Stack, Geary.BaseInterface { /** * The current conversation listbox, if any. @@ -68,6 +68,8 @@ * Constructs a new conversation view instance. */ public ConversationViewer() { + base_ref(); + EmptyPlaceholder no_conversations = new EmptyPlaceholder(); no_conversations.title = _("No conversations selected"); no_conversations.subtitle = _( @@ -103,6 +105,10 @@ this.conversation_find_bar.connect_entry(this.conversation_find_entry); } + ~ConversationViewer() { + base_unref(); + } + /** * Puts the view into composer mode, showing a full-height composer. */ @@ -139,15 +145,23 @@ this.conversation_scroller ); + // We need to disable kinetic scrolling so that if it still + // has some momentum when the composer is inserted and + // scrolled to, it won't jump away again. See Bug 778027. + conversation_scroller.kinetic_scrolling = false; + if (this.current_list != null) { this.current_list.add_embedded_composer(embed, is_draft); } + + conversation_scroller.kinetic_scrolling = true; } /** * Shows the loading UI. */ public void show_loading() { + this.loading_page.start(); set_visible_child(this.loading_page); } @@ -183,7 +197,9 @@ * Shows a conversation in the viewer. */ public async void load_conversation(Geary.App.Conversation conversation, - Geary.Folder location) + Geary.Folder location, + Configuration config, + Soup.Session avatar_session) throws Error { remove_current_list(); @@ -195,7 +211,8 @@ account.get_contact_store(), account.information, location.special_folder_type == Geary.SpecialFolderType.DRAFTS, - ((MainWindow) get_ancestor(typeof(MainWindow))).application.config, + config, + avatar_session, this.conversation_scroller.get_vadjustment() ); @@ -285,13 +302,19 @@ */ private new void set_visible_child(Gtk.Widget widget) { debug("Showing: %s", widget.get_name()); - if (widget != this.conversation_page && - get_visible_child() == this.conversation_page) { - // By removing the current list, any load it is currently - // performing is also cancelled, which is important to - // avoid a possible crit warning when switching folders, - // etc. - remove_current_list(); + Gtk.Widget current = get_visible_child(); + if (current == this.conversation_page) { + if (widget != this.conversation_page) { + // By removing the current list, any load it is currently + // performing is also cancelled, which is important to + // avoid a possible crit warning when switching folders, + // etc. + remove_current_list(); + } + } else if (current == this.loading_page) { + // Stop the spinner running so it doesn't trigger repaints + // and wake up Geary even when idle. See Bug 783025. + this.loading_page.stop(); } base.set_visible_child(widget); } diff -Nru geary-0.12.0/src/client/conversation-viewer/conversation-web-view.vala geary-0.12.4/src/client/conversation-viewer/conversation-web-view.vala --- geary-0.12.0/src/client/conversation-viewer/conversation-web-view.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/conversation-viewer/conversation-web-view.vala 2018-08-29 13:57:20.000000000 +0000 @@ -15,7 +15,7 @@ // Key codes we don't forward on to the super class on key press // since we want to override them elsewhere, especially // ConversationListBox. - private const int[] BLACKLISTED_KEY_CODES = { + private const uint[] BLACKLISTED_KEY_CODES = { Gdk.Key.space, Gdk.Key.KP_Space, Gdk.Key.Up, diff -Nru geary-0.12.0/src/client/dialogs/attachment-dialog.vala geary-0.12.4/src/client/dialogs/attachment-dialog.vala --- geary-0.12.0/src/client/dialogs/attachment-dialog.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/dialogs/attachment-dialog.vala 2018-08-29 13:57:20.000000000 +0000 @@ -60,7 +60,12 @@ public int run() { int response = this.chooser.run(); if (response == Gtk.ResponseType.ACCEPT) { - this.config.attachments_dir = this.chooser.get_current_folder(); + // Current folder can be null, e.g. if selecting an + // attachment from Recent Files + string? current_folder = this.chooser.get_current_folder(); + if (!Geary.String.is_empty(current_folder)) { + this.config.attachments_dir = current_folder; + } } return response; } diff -Nru geary-0.12.0/src/client/folder-list/folder-list-account-branch.vala geary-0.12.4/src/client/folder-list/folder-list-account-branch.vala --- geary-0.12.0/src/client/folder-list/folder-list-account-branch.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/folder-list/folder-list-account-branch.vala 2018-08-29 13:57:20.000000000 +0000 @@ -20,14 +20,14 @@ account.information.notify["nickname"].connect(on_nicknamed_changed); - graft(get_root(), user_folder_group); - entry_removed.connect(on_entry_removed); + entry_moved.connect(check_user_folders); } ~AccountBranch() { account.information.notify["nickname"].disconnect(on_nicknamed_changed); entry_removed.disconnect(on_entry_removed); + entry_moved.disconnect(check_user_folders); } private void on_nicknamed_changed() { @@ -87,6 +87,10 @@ } else if (folder.path.get_parent() == null) { // Top-level folders get put in our special user folders group. graft_point = user_folder_group; + + if (!has_entry(user_folder_group)) { + graft(get_root(), user_folder_group); + } } else { Sidebar.Entry? entry = folder_entries.get(folder.path.get_parent()); if (entry != null) @@ -129,5 +133,16 @@ FolderEntry? folder_entry = entry as FolderEntry; if (folder_entry != null && folder_entries.has_key(folder_entry.folder.path)) folder_entries.unset(folder_entry.folder.path); + + check_user_folders(entry); + } + + private void check_user_folders(Sidebar.Entry entry) { + if (entry != user_folder_group) { + // remove "Labels" entry if there are no more user entries + if (has_entry(user_folder_group) && (get_child_count(user_folder_group) == 0)) { + prune(user_folder_group); + } + } } } diff -Nru geary-0.12.0/src/client/folder-list/folder-list-tree.vala geary-0.12.4/src/client/folder-list/folder-list-tree.vala --- geary-0.12.0/src/client/folder-list/folder-list-tree.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/folder-list/folder-list-tree.vala 2018-08-29 13:57:20.000000000 +0000 @@ -4,7 +4,7 @@ * (version 2.1 or later). See the COPYING file in this distribution. */ -public class FolderList.Tree : Sidebar.Tree { +public class FolderList.Tree : Sidebar.Tree, Geary.BaseInterface { public const Gtk.TargetEntry[] TARGET_ENTRY_LIST = { { "application/x-geary-mail", Gtk.TargetFlags.SAME_APP, 0 } }; @@ -21,9 +21,10 @@ private InboxesBranch inboxes_branch = new InboxesBranch(); private SearchBranch? search_branch = null; private NewMessagesMonitor? monitor = null; - + public Tree() { base(new Gtk.TargetEntry[0], Gdk.DragAction.ASK, drop_handler); + base_ref(); entry_selected.connect(on_entry_selected); // Set self as a drag destination. @@ -52,11 +53,12 @@ """ ); } - + ~Tree() { set_new_messages_monitor(null); + base_unref(); } - + private void drop_handler(Gdk.DragContext context, Sidebar.Entry? entry, Gtk.SelectionData data, uint info, uint time) { } diff -Nru geary-0.12.0/src/client/notification/libnotify.vala geary-0.12.4/src/client/notification/libnotify.vala --- geary-0.12.0/src/client/notification/libnotify.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/notification/libnotify.vala 2018-08-29 13:57:20.000000000 +0000 @@ -158,9 +158,9 @@ // Avoid constructor due to ABI change Notify.Notification notification = (Notify.Notification) GLib.Object.new( typeof (Notify.Notification), - "icon-name", "geary", + "icon-name", "org.gnome.Geary", "summary", GLib.Environment.get_application_name()); - notification.set_hint_string("desktop-entry", "geary"); + notification.set_hint_string("desktop-entry", "org.gnome.Geary"); if (caps.find_custom("actions", GLib.strcmp) != null) notification.add_action("default", _("Open"), on_default_action); diff -Nru geary-0.12.0/src/client/sidebar/sidebar-branch.vala geary-0.12.4/src/client/sidebar/sidebar-branch.vala --- geary-0.12.0/src/client/sidebar/sidebar-branch.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/sidebar/sidebar-branch.vala 2018-08-29 13:57:20.000000000 +0000 @@ -6,7 +6,7 @@ public delegate bool Locator(G item); -public class Sidebar.Branch : Object { +public class Sidebar.Branch : Geary.BaseObject { [Flags] public enum Options { NONE = 0, diff -Nru geary-0.12.0/src/client/sidebar/sidebar-common.vala geary-0.12.4/src/client/sidebar/sidebar-common.vala --- geary-0.12.0/src/client/sidebar/sidebar-common.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/sidebar/sidebar-common.vala 2018-08-29 13:57:20.000000000 +0000 @@ -5,7 +5,7 @@ */ // A simple grouping Entry that is only expandable -public class Sidebar.Grouping : Object, Sidebar.Entry, Sidebar.ExpandableEntry, +public class Sidebar.Grouping : Geary.BaseObject, Sidebar.Entry, Sidebar.ExpandableEntry, Sidebar.RenameableEntry { private string name; diff -Nru geary-0.12.0/src/client/sidebar/sidebar-tree.vala geary-0.12.4/src/client/sidebar/sidebar-tree.vala --- geary-0.12.0/src/client/sidebar/sidebar-tree.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/client/sidebar/sidebar-tree.vala 2018-08-29 13:57:20.000000000 +0000 @@ -641,10 +641,10 @@ private void on_branch_entry_removed(Sidebar.Branch branch, Sidebar.Entry entry) { EntryWrapper? wrapper = get_wrapper(entry); - assert(wrapper != null); - assert(!(wrapper is RootWrapper)); - - disassociate_wrapper_and_signal(wrapper, false); + if (wrapper != null) { + assert(!(wrapper is RootWrapper)); + disassociate_wrapper_and_signal(wrapper, false); + } } private void on_branch_entry_moved(Sidebar.Branch branch, Sidebar.Entry entry) { diff -Nru geary-0.12.0/src/CMakeLists.txt geary-0.12.4/src/CMakeLists.txt --- geary-0.12.0/src/CMakeLists.txt 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/CMakeLists.txt 2018-08-29 13:57:20.000000000 +0000 @@ -124,7 +124,6 @@ engine/imap/message/imap-flags.vala engine/imap/message/imap-internal-date.vala engine/imap/message/imap-mailbox-specifier.vala -engine/imap/message/imap-mailbox-parameter.vala engine/imap/message/imap-message-data.vala engine/imap/message/imap-message-flag.vala engine/imap/message/imap-message-flags.vala diff -Nru geary-0.12.0/src/engine/api/geary-account-information.vala geary-0.12.4/src/engine/api/geary-account-information.vala --- geary-0.12.0/src/engine/api/geary-account-information.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/api/geary-account-information.vala 2018-08-29 13:57:20.000000000 +0000 @@ -138,7 +138,6 @@ // being saved. get { return (allow_save_sent_mail() ? _save_sent_mail : true); } set { _save_sent_mail = value; } - default = true; } // Order for display purposes. @@ -466,8 +465,8 @@ /** * Sets the path Geary will look for or create a special folder. This is * only obeyed if the server doesn't tell Geary which folders are special. - * Only the DRAFTS, SENT, SPAM, and TRASH special folder types are valid to - * pass to this function. + * Only the DRAFTS, SENT, SPAM, TRASH and ARCHIVE special folder types are + * valid to pass to this function. */ public void set_special_folder_path(Geary.SpecialFolderType special, Geary.FolderPath? path) { switch (special) { diff -Nru geary-0.12.0/src/engine/api/geary-attachment.vala geary-0.12.4/src/engine/api/geary-attachment.vala --- geary-0.12.0/src/engine/api/geary-attachment.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/api/geary-attachment.vala 2018-08-29 13:57:20.000000000 +0000 @@ -155,7 +155,7 @@ } } string? ext = mime_type.get_file_name_extension(); - if (!file_name.has_suffix(ext)) { + if (ext != null && !file_name.has_suffix(ext)) { file_name = file_name + (ext ?? ""); } } diff -Nru geary-0.12.0/src/engine/api/geary-base-object.vala geary-0.12.4/src/engine/api/geary-base-object.vala --- geary-0.12.0/src/engine/api/geary-base-object.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/api/geary-base-object.vala 2018-08-29 13:57:20.000000000 +0000 @@ -1,64 +1,189 @@ -/* Copyright 2016 Software Freedom Conservancy Inc. +/* + * Copyright 2016 Software Freedom Conservancy Inc. + * Copyright 2018 Michael Gratton * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ -public abstract class Geary.BaseObject : Object { #if REF_TRACKING - private static Gee.HashMap? refmap = null; - +private class Counts { + public int created = 0; + public int destroyed = 0; +} + +private static GLib.Mutex reflock; +private static Gee.HashMap refmap; +#endif + +/** + * Common parent class for Geary Engine objects. + * + * Most Engine classes should be derived from this class to be able to + * access common functionality. + * + * Currently, this class enables automatic application-based reference + * tracking of objects, which can assist in tracking down memory + * leaks. To enable this, set the //ref_track// compile time option to + * true and compile. An application can then call {@link dump_refs} to + * output a list of objects with both instantiation and destruction + * counts. + * + * This class can only be used for classes that would otherwise derive + * directly from GLib.Object. If a class must be derived from some + * other pre-existing class, it is possible to use {@link + * BaseInterface} as a mixin with a little extra work instead. + */ +public abstract class Geary.BaseObject : Geary.BaseInterface, Object { + +#if REF_TRACKING + static construct { + reflock = GLib.Mutex(); + refmap = new Gee.HashMap( + // because strings are unowned and guaranteed to be + // unique by GType, use direct comparison functions, + // more efficient then string hash/equal + Gee.Functions.get_hash_func_for(typeof(void*)), + Gee.Functions.get_equal_func_for(typeof(void*)) + ); + } +#endif + + /** + * Constructs a new base object. + * + * This constructor automatically increments the reference count + * by calling {@link BaseInterface.base_ref} if reference tracking + * is enabled at compile-time, otherwise this is a no-op. + */ protected BaseObject() { - lock (refmap) { - if (refmap == null) { - // because strings are unowned and guaranteed to be - // unique by GType, use direct comparison functions, - // more efficient then string hash/equal - refmap = new Gee.HashMap( - Gee.Functions.get_hash_func_for(typeof(void*)), - Gee.Functions.get_equal_func_for(typeof(void*))); - } - - unowned string classname = get_classname(); - refmap.set(classname, refmap.get(classname) + 1); - } +#if REF_TRACKING + base_ref(); +#endif } - + + /** + * Destructs an existing base object. + * + * This constructor automatically decrements the reference count + * by calling {@link BaseInterface.base_unref} if reference + * tracking is enabled at compile-time, otherwise this is a no-op. + */ ~BaseObject() { - lock (refmap) { - unowned string classname = get_classname(); - int count = refmap.get(classname) - 1; - if (count == 0) - refmap.unset(classname); - else - refmap.set(classname, count); - } - } - - private unowned string get_classname() { - return get_class().get_type().name(); +#if REF_TRACKING + base_unref(); +#endif } - + + /** + * Dumps reference counting logs to the given stream. + * + * This method prints a list of reference-counted classes, and the + * number of times each was constructed and destructed along with + * a flag indicating those that are not equal. If reference + * tracking was not enabled at compile-time, this is no-op. + */ public static void dump_refs(FileStream outs) { - if (refmap == null || refmap.size == 0) { +#if REF_TRACKING + if (!refmap.is_empty) { + Gee.ArrayList list = new Gee.ArrayList(); + list.add_all(refmap.keys); + list.sort(); + outs.printf("? created/destroyed class\n"); + foreach (unowned string classname in list) { + Counts? counts = refmap.get(classname); + string alert = " "; + if (counts.created != counts.destroyed) { + double leak_rate = (counts.created - counts.destroyed) / counts.created; + alert = (leak_rate > 0.1) ? "!" : "*"; + } + outs.printf( + "%s %9d/%9d %s\n", + alert, + counts.created, + counts.destroyed, + classname + ); + } + } else { outs.printf("No references to report.\n"); - - return; } - - Gee.ArrayList list = new Gee.ArrayList(); - list.add_all(refmap.keys); - list.sort(); - foreach (unowned string classname in list) - outs.printf("%9d %s\n", refmap.get(classname), classname); +#endif } -#else - protected BaseObject() { + +} + +/** + * Base mixin interface for Engine objects derived from another. + * + * This interface provides an analogue to {@link BaseObject} for + * objects that must be derived from an existing class, such a GTK + * widget. Since this is simply a mixin, some additional work is + * required to use this interface compared to BaseObject. + * + * To use this interface, declare it as a parent of your class and + * call {@link base_ref} immediately after the base constructor is + * called, and call {@link base_unref} at the end of the destructor: + * + * public class CustomWidget : Gtk.Widget, Geary.BaseInterface { + * + * public CustomWidget() { + * base_ref(); + * ... + * } + * + * ~CustomWidget() { + * ... + * base_unref(); + * } + * + * } + * + * Care must be taken to ensure that if {@link base_unref} is not + * called for an instance if {@link base_ref} was not called. + */ +public interface Geary.BaseInterface { + + /** + * Increments the reference count for the implementing class. + * + * Implementing classes should call this as soon as possible after + * the base class's constructor is called. This method is a no-op + * if reference tracking is not enabled at compile-time. + */ + protected void base_ref() { +#if REF_TRACKING + reflock.lock(); + unowned string classname = get_classname(); + Counts? counts = refmap.get(classname); + if (counts == null) { + counts = new Counts(); + refmap.set(classname, counts); + } + counts.created++; + reflock.unlock(); +#endif } - - public static void dump(FileStream outs) { - outs.printf("Reference tracking disabled.\n"); + + /** + * Decrements the reference count for the implementing class. + * + * Implementing classes should call this at the end of the class's + * destructor. This method is a no-op if reference tracking is not + * enabled at compile-time. + */ + protected void base_unref() { +#if REF_TRACKING + reflock.lock(); + refmap.get(get_classname()).destroyed++; + reflock.unlock(); +#endif } + +#if REF_TRACKING + private unowned string get_classname() { + return ((Object) this).get_type().name(); + } + #endif } - diff -Nru geary-0.12.0/src/engine/imap/api/imap-account.vala geary-0.12.4/src/engine/imap/api/imap-account.vala --- geary-0.12.0/src/engine/imap/api/imap-account.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/api/imap-account.vala 2018-08-29 13:57:20.000000000 +0000 @@ -257,7 +257,8 @@ public async void create_folder_async(FolderPath path, Cancellable? cancellable) throws Error { check_open(); - + yield claim_session_async(cancellable); + StatusResponse response = yield send_command_async(new CreateCommand( new MailboxSpecifier.from_folder_path(path, this.hierarchy_delimiter)), null, null, cancellable); diff -Nru geary-0.12.0/src/engine/imap/message/imap-data-format.vala geary-0.12.4/src/engine/imap/message/imap-data-format.vala --- geary-0.12.0/src/engine/imap/message/imap-data-format.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/message/imap-data-format.vala 2018-08-29 13:57:20.000000000 +0000 @@ -7,7 +7,10 @@ namespace Geary.Imap.DataFormat { private const char[] ATOM_SPECIALS = { - '(', ')', '{', ' ', '%', '*', '"' + '(', ')', '{', ' ', // CTL chars are handled by is_special_char + '%', '*', // list-wildcards + '"', '\\', // quoted-specials + ']' // resp-specials }; private const char[] TAG_SPECIALS = { @@ -21,11 +24,14 @@ } private bool is_special_char(char ch, char[] ar, string? exceptions) { - if (ch > 0x7F || ch.iscntrl()) + // Check for CTL chars + if (ch <= 0x1F || ch >= 0x7F) { return true; + } - if (ch in ar) - return (exceptions != null) ? exceptions.index_of_char(ch) < 0 : true; + if (ch in ar) { + return (exceptions != null) ? Ascii.index_of(exceptions, ch) < 0 : true; + } return false; } diff -Nru geary-0.12.0/src/engine/imap/message/imap-fetch-body-data-specifier.vala geary-0.12.4/src/engine/imap/message/imap-fetch-body-data-specifier.vala --- geary-0.12.0/src/engine/imap/message/imap-fetch-body-data-specifier.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/message/imap-fetch-body-data-specifier.vala 2018-08-29 13:57:20.000000000 +0000 @@ -73,15 +73,15 @@ assert_not_reached(); } } - + public static SectionPart deserialize(string value) throws ImapError { if (String.is_empty(value)) return NONE; - - switch (value.down()) { + + switch (Ascii.strdown(value)) { case "header": return HEADER; - + case "header.fields": return HEADER_FIELDS; @@ -178,25 +178,23 @@ this.subset_start = subset_start; this.subset_count = subset_count; this.is_peek = is_peek; - + if (field_names != null && field_names.length > 0) { - this.field_names = new Gee.TreeSet((s1, s2) => { - return GLib.strcmp(s1, s2); - }); + this.field_names = new Gee.TreeSet(Ascii.strcmp); foreach (string field_name in field_names) { - string converted = field_name.strip().down(); - + string converted = Ascii.strdown(field_name.strip()); + if (!String.is_empty(converted)) this.field_names.add(converted); } } else { this.field_names = null; } - + // see equal_to() for why the response version is used hashable = serialize_response(); } - + /** * Returns the {@link FetchBodyDataSpecifier} in a string ready for a {@link Command}. * diff -Nru geary-0.12.0/src/engine/imap/message/imap-flag.vala geary-0.12.4/src/engine/imap/message/imap-flag.vala --- geary-0.12.0/src/engine/imap/message/imap-flag.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/message/imap-flag.vala 2018-08-29 13:57:20.000000000 +0000 @@ -15,11 +15,16 @@ public abstract class Geary.Imap.Flag : BaseObject, Gee.Hashable { public string value { get; private set; } - - public Flag(string value) { - this.value = value; + + /** + * Constructs a new flag. + * + * The given keyword must be an IMAP atom. + */ + public Flag(string name) { + this.value = name; } - + public bool is_system() { return value[0] == '\\'; } @@ -31,14 +36,14 @@ public bool equal_to(Geary.Imap.Flag flag) { return (flag == this) ? true : flag.equals_string(value); } - + /** * Returns the {@link Flag} as an appropriate {@link Parameter}. */ public StringParameter to_parameter() throws ImapError { - return StringParameter.get_best_for(value); + return new UnquotedStringParameter(value); } - + public uint hash() { return Ascii.stri_hash(value); } diff -Nru geary-0.12.0/src/engine/imap/message/imap-internal-date.vala geary-0.12.4/src/engine/imap/message/imap-internal-date.vala --- geary-0.12.0/src/engine/imap/message/imap-internal-date.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/message/imap-internal-date.vala 2018-08-29 13:57:20.000000000 +0000 @@ -64,18 +64,18 @@ || year < 1970) { throw new ImapError.PARSE_ERROR("Invalid INTERNALDATE \"%s\": bad numerical range", internaldate); } - + // check month (this catches localization problems) int month = -1; - string mon_down = ((string) mon).down(); + string mon_down = Ascii.strdown(((string) mon)); for (int ctr = 0; ctr < EN_US_MON_DOWN.length; ctr++) { if (mon_down == EN_US_MON_DOWN[ctr]) { month = ctr; - + break; } } - + if (month < 0) throw new ImapError.PARSE_ERROR("Invalid INTERNALDATE \"%s\": bad month", internaldate); diff -Nru geary-0.12.0/src/engine/imap/message/imap-mailbox-parameter.vala geary-0.12.4/src/engine/imap/message/imap-mailbox-parameter.vala --- geary-0.12.0/src/engine/imap/message/imap-mailbox-parameter.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/message/imap-mailbox-parameter.vala 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* Copyright 2016 Software Freedom Conservancy Inc. - * - * This software is licensed under the GNU Lesser General Public License - * (version 2.1 or later). See the COPYING file in this distribution. - */ - -/** - * A {@link StringParameter} that holds a mailbox reference (can be wildcarded). - * - * Used to juggle between our internal UTF-8 representation of mailboxes and IMAP's - * odd "modified UTF-7" representation. The value is stored in IMAP's encoded - * format since that's how it comes across the wire. - */ - -public class Geary.Imap.MailboxParameter : StringParameter { - public MailboxParameter(string mailbox) { - base (utf8_to_imap_utf7(mailbox)); - } - - public MailboxParameter.from_string_parameter(StringParameter string_parameter) { - base (string_parameter.ascii); - } - - private static string utf8_to_imap_utf7(string utf8) { - try { - return Geary.ImapUtf7.utf8_to_imap_utf7(utf8); - } catch (ConvertError e) { - debug("Error encoding mailbox name '%s': %s", utf8, e.message); - return utf8; - } - } - - private static string imap_utf7_to_utf8(string imap_utf7) { - try { - return Geary.ImapUtf7.imap_utf7_to_utf8(imap_utf7); - } catch (ConvertError e) { - debug("Invalid mailbox name '%s': %s", imap_utf7, e.message); - return imap_utf7; - } - } - - public string decode() { - return imap_utf7_to_utf8(ascii); - } - - /** - * {@inheritDoc} - */ - public override void serialize(Serializer ser, Tag tag) throws Error { - serialize_string(ser); - } - - /** - * {@inheritDoc} - */ - public override string to_string() { - return ascii; - } -} - diff -Nru geary-0.12.0/src/engine/imap/message/imap-mailbox-specifier.vala geary-0.12.4/src/engine/imap/message/imap-mailbox-specifier.vala --- geary-0.12.0/src/engine/imap/message/imap-mailbox-specifier.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/message/imap-mailbox-specifier.vala 2018-08-29 13:57:20.000000000 +0000 @@ -43,15 +43,37 @@ * See [[http://tools.ietf.org/html/rfc3501#section-5.1]] */ public bool is_inbox { get; private set; } - + + /** + * Constructs a new specifier from a UTF-8 name. + */ public MailboxSpecifier(string name) { init(name); } - - public MailboxSpecifier.from_parameter(MailboxParameter param) { - init(param.decode()); + + /** + * Constructs a new specifier from a IMAP modified-UTF-7 string. + * + * If a modified-UTF-7 decoding error occurs, the parameter will + * assumed to be UTF-8, repaired, and used instead. + */ + public MailboxSpecifier.from_parameter(StringParameter param) { + string? name = null; + try { + name = Geary.ImapUtf7.imap_utf7_to_utf8(param.ascii); + } catch (ConvertError err) { + // Could no decode the name as IMAP modified UTF7, so per + // https://imapwiki.org/ClientImplementation/MailboxList + // assume UTF8. + debug( + "Error decoding mailbox name, assuming UTF-8: %s", err.message + ); + name = param.ascii; + } + + init(name); } - + /** * Returns true if the {@link Geary.FolderPath} points to the IMAP Inbox. */ @@ -72,7 +94,7 @@ public static bool is_inbox_name(string name) { return Ascii.stri_equal(name, CANONICAL_INBOX_NAME); } - + /** * Returns true if the string is the ''canonical'' name of the IMAP Inbox. * @@ -85,9 +107,9 @@ * @see is_inbox_name */ public static bool is_canonical_inbox_name(string name) { - return (name == CANONICAL_INBOX_NAME); + return Ascii.str_equal(name, CANONICAL_INBOX_NAME); } - + /** * Converts a generic {@link FolderPath} into an IMAP mailbox specifier. */ @@ -167,35 +189,42 @@ return !String.is_empty(basename) ? basename : name; } - + public Parameter to_parameter() { - return new MailboxParameter(name); + string encoded= Geary.ImapUtf7.utf8_to_imap_utf7(this.name); + Parameter? param = null; + try { + param = StringParameter.get_best_for(encoded); + } catch (ImapError err) { + param = new LiteralParameter(new Geary.Memory.StringBuffer(encoded)); + } + return param; } - + public uint hash() { return is_inbox ? Ascii.stri_hash(name) : Ascii.str_hash(name); } - + public bool equal_to(MailboxSpecifier other) { if (this == other) return true; - + if (is_inbox) return Ascii.stri_equal(name, other.name); - - return (name == other.name); + + return Ascii.str_equal(name, other.name); } - + public int compare_to(MailboxSpecifier other) { if (this == other) return 0; - + if (is_inbox && other.is_inbox) return 0; - - return GLib.strcmp(name, other.name); + + return Ascii.strcmp(name, other.name); } - + public string to_string() { return name; } diff -Nru geary-0.12.0/src/engine/imap/parameter/imap-string-parameter.vala geary-0.12.4/src/engine/imap/parameter/imap-string-parameter.vala --- geary-0.12.0/src/engine/imap/parameter/imap-string-parameter.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/parameter/imap-string-parameter.vala 2018-08-29 13:57:20.000000000 +0000 @@ -134,35 +134,35 @@ public bool is_empty() { return String.is_empty(ascii); } - + /** * Case-sensitive comparison. */ public bool equals_cs(string value) { - return (ascii == value); + return Ascii.str_equal(ascii, value); } - + /** * Case-insensitive comparison. */ public bool equals_ci(string value) { return Ascii.stri_equal(ascii, value); } - + /** * Returns the string lowercased. */ public string as_lower() { - return ascii.down(); + return Ascii.strdown(ascii); } - + /** * Returns the string uppercased. */ public string as_upper() { - return ascii.up(); + return Ascii.strup(ascii); } - + /** * Converts the {@link ascii} to a signed 32-bit integer, clamped between clamp_min and * clamp_max. diff -Nru geary-0.12.0/src/engine/imap/response/imap-mailbox-information.vala geary-0.12.4/src/engine/imap/response/imap-mailbox-information.vala --- geary-0.12.0/src/engine/imap/response/imap-mailbox-information.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/response/imap-mailbox-information.vala 2018-08-29 13:57:20.000000000 +0000 @@ -71,19 +71,21 @@ // decode everything MailboxAttributes attributes = new MailboxAttributes(attrlist); StringParameter? delim = server_data.get_as_nullable_string(3); - MailboxParameter mailbox = new MailboxParameter.from_string_parameter( - server_data.get_as_string(4)); - - // Set \Inbox to standard path - if (canonical_inbox && Geary.Imap.MailboxAttribute.SPECIAL_FOLDER_INBOX in attributes) { - return new MailboxInformation(MailboxSpecifier.inbox, - (delim != null) ? delim.nullable_ascii : null, attributes); - } else { - return new MailboxInformation(new MailboxSpecifier.from_parameter(mailbox), - (delim != null) ? delim.nullable_ascii : null, attributes); - } + StringParameter mailbox = server_data.get_as_string(4); + + // If special-use flag \Inbox is set just use the canonical + // Inbox name, otherwise decode it + MailboxSpecifier? specifier = + (canonical_inbox && + Geary.Imap.MailboxAttribute.SPECIAL_FOLDER_INBOX in attributes) + ? MailboxSpecifier.inbox + : new MailboxSpecifier.from_parameter(mailbox); + + return new MailboxInformation( + specifier, (delim != null) ? delim.nullable_ascii : null, attributes + ); } - + /** * The {@link Geary.FolderPath} for the {@link mailbox}. * diff -Nru geary-0.12.0/src/engine/imap/response/imap-response-code-type.vala geary-0.12.4/src/engine/imap/response/imap-response-code-type.vala --- geary-0.12.0/src/engine/imap/response/imap-response-code-type.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/response/imap-response-code-type.vala 2018-08-29 13:57:20.000000000 +0000 @@ -64,17 +64,17 @@ public ResponseCodeType.from_parameter(StringParameter stringp) throws ImapError { init(stringp.ascii); } - + private void init(string ascii) throws ImapError { // note that is_quoting_required() also catches empty strings (as they require quoting) if (DataFormat.is_quoting_required(ascii) != DataFormat.Quoting.OPTIONAL) throw new ImapError.INVALID("\"%s\" cannot be represented as a ResponseCodeType", ascii); - + // store lowercased so it's easily compared with const strings above original = ascii; - value = ascii.down(); + value = Ascii.strdown(ascii); } - + public bool is_value(string str) { return Ascii.stri_equal(value, str); } diff -Nru geary-0.12.0/src/engine/imap/response/imap-status-data.vala geary-0.12.4/src/engine/imap/response/imap-status-data.vala --- geary-0.12.0/src/engine/imap/response/imap-status-data.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/response/imap-status-data.vala 2018-08-29 13:57:20.000000000 +0000 @@ -74,10 +74,9 @@ throw new ImapError.PARSE_ERROR("Bad STATUS command name in response \"%s\"", server_data.to_string()); } - - MailboxParameter mailbox_param = new MailboxParameter.from_string_parameter( - server_data.get_as_string(2)); - + + StringParameter mailbox_param = server_data.get_as_string(2); + int messages = UNSET; int recent = UNSET; UID? uid_next = null; diff -Nru geary-0.12.0/src/engine/imap/transport/imap-deserializer.vala geary-0.12.4/src/engine/imap/transport/imap-deserializer.vala --- geary-0.12.0/src/engine/imap/transport/imap-deserializer.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap/transport/imap-deserializer.vala 2018-08-29 13:57:20.000000000 +0000 @@ -37,7 +37,7 @@ TAG, START_PARAM, ATOM, - SYSTEM_FLAG, + FLAG, QUOTED, QUOTED_ESCAPE, PARTIAL_BODY_ATOM, @@ -72,7 +72,6 @@ state_to_string, event_to_string); private string identifier; - private ConverterInputStream cins; private DataInputStream dins; private Geary.State.Machine fsm; private ListParameter context; @@ -85,8 +84,8 @@ private Geary.Memory.GrowableBuffer? block_buffer = null; private unowned uint8[]? current_buffer = null; private int ins_priority = Priority.DEFAULT; - private char[] atom_specials_exceptions = { ' ', ' ', '\0' }; - + + /** * Fired when a complete set of IMAP {@link Parameter}s have been received. * @@ -99,21 +98,7 @@ * {@link QuotedStringParameter} which allows for some control characters). */ public signal void parameters_ready(RootParameters root); - - /** - * Fired when the underlying InputStream is closed, whether due to normal EOS or input error. - * - * @see receive_failure - */ - public signal void eos(); - - /** - * Fired when an Error is trapped on the input stream. - * - * This is nonrecoverable and means the stream should be closed and this Deserializer destroyed. - */ - public signal void receive_failure(Error err); - + /** * Fired as data blocks are received during download. * @@ -127,7 +112,14 @@ * on the receive channel, especially during long downloads. */ public signal void bytes_received(size_t bytes); - + + /** + * Fired when the underlying InputStream is closed, whether due to normal EOS or input error. + * + * @see receive_failure + */ + public signal void eos(); + /** * Fired when a syntax error has occurred. * @@ -135,11 +127,19 @@ * or impossible. */ public signal void deserialize_failure(); - + + /** + * Fired when an Error is trapped on the input stream. + * + * This is nonrecoverable and means the stream should be closed and this Deserializer destroyed. + */ + public signal void receive_failure(Error err); + + public Deserializer(string identifier, InputStream ins) { this.identifier = identifier; - - cins = new ConverterInputStream(ins, midstream); + + ConverterInputStream cins = new ConverterInputStream(ins, midstream); cins.set_close_base_stream(false); dins = new DataInputStream(cins); dins.set_newline_type(DataStreamNewlineType.CR_LF); @@ -162,10 +162,10 @@ new Geary.State.Mapping(State.ATOM, Event.EOS, on_eos), new Geary.State.Mapping(State.ATOM, Event.ERROR, on_error), - new Geary.State.Mapping(State.SYSTEM_FLAG, Event.CHAR, on_system_flag_char), - new Geary.State.Mapping(State.SYSTEM_FLAG, Event.EOL, on_atom_eol), - new Geary.State.Mapping(State.SYSTEM_FLAG, Event.EOS, on_eos), - new Geary.State.Mapping(State.SYSTEM_FLAG, Event.ERROR, on_error), + new Geary.State.Mapping(State.FLAG, Event.CHAR, on_first_flag_char), + new Geary.State.Mapping(State.FLAG, Event.EOL, on_atom_eol), + new Geary.State.Mapping(State.FLAG, Event.EOS, on_eos), + new Geary.State.Mapping(State.FLAG, Event.ERROR, on_error), new Geary.State.Mapping(State.QUOTED, Event.CHAR, on_quoted_char), new Geary.State.Mapping(State.QUOTED, Event.EOS, on_eos), @@ -195,10 +195,11 @@ new Geary.State.Mapping(State.LITERAL_DATA, Event.DATA, on_literal_data), new Geary.State.Mapping(State.LITERAL_DATA, Event.EOS, on_eos), new Geary.State.Mapping(State.LITERAL_DATA, Event.ERROR, on_error), - + + new Geary.State.Mapping(State.FAILED, Event.EOL, on_failed_eol), new Geary.State.Mapping(State.FAILED, Event.EOS, Geary.State.nop), new Geary.State.Mapping(State.FAILED, Event.ERROR, Geary.State.nop), - + new Geary.State.Mapping(State.CLOSED, Event.EOS, Geary.State.nop), new Geary.State.Mapping(State.CLOSED, Event.ERROR, Geary.State.nop) }; @@ -251,7 +252,28 @@ yield closed_semaphore.wait_async(); debug("[%s] Deserializer closed", to_string()); } - + + /** + * Determines if the deserializer is closed. + */ + public bool is_halted() { + switch (get_mode()) { + case Mode.FAILED: + case Mode.CLOSED: + return true; + + default: + return false; + } + } + + /** + * Returns a string representation of this object for debugging. + */ + public string to_string() { + return "des:%s/%s".printf(identifier, fsm.get_state_string(fsm.get_state())); + } + private void next_deserialize_step() { switch (get_mode()) { case Mode.LINE: @@ -293,15 +315,12 @@ return; } - - Logging.debug(Logging.Flag.DESERIALIZER, "[%s] line %s", to_string(), line); - + + Logging.debug(Logging.Flag.DESERIALIZER, "[%s] line: %s", to_string(), line); bytes_received(bytes_read); - push_line(line, bytes_read); } catch (Error err) { push_error(err); - return; } @@ -322,12 +341,11 @@ } Logging.debug(Logging.Flag.DESERIALIZER, "[%s] block %lub", to_string(), bytes_read); - bytes_received(bytes_read); - + // adjust the current buffer's size to the amount that was actually read in block_buffer.trim(current_buffer, bytes_read); - + push_data(bytes_read); } catch (Error err) { push_error(err); @@ -337,51 +355,37 @@ next_deserialize_step(); } - + // Push a line (without the CRLF!). Because DataInputStream reads to EOL but accepts all other // characters, it's possible for NULs to be embedded in the string, so the count must be passed // as well (and shouldn't be -1!) - private Mode push_line(string line, size_t count) { + private void push_line(string line, size_t count) { assert(get_mode() == Mode.LINE); - + for (long ctr = 0; ctr < count; ctr++) { char ch = line[ctr]; - if (ch == String.EOS) { + if (ch == '\0') { // drop on the floor; IMAP spec does not allow NUL in lines at all, see // http://tools.ietf.org/html/rfc3501#section-9 note 3. - // This also catches the terminating NUL. continue; } - + if (fsm.issue(Event.CHAR, &ch) == State.FAILED) { - deserialize_failure(); - - return Mode.FAILED; + // Don't try to continue processing, but continue to + // EOL regardless for cleanup. + break; } } - - if (fsm.issue(Event.EOL) == State.FAILED) { - deserialize_failure(); - - return Mode.FAILED; - } - - return get_mode(); + + fsm.issue(Event.EOL); } - + // Push a block of literal data - private Mode push_data(size_t bytes_read) { + private void push_data(size_t bytes_read) { assert(get_mode() == Mode.BLOCK); - - if (fsm.issue(Event.DATA, &bytes_read) == State.FAILED) { - deserialize_failure(); - - return Mode.FAILED; - } - - return get_mode(); + fsm.issue(Event.DATA, &bytes_read); } - + // Push an EOS event private void push_eos() { fsm.issue(Event.EOS); @@ -407,19 +411,7 @@ return Mode.LINE; } } - - // True if the Deserializer is FAILED or CLOSED. - private bool is_halted() { - switch (get_mode()) { - case Mode.FAILED: - case Mode.CLOSED: - return true; - - default: - return false; - } - } - + private bool is_current_string_empty() { return (current_string == null) || String.is_empty(current_string.str); } @@ -456,11 +448,7 @@ current_string = null; } - - private void clear_string_parameter() { - current_string = null; - } - + private void save_literal_parameter() { save_parameter(new LiteralParameter(block_buffer)); block_buffer = null; @@ -493,38 +481,40 @@ return State.START_PARAM; } - - private State flush_params() { - if (context != root) { - warning("Unclosed list in parameters"); - - return State.FAILED; + + private void flush_params() { + bool okay = true; + if (this.context != this.root) { + Logging.debug(Logging.Flag.DESERIALIZER, "[%s] Unclosed list in parameters"); + okay = false; } - - if (!is_current_string_empty() || literal_length_remaining > 0) { - warning("Unfinished parameter: string=%s literal remaining=%lu", - (!is_current_string_empty()).to_string(), literal_length_remaining); - - return State.FAILED; + + if (!is_current_string_empty() || this.literal_length_remaining > 0) { + Logging.debug( + Logging.Flag.DESERIALIZER, + "Unfinished parameter: string=%s literal remaining=%lu", + (!is_current_string_empty()).to_string(), this.literal_length_remaining + ); + okay = false; } - - RootParameters ready = root; - root = new RootParameters(); - context = root; - - parameters_ready(ready); - - return State.TAG; + + if (okay && this.root != null && root.size > 0) { + parameters_ready(this.root); + } + + reset_params(); } - - public string to_string() { - return "des:%s/%s".printf(identifier, fsm.get_state_string(fsm.get_state())); + + private void reset_params() { + this.context = this.root = new RootParameters(); + this.current_string = null; + this.literal_length_remaining = 0; } - + // // Transition handlers // - + private uint on_first_param_char(uint state, uint event, void *user) { // look for opening characters to special parameter formats, otherwise jump to atom // handler (i.e. don't drop this character in the case of atoms) @@ -534,29 +524,52 @@ // open response code ResponseCode response_code = new ResponseCode(); push(response_code); - return State.START_PARAM; - + + case ']': + if (ch == get_current_context_terminator()) { + return pop(); + } + + // Received an unexpected closing brace + return State.FAILED; + case '{': return State.LITERAL; - + case '\"': return State.QUOTED; - + case '(': // open list ListParameter list = new ListParameter(); push(list); - return State.START_PARAM; - - default: - // if current context's terminator, close the context, otherwise deserializer is - // now "in" an Atom - if (ch == get_current_context_terminator()) + + case ')': + if (ch == get_current_context_terminator()) { return pop(); - else - return on_atom_char(state, event, user); + } + + // Received an unexpected closing parens + return State.FAILED; + + case '\\': + // Start of a flag + append_to_string(ch); + return State.FLAG; + + case ' ': + // just consume the space + return State.START_PARAM; + + default: + if (!DataFormat.is_atom_special(ch)) { + append_to_string(ch); + return State.ATOM; + } + // Received an invalid atom-char + return State.FAILED; } } @@ -579,97 +592,94 @@ return State.TAG; } - + private uint on_atom_char(uint state, uint event, void *user) { char ch = *((char *) user); - + // The partial body fetch results ("BODY[section]" or "BODY[section]" and their // .peek variants) offer so many exceptions to the decoding process they're given their own // state if (ch == '[' && (is_current_string_ci("body") || is_current_string_ci("body.peek"))) { append_to_string(ch); - return State.PARTIAL_BODY_ATOM; } - - // get the terminator for this context and re-use the atom_special_exceptions array to - // pass to DataFormat.is_atom_special() (this means not allocating a new array on the heap - // for each call here, which isn't a problem because the FSM is non-reentrant) - char terminator = get_current_context_terminator(); - atom_specials_exceptions[1] = terminator; - - // drop if not allowed for atoms, barring specials which indicate special state changes - if (DataFormat.is_atom_special(ch, (string) atom_specials_exceptions)) - return State.ATOM; - - // message flag indicator is only legal at start of atom - if (ch == '\\' && is_current_string_empty()) { - append_to_string(ch); - - return State.SYSTEM_FLAG; - } - - // space indicates end-of-atom + + // space indicates end-of-atom, consume it and return to go. if (ch == ' ') { save_string_parameter(false); - return State.START_PARAM; } - - if (ch == get_current_context_terminator()) { + + // as does an end-of-list delim + char terminator = get_current_context_terminator(); + if (ch == terminator) { save_string_parameter(false); - return pop(); } - + + // Any of the atom specials indicate end of atom, so save and + // work out where to go next + if (DataFormat.is_atom_special(ch)) { + save_string_parameter(false); + return on_first_param_char(state, event, user); + } + append_to_string(ch); - return State.ATOM; } - - private uint on_system_flag_char(uint state, uint event, void *user) { + + // Although flags basically have the form "\atom", the special + // flag "\*" isn't a valid atom, and hence we need a special case + // for flag parsing. This is only used for the first char after + // the '\', since all following chars must be valid for atoms + private uint on_first_flag_char(uint state, uint event, void *user) { char ch = *((char *) user); - - // see note in on_atom_char for why/how this works - char terminator = get_current_context_terminator(); - atom_specials_exceptions[1] = terminator; - - // drop if not allowed for atoms, barring specials which indicate state changes - // note that asterisk is allowed for flags - if (ch != '*' && DataFormat.is_atom_special(ch, (string) atom_specials_exceptions)) - return State.SYSTEM_FLAG; - - // space indicates end-of-system-flag - if (ch == ' ') { + + // handle special flag "\*", this also indicates end-of-flag + if (ch == '*') { + append_to_string(ch); save_string_parameter(false); - return State.START_PARAM; } - - // close-parens/close-square-bracket after a system flag indicates end-of-list/end-of-response - // code - if (ch == terminator) { - save_string_parameter(false); - - return pop(); + + // Any of the atom specials indicate end of atom, but we are + // at the first char after a "\" and a flag has to have at + // least one atom char to be valid, so if we get an + // atom-special here bail out. + if (DataFormat.is_atom_special(ch)) { + return State.FAILED; } - + + // Append the char, but then switch to the ATOM state, since + // '*' is no longer valid and the remainder must be an atom append_to_string(ch); - - return State.SYSTEM_FLAG; + return State.ATOM; } - + private uint on_eol(uint state, uint event, void *user) { - return flush_params(); + flush_params(); + return State.TAG; } - + private uint on_atom_eol(uint state, uint event, void *user) { // clean up final atom save_string_parameter(false); - - return flush_params(); + flush_params(); + return State.TAG; } - + + private uint on_failed_eol(uint state, uint event, void *user) { + // We don't go into the error state on syntax error, merely + // reset, cross our fingers and hope for the best. Maybe + // there's a better strategy though? + Logging.debug( + Logging.Flag.DESERIALIZER, "[%s] Syntax error, dropping", to_string() + ); + deserialize_failure(); + reset_params(); + return State.TAG; + } + private uint on_quoted_char(uint state, uint event, void *user) { char ch = *((char *) user); @@ -753,16 +763,14 @@ // empty literal treated as garbage if (is_current_string_empty()) return State.FAILED; - - literal_length_remaining = (size_t) long.parse(current_string.str); + + literal_length_remaining = (size_t) long.parse(this.current_string.str); + this.current_string = null; if (literal_length_remaining < 0) { warning("Negative literal data length %lu", literal_length_remaining); - return State.FAILED; } - - clear_string_parameter(); - + return State.LITERAL_DATA_BEGIN; } @@ -792,17 +800,22 @@ return State.START_PARAM; } - + private uint on_eos() { debug("[%s] EOS", to_string()); - + + // Per RFC 3501 7.1.5, we may get a EOS immediately after a + // BYE, so flush any message being processed. + // https://tools.ietf.org/html/rfc3501#section-7.1.5 + flush_params(); + // always signal as closed and notify subscribers closed_semaphore.blind_notify(); eos(); - + return State.CLOSED; } - + private uint on_error(uint state, uint event, void *user, Object? object, Error? err) { assert(err != null); @@ -826,4 +839,3 @@ return State.FAILED; } } - diff -Nru geary-0.12.0/src/engine/imap-db/imap-db-folder.vala geary-0.12.4/src/engine/imap-db/imap-db-folder.vala --- geary-0.12.0/src/engine/imap-db/imap-db-folder.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap-db/imap-db-folder.vala 2018-08-29 13:57:20.000000000 +0000 @@ -1919,25 +1919,27 @@ MessageRow row = do_fetch_message_row(cx, location.message_id, Geary.Email.Field.FLAGS, out pre_fields, cancellable); post_fields = pre_fields; - - // compare flags for (a) any change at all and (b) unread changes + + // Only update if changed Geary.Email row_email = row.to_email(location.email_id); - - if (row_email.email_flags != null && row_email.email_flags.equal_to(email.email_flags)) - return; - - if (row_email.email_flags.is_unread() != email.email_flags.is_unread()) - unread_count_change += email.email_flags.is_unread() ? 1 : -1; - - // write them out to the message row - Gee.Map map = new Gee.HashMap(); - map.set((ImapDB.EmailIdentifier) email.id, email.email_flags); - - do_set_email_flags(cx, map, cancellable); - post_fields |= Geary.Email.Field.FLAGS; + if (row_email.email_flags == null || + !row_email.email_flags.equal_to(email.email_flags)) { + + // Check for unread count changes + if (row_email.email_flags != null && + row_email.email_flags.is_unread() != email.email_flags.is_unread()) { + unread_count_change += email.email_flags.is_unread() ? 1 : -1; + } + + Gee.Map map = + new Gee.HashMap(); + map.set((ImapDB.EmailIdentifier) email.id, email.email_flags); + do_set_email_flags(cx, map, cancellable); + + post_fields |= Geary.Email.Field.FLAGS; + } } - + private void do_merge_email(Db.Connection cx, LocationIdentifier location, Geary.Email email, out Geary.Email.Field pre_fields, out Geary.Email.Field post_fields, out Gee.Collection updated_contacts, ref int unread_count_change, diff -Nru geary-0.12.0/src/engine/imap-db/outbox/smtp-outbox-folder.vala geary-0.12.4/src/engine/imap-db/outbox/smtp-outbox-folder.vala --- geary-0.12.0/src/engine/imap-db/outbox/smtp-outbox-folder.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap-db/outbox/smtp-outbox-folder.vala 2018-08-29 13:57:20.000000000 +0000 @@ -74,6 +74,7 @@ this.db = db; _account = account; + _account.opened.connect(() => { this.fill_outbox_queue.begin(); }); this.sending_monitor = sending_monitor; smtp = new Geary.Smtp.ClientSession(_account.information.get_smtp_endpoint()); @@ -133,20 +134,17 @@ return (message.subject != null && !String.is_empty(message.subject.to_string())) ? message.subject.to_string() : "(no subject)"; } - - // TODO: Use Cancellable to shut down outbox processor when closing account - private async void do_postman_async() { - debug("Starting outbox postman"); - uint send_retry_seconds = MIN_SEND_RETRY_INTERVAL_SEC; - - // Fill the send queue with existing mail (if any) + + + // Fill the send queue with existing mail (if any) + private async void fill_outbox_queue() { + debug("Filling outbox queue"); try { Gee.ArrayList list = new Gee.ArrayList(); yield db.exec_transaction_async(Db.TransactionType.RO, (cx, cancellable) => { Db.Statement stmt = cx.prepare(""" SELECT id, ordering, message FROM SmtpOutboxTable - WHERE sent = 0 ORDER BY ordering """); @@ -172,37 +170,28 @@ } catch (Error prime_err) { warning("Error priming outbox: %s", prime_err.message); } + } + + + // TODO: Use Cancellable to shut down outbox processor when closing account + private async void do_postman_async() { + debug("Starting outbox postman"); + uint send_retry_seconds = MIN_SEND_RETRY_INTERVAL_SEC; // Start the send queue. for (;;) { // yield until a message is ready OutboxRow row; + bool mail_sent; try { row = yield outbox_queue.recv_async(); - - // Ignore messages that have since been sent. - if (!yield is_unsent_async(row.ordering, null)) { - debug("Dropping sent outbox message %s", row.outbox_id.to_string()); - continue; - } + mail_sent = !yield is_unsent_async(row.ordering, null); } catch (Error wait_err) { debug("Outbox postman queue error: %s", wait_err.message); break; } - // Get SMTP password if we haven't loaded it yet and the account needs credentials. - // If the account needs a password but it's not set or incorrect in the keyring, we'll - // prompt below after getting an AUTHENTICATION_FAILED error. - if (_account.information.smtp_credentials != null && - !_account.information.smtp_credentials.is_complete()) { - try { - yield _account.information.get_passwords_async(ServiceFlag.SMTP); - } catch (Error e) { - debug("SMTP password fetch error: %s", e.message); - } - } - // Convert row into RFC822 message suitable for sending or framing RFC822.Message message; try { @@ -213,95 +202,116 @@ continue; } - - // Send the message, but only remove from database once sent - bool should_nap = false; - bool mail_sent = false; - try { - // only try if (a) no TLS issues or (b) user has acknowledged them and says to - // continue - if (_account.information.get_smtp_endpoint().is_trusted_or_never_connected) { - debug("Outbox postman: Sending \"%s\" (ID:%s)...", message_subject(message), - row.outbox_id.to_string()); - yield send_email_async(message, null); - mail_sent = true; - } else { - // user was warned via Geary.Engine signal, need to wait for that to be cleared - // befor sending - outbox_queue.send(row); + + if (!mail_sent) { + // Get SMTP password if we haven't loaded it yet and the account needs credentials. + // If the account needs a password but it's not set or incorrect in the keyring, we'll + // prompt below after getting an AUTHENTICATION_FAILED error. + if (_account.information.smtp_credentials != null && + !_account.information.smtp_credentials.is_complete()) { + try { + yield _account.information.get_passwords_async(ServiceFlag.SMTP); + } catch (Error e) { + debug("SMTP password fetch error: %s", e.message); + } + } + + // Send the message, but only remove from database once sent + bool should_nap = false; + try { + // only try if (a) no TLS issues or (b) user has acknowledged them and says to + // continue + if (_account.information.get_smtp_endpoint().is_trusted_or_never_connected) { + debug("Outbox postman: Sending \"%s\" (ID:%s)...", message_subject(message), + row.outbox_id.to_string()); + yield send_email_async(message, null); + mail_sent = true; + } else { + // user was warned via Geary.Engine signal, need to wait for that to be cleared + // befor sending + outbox_queue.send(row); + should_nap = true; + } + } catch (Error send_err) { + debug("Outbox postman send error, retrying: %s", send_err.message); + should_nap = true; + + if (send_err is SmtpError.AUTHENTICATION_FAILED) { + bool report = true; + + // Retry immediately (bug 6387) + should_nap = false; + + // At this point we may already have a password in memory -- but it's incorrect. + // Delete the current password, prompt the user for a new one, and try again. + try { + if (yield _account.information.fetch_passwords_async(ServiceFlag.SMTP, true)) + report = false; + } catch (Error e) { + debug("Error prompting for SMTP password: %s", e.message); + } + + if (report) + report_problem(Geary.Account.Problem.SEND_EMAIL_LOGIN_FAILED, send_err); + } else if (send_err is TlsError) { + // up to application to be aware of problem via Geary.Engine, but do nap and + // try later + debug("TLS connection warnings connecting to %s, user must confirm connection to continue", + _account.information.get_smtp_endpoint().to_string()); + } else { + report_problem(Geary.Account.Problem.EMAIL_DELIVERY_FAILURE, send_err); + } } - } catch (Error send_err) { - debug("Outbox postman send error, retrying: %s", send_err.message); - - should_nap = true; - - if (send_err is SmtpError.AUTHENTICATION_FAILED) { - bool report = true; - - // Retry immediately (bug 6387) - should_nap = false; - - // At this point we may already have a password in memory -- but it's incorrect. - // Delete the current password, prompt the user for a new one, and try again. + + if (should_nap) { + debug("Outbox napping for %u seconds...", send_retry_seconds); + + // Take a brief nap before continuing to allow connection problems to resolve. + yield Geary.Scheduler.sleep_async(send_retry_seconds); + send_retry_seconds = Geary.Numeric.uint_ceiling(send_retry_seconds * 2, MAX_SEND_RETRY_INTERVAL_SEC); + } + + // If we got this far the send was successful, so reset the send retry interval. + send_retry_seconds = MIN_SEND_RETRY_INTERVAL_SEC; + + // Mark as sent, so if there's a problem pushing up to Sent Mail, + // we don't retry sending. + if (mail_sent) { try { - if (yield _account.information.fetch_passwords_async(ServiceFlag.SMTP, true)) - report = false; + debug("Outbox postman: Marking %s as sent", row.outbox_id.to_string()); + yield mark_email_as_sent_async(row.outbox_id, null); } catch (Error e) { - debug("Error prompting for SMTP password: %s", e.message); + debug("Outbox postman: Unable to mark row as sent: %s", e.message); } - - if (report) - report_problem(Geary.Account.Problem.SEND_EMAIL_LOGIN_FAILED, send_err); - } else if (send_err is TlsError) { - // up to application to be aware of problem via Geary.Engine, but do nap and - // try later - debug("TLS connection warnings connecting to %s, user must confirm connection to continue", - _account.information.get_smtp_endpoint().to_string()); - } else { - report_problem(Geary.Account.Problem.EMAIL_DELIVERY_FAILURE, send_err); } } - - if (should_nap) { - debug("Outbox napping for %u seconds...", send_retry_seconds); - - // Take a brief nap before continuing to allow connection problems to resolve. - yield Geary.Scheduler.sleep_async(send_retry_seconds); - send_retry_seconds = Geary.Numeric.uint_ceiling(send_retry_seconds * 2, MAX_SEND_RETRY_INTERVAL_SEC); - } - + if (!mail_sent) { - // don't drop row until it's sent + // try again later outbox_queue.send(row); - continue; } - - // If we got this far the send was successful, so reset the send retry interval. - send_retry_seconds = MIN_SEND_RETRY_INTERVAL_SEC; - + + bool mail_saved = true; if (_account.information.allow_save_sent_mail() && _account.information.save_sent_mail) { - // First mark as sent, so if there's a problem pushing up to Sent Mail, - // we don't retry sending. - try { - debug("Outbox postman: Marking %s as sent", row.outbox_id.to_string()); - yield mark_email_as_sent_async(row.outbox_id, null); - } catch (Error e) { - debug("Outbox postman: Unable to mark row as sent: %s", e.message); - } - + mail_saved = false; try { debug("Outbox postman: Saving %s to sent mail", row.outbox_id.to_string()); yield save_sent_mail_async(message, null); + mail_saved = true; } catch (Error e) { debug("Outbox postman: Error saving sent mail: %s", e.message); report_problem(Geary.Account.Problem.SAVE_SENT_MAIL_FAILED, e); - - continue; } } - + + if (!mail_saved) { + // try again later + outbox_queue.send(row); + continue; + } + // Remove from database ... can't use remove_email_async() because this runs even if // the outbox is closed as a Geary.Folder. try { diff -Nru geary-0.12.0/src/engine/imap-engine/imap-engine-email-prefetcher.vala geary-0.12.4/src/engine/imap-engine/imap-engine-email-prefetcher.vala --- geary-0.12.0/src/engine/imap-engine/imap-engine-email-prefetcher.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/imap-engine/imap-engine-email-prefetcher.vala 2018-08-29 13:57:20.000000000 +0000 @@ -11,7 +11,7 @@ * * The EmailPrefetcher does not maintain a reference to the folder. */ -private class Geary.ImapEngine.EmailPrefetcher : Object { +private class Geary.ImapEngine.EmailPrefetcher : Geary.BaseObject { public const int PREFETCH_DELAY_SEC = 1; private const Geary.Email.Field PREFETCH_FIELDS = Geary.Email.Field.ALL; diff -Nru geary-0.12.0/src/engine/mime/mime-content-parameters.vala geary-0.12.4/src/engine/mime/mime-content-parameters.vala --- geary-0.12.0/src/engine/mime/mime-content-parameters.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/mime/mime-content-parameters.vala 2018-08-29 13:57:20.000000000 +0000 @@ -78,7 +78,7 @@ return (stored != null) ? Ascii.stri_equal(stored, value) : false; } - + /** * Returns true if the attribute has the supplied value (case-sensitive comparison). * @@ -86,10 +86,10 @@ */ public bool has_value_cs(string attribute, string value) { string? stored = params.get(attribute); - - return (stored != null) ? (stored == value) : false; + + return (stored != null) ? Ascii.str_equal(stored, value) : false; } - + /** * Add or replace the parameter. * diff -Nru geary-0.12.0/src/engine/mime/mime-content-type.vala geary-0.12.4/src/engine/mime/mime-content-type.vala --- geary-0.12.0/src/engine/mime/mime-content-type.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/mime/mime-content-type.vala 2018-08-29 13:57:20.000000000 +0000 @@ -79,9 +79,9 @@ int max_len = 4096; // XXX determine actual max needed buffer size using // xdg_mime_get_max_buffer_extents? - uint8[] data = (max_len > buf.size) - ? buf.get_bytes()[0:max_len - 1].get_data() - : buf.get_uint8_array(); + uint8[] data = (buf.size <= max_len) + ? buf.get_uint8_array() + : buf.get_bytes()[0:max_len].get_data(); // XXX might just want to use xdgmime lib directly here to // avoid the intermediate glib_content_type step here? diff -Nru geary-0.12.0/src/engine/mime/mime-disposition-type.vala geary-0.12.4/src/engine/mime/mime-disposition-type.vala --- geary-0.12.0/src/engine/mime/mime-disposition-type.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/mime/mime-disposition-type.vala 2018-08-29 13:57:20.000000000 +0000 @@ -31,24 +31,24 @@ */ public static DispositionType deserialize(string? str, out bool is_unknown) { is_unknown = false; - + if (String.is_empty_or_whitespace(str)) return UNSPECIFIED; - - switch (str.down()) { + + switch (Ascii.strdown(str)) { case "inline": return INLINE; - + case "attachment": return ATTACHMENT; - + default: is_unknown = true; - + return ATTACHMENT; } } - + /** * Returns null if value is {@link UNSPECIFIED} */ diff -Nru geary-0.12.0/src/engine/mime/mime-multipart-subtype.vala geary-0.12.4/src/engine/mime/mime-multipart-subtype.vala --- geary-0.12.0/src/engine/mime/mime-multipart-subtype.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/mime/mime-multipart-subtype.vala 2018-08-29 13:57:20.000000000 +0000 @@ -48,24 +48,24 @@ public static MultipartSubtype from_content_type(ContentType? content_type, out bool is_unknown) { if (content_type == null || !content_type.has_media_type("multipart")) { is_unknown = true; - + return MIXED; } - + is_unknown = false; - switch (content_type.media_subtype.down()) { + switch (Ascii.strdown(content_type.media_subtype)) { case "mixed": return MIXED; - + case "alternative": return ALTERNATIVE; - + case "related": return RELATED; - + default: is_unknown = true; - + return MIXED; } } diff -Nru geary-0.12.0/src/engine/rfc822/rfc822-mailbox-address.vala geary-0.12.4/src/engine/rfc822/rfc822-mailbox-address.vala --- geary-0.12.0/src/engine/rfc822/rfc822-mailbox-address.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/rfc822/rfc822-mailbox-address.vala 2018-08-29 13:57:20.000000000 +0000 @@ -53,7 +53,7 @@ source_route = null; - int atsign = address.index_of_char('@'); + int atsign = Ascii.index_of(address, '@'); if (atsign > 0) { mailbox = address.slice(0, atsign); domain = address.slice(atsign + 1, address.length); @@ -62,7 +62,7 @@ domain = ""; } } - + public MailboxAddress.imap(string? name, string? source_route, string mailbox, string domain) { this.name = (name != null) ? decode_name(name) : null; this.source_route = source_route; diff -Nru geary-0.12.0/src/engine/rfc822/rfc822-message.vala geary-0.12.4/src/engine/rfc822/rfc822-message.vala --- geary-0.12.0/src/engine/rfc822/rfc822-message.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/rfc822/rfc822-message.vala 2018-08-29 13:57:20.000000000 +0000 @@ -960,7 +960,11 @@ GMime.MessagePart? messagepart = root as GMime.MessagePart; if (messagepart != null) { GMime.Message sub_message = messagepart.get_message(); - messages.add(new Geary.RFC822.Message.from_gmime_message(sub_message)); + if (sub_message != null) { + messages.add(new Geary.RFC822.Message.from_gmime_message(sub_message)); + } else { + warning("Corrupt message, possibly bug 769697"); + } } } diff -Nru geary-0.12.0/src/engine/rfc822/rfc822-utils.vala geary-0.12.4/src/engine/rfc822/rfc822-utils.vala --- geary-0.12.0/src/engine/rfc822/rfc822-utils.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/rfc822/rfc822-utils.vala 2018-08-29 13:57:20.000000000 +0000 @@ -257,7 +257,11 @@ } quoted += "
"; - quoted += quote_body(email, quote, true, format); + try { + quoted += quote_body(email, quote, true, format); + } catch (Error err) { + debug("Failed to quote body for replying: %s".printf(err.message)); + } return quoted; } @@ -290,31 +294,35 @@ quoted += _("Cc: %s\n").printf(cc_line); quoted += "\n"; // A blank line between headers and body quoted = quoted.replace("\n", "
"); - quoted += quote_body(email, quote, false, format); + try { + quoted += quote_body(email, quote, false, format); + } catch (Error err) { + debug("Failed to quote body for forwarding: %s".printf(err.message)); + } return quoted; } -private string quote_body(Geary.Email email, string? quote, bool use_quotes, TextFormat format) { - string? body_text = quote ?? ""; +private string quote_body(Geary.Email email, string? quote, bool use_quotes, TextFormat format) + throws Error { + Message? message = email.get_message(); + bool preserve_whitespace = !message.has_html_body(); + string? body_text = null; if (quote == null) { - try { - Message message = email.get_message(); - switch (format) { - case TextFormat.HTML: - body_text = message.has_html_body() - ? message.get_html_body(null) - : message.get_plain_body(true, null); - break; - - case TextFormat.PLAIN: - body_text = message.has_plain_body() - ? message.get_plain_body(true, null) - : message.get_html_body(null); - break; - } - } catch (Error error) { - debug("Could not get message text for quoting: %s", error.message); + switch (format) { + case TextFormat.HTML: + body_text = message.has_html_body() + ? message.get_html_body(null) + : message.get_plain_body(true, null); + break; + + case TextFormat.PLAIN: + body_text = message.has_plain_body() + ? message.get_plain_body(true, null) + : message.get_html_body(null); + break; } + } else { + body_text = Geary.HTML.smart_escape(quote, preserve_whitespace); } // Wrap the whole thing in a blockquote. diff -Nru geary-0.12.0/src/engine/smtp/smtp-command.vala geary-0.12.4/src/engine/smtp/smtp-command.vala --- geary-0.12.0/src/engine/smtp/smtp-command.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/smtp/smtp-command.vala 2018-08-29 13:57:20.000000000 +0000 @@ -56,36 +56,36 @@ assert_not_reached(); } } - + public static Command deserialize(string str) throws SmtpError { - switch (str.down()) { + switch (Ascii.strdown(str)) { case "helo": return HELO; - + case "ehlo": return EHLO; - + case "quit": return QUIT; - + case "help": return HELP; - + case "noop": return NOOP; - + case "rset": return RSET; - + case "auth": return AUTH; - + case "mail": return MAIL; - + case "rcpt": return RCPT; - + case "data": return DATA; diff -Nru geary-0.12.0/src/engine/smtp/smtp-greeting.vala geary-0.12.4/src/engine/smtp/smtp-greeting.vala --- geary-0.12.0/src/engine/smtp/smtp-greeting.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/smtp/smtp-greeting.vala 2018-08-29 13:57:20.000000000 +0000 @@ -25,21 +25,21 @@ return ""; } } - + public static ServerFlavor deserialize(string str) { - switch (str.up()) { + switch (Ascii.strup(str)) { case "SMTP": return SMTP; - + case "ESMTP": return ESMTP; - + default: return UNSPECIFIED; } } } - + public string? domain { get; private set; default = null; } public ServerFlavor flavor { get; private set; default = ServerFlavor.UNSPECIFIED; } public string? message { get; private set; default = null; } diff -Nru geary-0.12.0/src/engine/util/util-ascii.vala geary-0.12.4/src/engine/util/util-ascii.vala --- geary-0.12.0/src/engine/util/util-ascii.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/util/util-ascii.vala 2018-08-29 13:57:20.000000000 +0000 @@ -4,40 +4,71 @@ * (version 2.1 or later). See the COPYING file in this distribution. */ +// These calls are bound to the string class in Vala 0.26. When that version of Vala is the +// minimum, these can be dropped and Ascii.strup and Ascii.strdown can use the string methods. +extern string g_ascii_strup(string str, ssize_t len = -1); +extern string g_ascii_strdown(string str, ssize_t len = -1); + namespace Geary.Ascii { +public int index_of(string str, char ch) { + char *strptr = str; + int index = 0; + for (;;) { + char strch = *strptr++; + + if (strch == String.EOS) + return -1; + + if (strch == ch) + return index; + + index++; + } +} + public bool get_next_char(string str, ref int index, out char ch) { ch = str[index++]; - + return ch != String.EOS; } -public bool stri_equal(string a, string b) { - // XXX Is this marginally faster than a.down() == b.down() in the - // best case, slower in the worse case, so not worth it? +public inline int strcmp(string a, string b) { + return GLib.strcmp(a, b); +} + +public int stricmp(string a, string b) { char *aptr = a; char *bptr = b; for (;;) { int diff = (int) (*aptr).tolower() - (int) (*bptr).tolower(); if (diff != 0) - return false; - + return diff; + if (*aptr == String.EOS) - return true; - + return 0; + aptr++; bptr++; } } +public inline bool str_equal(string a, string b) { + return a == b; +} + +public inline bool stri_equal(string a, string b) { + return stricmp(a, b) == 0; +} + public bool nullable_stri_equal(string? a, string? b) { if (a == null) return (b == null); - + // a != null, so always false if (b == null) return false; - + return stri_equal(a, b); } @@ -55,6 +86,14 @@ return (str != null) ? stri_hash(str) : 0; } +public string strdown(string str) { + return g_ascii_strdown(str); +} + +public string strup(string str) { + return g_ascii_strup(str); +} + /** * Returns true if the ASCII string contains only whitespace and at least one numeric character. */ diff -Nru geary-0.12.0/src/engine/util/util-html.vala geary-0.12.4/src/engine/util/util-html.vala --- geary-0.12.0/src/engine/util/util-html.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/util/util-html.vala 2018-08-29 13:57:20.000000000 +0000 @@ -182,7 +182,7 @@ preserve_whitespace_in_html = true; } if (preserve_whitespace_in_html) - res = @"
$res
"; + res = @"
$res
"; return res; } diff -Nru geary-0.12.0/src/engine/util/util-idle-manager.vala geary-0.12.4/src/engine/util/util-idle-manager.vala --- geary-0.12.0/src/engine/util/util-idle-manager.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/util/util-idle-manager.vala 2018-08-29 13:57:20.000000000 +0000 @@ -43,7 +43,9 @@ get { return this.source_id >= 0; } } - private IdleFunc callback; + // Callback must be unowned to avoid reference loop with owner's + // class when a closure is used as the callback. + private unowned IdleFunc callback; private int source_id = -1; diff -Nru geary-0.12.0/src/engine/util/util-imap-utf7.vala geary-0.12.4/src/engine/util/util-imap-utf7.vala --- geary-0.12.0/src/engine/util/util-imap-utf7.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/util/util-imap-utf7.vala 2018-08-29 13:57:20.000000000 +0000 @@ -94,7 +94,7 @@ return -1; } -public string utf8_to_imap_utf7(string str) throws ConvertError { +public string utf8_to_imap_utf7(string str) { int p = first_encode_index(str); if (p < 0) { /* no characters that need to be encoded */ diff -Nru geary-0.12.0/src/engine/util/util-timeout-manager.vala geary-0.12.4/src/engine/util/util-timeout-manager.vala --- geary-0.12.0/src/engine/util/util-timeout-manager.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/src/engine/util/util-timeout-manager.vala 2018-08-29 13:57:20.000000000 +0000 @@ -50,7 +50,9 @@ get { return this.source_id >= 0; } } - private TimeoutFunc callback; + // Callback must be unowned to avoid reference loop with owner's + // class when a closure is used as the callback. + private unowned TimeoutFunc callback; private int source_id = -1; diff -Nru geary-0.12.0/test/client/components/client-web-view-test-case.vala geary-0.12.4/test/client/components/client-web-view-test-case.vala --- geary-0.12.0/test/client/components/client-web-view-test-case.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/test/client/components/client-web-view-test-case.vala 2018-08-29 13:57:20.000000000 +0000 @@ -38,7 +38,7 @@ protected virtual void load_body_fixture(string html = "") { ClientWebView client_view = (ClientWebView) this.test_view; client_view.load_html(html); - while (client_view.is_loading) { + while (!client_view.is_content_loaded) { Gtk.main_iteration(); } } diff -Nru geary-0.12.0/test/client/composer/composer-web-view-test.vala geary-0.12.4/test/client/composer/composer-web-view-test.vala --- geary-0.12.0/test/client/composer/composer-web-view-test.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/test/client/composer/composer-web-view-test.vala 2018-08-29 13:57:20.000000000 +0000 @@ -7,7 +7,7 @@ public class ComposerWebViewTest : ClientWebViewTestCase { - private const string BODY_TEMPLATE = """
%s


"""; + private const string BODY_TEMPLATE = """
%s


"""; public ComposerWebViewTest() { base("ComposerWebViewTest"); diff -Nru geary-0.12.0/test/CMakeLists.txt geary-0.12.4/test/CMakeLists.txt --- geary-0.12.0/test/CMakeLists.txt 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/test/CMakeLists.txt 2018-08-29 13:57:20.000000000 +0000 @@ -8,6 +8,9 @@ engine/api/geary-attachment-test.vala engine/api/geary-engine-test.vala + engine/imap/message/imap-data-format-test.vala + engine/imap/message/imap-mailbox-specifier-test.vala + engine/imap/transport/imap-deserializer-test.vala engine/mime-content-type-test.vala engine/rfc822-mailbox-address-test.vala engine/rfc822-message-test.vala @@ -24,6 +27,7 @@ client/components/client-web-view-test-case.vala client/composer/composer-web-view-test.vala + js/client-page-state-test.vala js/composer-page-state-test.vala js/conversation-page-state-test.vala ) diff -Nru geary-0.12.0/test/engine/api/geary-attachment-test.vala geary-0.12.4/test/engine/api/geary-attachment-test.vala --- geary-0.12.0/test/engine/api/geary-attachment-test.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/test/engine/api/geary-attachment-test.vala 2018-08-29 13:57:20.000000000 +0000 @@ -5,13 +5,16 @@ * (version 2.1 or later). See the COPYING file in this distribution. */ +// Defined by CMake build script. +extern const string _SOURCE_ROOT_DIR; + class Geary.AttachmentTest : Gee.TestCase { private const string ATTACHMENT_ID = "test-id"; private const string CONTENT_TYPE = "image/png"; private const string CONTENT_ID = "test-content-id"; private const string CONTENT_DESC = "Mea navis volitans anguillis plena est"; - private const string FILE_PATH = "../icons/hicolor/16x16/apps/geary.png"; + private const string FILE_PATH = "icons/hicolor/16x16/apps/org.gnome.Geary.png"; private Mime.ContentType? content_type; private Mime.ContentType? default_type; @@ -53,6 +56,8 @@ get_safe_file_name_with_default_content_type); add_test("get_safe_file_name_with_default_content_type_bad_file_name", get_safe_file_name_with_default_content_type_bad_file_name); + add_test("get_safe_file_name_with_unknown_content_type", + get_safe_file_name_with_unknown_content_type); } public override void set_up() { @@ -60,10 +65,9 @@ this.content_type = Mime.ContentType.deserialize(CONTENT_TYPE); this.default_type = Mime.ContentType.deserialize(Mime.ContentType.DEFAULT_CONTENT_TYPE); this.content_disposition = new Mime.ContentDisposition("attachment", null); - // XXX this will break as soon as the test runner is not - // launched from the project root dir - this.file = File.new_for_path("../icons/hicolor/16x16/apps/geary.png"); + File source = File.new_for_path(_SOURCE_ROOT_DIR); + this.file = source.get_child(FILE_PATH); } catch (Error err) { assert_not_reached(); } @@ -222,9 +226,7 @@ CONTENT_DESC, content_disposition, TEST_FILENAME, - // XXX this will break as soon as the test runner is not - // launched from the project root dir - File.new_for_path("../icons/hicolor/16x16/apps/geary.png"), + this.file, 742 ); @@ -235,4 +237,24 @@ assert(test.get_safe_file_name.end(async_result()) == RESULT_FILENAME); } + public void get_safe_file_name_with_unknown_content_type() { + const string TEST_FILENAME = "test-filename.unlikely"; + Attachment test = new TestAttachment( + ATTACHMENT_ID, + this.default_type, + CONTENT_ID, + CONTENT_DESC, + content_disposition, + TEST_FILENAME, + File.new_for_path(TEST_FILENAME), + 742 + ); + + test.get_safe_file_name.begin(null, (obj, ret) => { + async_complete(ret); + }); + + assert(TEST_FILENAME == test.get_safe_file_name.end(async_result())); + } + } diff -Nru geary-0.12.0/test/engine/imap/message/imap-data-format-test.vala geary-0.12.4/test/engine/imap/message/imap-data-format-test.vala --- geary-0.12.0/test/engine/imap/message/imap-data-format-test.vala 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/test/engine/imap/message/imap-data-format-test.vala 2018-08-29 13:57:20.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright 2018 Michael Gratton + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +class Geary.Imap.DataFormatTest : Gee.TestCase { + + + public DataFormatTest() { + base("Geary.Imap.DataFormatTest"); + add_test("is_atom_special", is_atom_special); + } + + public void is_atom_special() { + assert_true( + !DataFormat.is_atom_special('a') && !DataFormat.is_atom_special('z') + ); + assert_true( + !DataFormat.is_atom_special('A') && !DataFormat.is_atom_special('Z') + ); + assert_true( + !DataFormat.is_atom_special('0') && !DataFormat.is_atom_special('9') + ); + assert_true( + !DataFormat.is_atom_special('#') && + !DataFormat.is_atom_special('.') && + !DataFormat.is_atom_special('+') && + !DataFormat.is_atom_special('/') && + !DataFormat.is_atom_special('~') && + !DataFormat.is_atom_special(':') + ); + + // atom-specials + assert_true( + DataFormat.is_atom_special('(') + ); + assert_true( + DataFormat.is_atom_special(')') + ); + assert_true( + DataFormat.is_atom_special('{') + ); + assert_true( + DataFormat.is_atom_special(' ') + ); + assert_true( + DataFormat.is_atom_special(0x00) + ); + assert_true( + DataFormat.is_atom_special(0x1F) + ); + assert_true( + DataFormat.is_atom_special(0x7F) + ); + assert_true( + DataFormat.is_atom_special(0x80) + ); + assert_true( + DataFormat.is_atom_special(0xFE) + ); + + // list-wildcards + assert_true( + DataFormat.is_atom_special('%') + ); + assert_true( + DataFormat.is_atom_special('*') + ); + + // quoted-specials + assert_true( + DataFormat.is_atom_special('\"') + ); + assert_true( + DataFormat.is_atom_special('\\') + ); + + // resp-specials + assert_true( + DataFormat.is_atom_special(']') + ); + } + +} diff -Nru geary-0.12.0/test/engine/imap/message/imap-mailbox-specifier-test.vala geary-0.12.4/test/engine/imap/message/imap-mailbox-specifier-test.vala --- geary-0.12.0/test/engine/imap/message/imap-mailbox-specifier-test.vala 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/test/engine/imap/message/imap-mailbox-specifier-test.vala 2018-08-29 13:57:20.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright 2018 Michael Gratton + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +class Geary.Imap.MailboxSpecifierTest : Gee.TestCase { + + + public MailboxSpecifierTest() { + base("Geary.Imap.MailboxSpecifierTest"); + add_test("to_parameter", to_parameter); + add_test("from_parameter", from_parameter); + } + + public void to_parameter() { + assert( + "test" == + new MailboxSpecifier("test").to_parameter().to_string() + ); + assert( + "foo/bar" == + new MailboxSpecifier("foo/bar").to_parameter().to_string() + ); + + // The param won't be quoted or escaped since + // QuotedStringParameter doesn't actually handle that, so just + // check that it is correct type + Parameter quoted = new MailboxSpecifier("""foo\bar""").to_parameter(); + assert(quoted is QuotedStringParameter); + + assert( + "ol&AOk-" == + new MailboxSpecifier("olé").to_parameter().to_string() + ); + } + + public void from_parameter() { + assert( + "test" == + new MailboxSpecifier.from_parameter( + new UnquotedStringParameter("test")).name + ); + + // This won't be quoted or escaped since QuotedStringParameter + // doesn't actually handle that. + assert( + "foo\\bar" == + new MailboxSpecifier.from_parameter( + new QuotedStringParameter("""foo\bar""")).name + ); + assert( + "olé" == + new MailboxSpecifier.from_parameter( + new UnquotedStringParameter("ol&AOk-")).name + ); + } + +} diff -Nru geary-0.12.0/test/engine/imap/transport/imap-deserializer-test.vala geary-0.12.4/test/engine/imap/transport/imap-deserializer-test.vala --- geary-0.12.0/test/engine/imap/transport/imap-deserializer-test.vala 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/test/engine/imap/transport/imap-deserializer-test.vala 2018-08-29 13:57:20.000000000 +0000 @@ -0,0 +1,223 @@ +/* + * Copyright 2017 Michael Gratton + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +class Geary.Imap.DeserializerTest : Gee.TestCase { + + + protected enum Expect { MESSAGE, EOS, DESER_FAIL; } + + private const string ID = "test"; + private const string EOL = "\r\n"; + + private Deserializer? deser = null; + private MemoryInputStream? stream = null; + + + public DeserializerTest() { + base("Geary.Imap.DeserializerTest"); + add_test("test_gmail_greeting", test_gmail_greeting); + add_test("test_cyrus_2_4_greeting", test_cyrus_2_4_greeting); + add_test("test_aliyun_greeting", test_aliyun_greeting); + + add_test("test_invalid_atom_prefix", test_invalid_atom_prefix); + + add_test("test_gmail_flags", test_gmail_flags); + add_test("test_gmail_permanent_flags", test_gmail_permanent_flags); + add_test("test_cyrus_flags", test_cyrus_flags); + + add_test("test_runin_special_flag", test_runin_special_flag); + add_test("test_invalid_flag_prefix", test_invalid_flag_prefix); + + add_test("test_instant_eos", test_instant_eos); + add_test("test_bye_eos", test_bye_eos); + } + + public override void set_up() { + this.stream = new MemoryInputStream(); + this.deser = new Deserializer(ID, this.stream); + } + + public override void tear_down() { + this.deser.stop_async.begin((obj, ret) => { async_complete(ret); }); + async_result(); + } + + public void test_gmail_greeting() { + string greeting = "* OK Gimap ready for requests from 115.187.245.46 c194mb399904375ivc"; + this.stream.add_data(greeting.data, g_free); + this.stream.add_data(EOL.data, g_free); + + this.process.begin(Expect.MESSAGE, (obj, ret) => { async_complete(ret); }); + RootParameters? message = this.process.end(async_result()); + + assert(message.to_string() == greeting); + } + + public void test_cyrus_2_4_greeting() { + string greeting = "* OK [CAPABILITY IMAP4rev1 LITERAL+ ID ENABLE AUTH=PLAIN SASL-IR] mogul Cyrus IMAP v2.4.12-Debian-2.4.12-2 server ready"; + this.stream.add_data(greeting.data, g_free); + this.stream.add_data(EOL.data, g_free); + + this.process.begin(Expect.MESSAGE, (obj, ret) => { async_complete(ret); }); + RootParameters? message = this.process.end(async_result()); + + assert(message.to_string() == greeting); + } + + public void test_aliyun_greeting() { + string greeting = "* OK AliYun IMAP Server Ready(10.147.40.164)"; + string parsed = "* OK AliYun IMAP Server Ready (10.147.40.164)"; + this.stream.add_data(greeting.data, g_free); + this.stream.add_data(EOL.data, g_free); + + this.process.begin(Expect.MESSAGE, (obj, ret) => { async_complete(ret); }); + RootParameters? message = this.process.end(async_result()); + + assert(message.to_string() == parsed); + } + + public void test_invalid_atom_prefix() { + string flags = """* OK %atom"""; + this.stream.add_data(flags.data, g_free); + this.stream.add_data(EOL.data, g_free); + + this.process.begin(Expect.DESER_FAIL, (obj, ret) => { async_complete(ret); }); + this.process.end(async_result()); + } + + public void test_gmail_flags() { + string flags = """* FLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing)"""; + this.stream.add_data(flags.data, g_free); + this.stream.add_data(EOL.data, g_free); + + this.process.begin(Expect.MESSAGE, (obj, ret) => { async_complete(ret); }); + RootParameters? message = this.process.end(async_result()); + + assert(message.to_string() == flags); + } + + public void test_gmail_permanent_flags() { + string flags = """* OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing \*)] Flags permitted."""; + this.stream.add_data(flags.data, g_free); + this.stream.add_data(EOL.data, g_free); + + this.process.begin(Expect.MESSAGE, (obj, ret) => { async_complete(ret); }); + RootParameters? message = this.process.end(async_result()); + + assert(message.to_string() == flags); + } + + public void test_cyrus_flags() { + string flags = """* 2934 FETCH (FLAGS (\Answered \Seen $Quuxo::Spam::Trained) UID 3041)"""; + this.stream.add_data(flags.data, g_free); + this.stream.add_data(EOL.data, g_free); + + this.process.begin(Expect.MESSAGE, (obj, ret) => { async_complete(ret); }); + RootParameters? message = this.process.end(async_result()); + + assert(message.to_string() == flags); + } + + public void test_runin_special_flag() { + // since we must terminate a special flag upon receiving the + // '*', the following atom will be treated as a run-on but + // distinct atom. + string flags = """* OK \*atom"""; + string expected = """* OK \* atom"""; + this.stream.add_data(flags.data, g_free); + this.stream.add_data(EOL.data, g_free); + + this.process.begin(Expect.MESSAGE, (obj, ret) => { async_complete(ret); }); + RootParameters? message = this.process.end(async_result()); + + assert(message.to_string() == expected); + } + + public void test_invalid_flag_prefix() { + string flags = """* OK \%atom"""; + this.stream.add_data(flags.data, g_free); + this.stream.add_data(EOL.data, g_free); + + this.process.begin(Expect.DESER_FAIL, (obj, ret) => { async_complete(ret); }); + this.process.end(async_result()); + } + + public void test_instant_eos() { + this.process.begin(Expect.EOS, (obj, ret) => { async_complete(ret); }); + this.process.end(async_result()); + assert(this.deser.is_halted()); + } + + public void test_bye_eos() { + string bye = """* OK bye"""; + this.stream.add_data(bye.data, g_free); + + bool eos = false; + this.deser.eos.connect(() => { eos = true; }); + + this.process.begin(Expect.MESSAGE, (obj, ret) => { async_complete(ret); }); + RootParameters? message = this.process.end(async_result()); + assert(message.to_string() == bye); + assert(eos); + assert(this.deser.is_halted()); + } + + protected async RootParameters? process(Expect expected) { + RootParameters? message = null; + bool eos = false; + bool deserialize_failure = false; + bool receive_failure = false; + size_t bytes_received = 0; + + this.deser.parameters_ready.connect((param) => { message = param; }); + this.deser.bytes_received.connect((count) => { bytes_received += count; }); + this.deser.eos.connect((param) => { eos = true; }); + this.deser.deserialize_failure.connect(() => { deserialize_failure = true; }); + this.deser.receive_failure.connect((err) => { receive_failure = true;}); + + this.deser.start_async.begin(); + while (message == null && !receive_failure && !eos && !deserialize_failure) { + this.main_loop.iteration(true); + } + + switch (expected) { + case Expect.MESSAGE: + assert(message != null); + assert(bytes_received > 0); + assert(!eos); + assert(!deserialize_failure); + assert(!receive_failure); + break; + + case Expect.EOS: + assert(message == null); + assert(eos); + assert(!deserialize_failure); + assert(!receive_failure); + break; + + case Expect.DESER_FAIL: + assert(message == null); + assert(!eos); + assert(deserialize_failure); + assert(!receive_failure); + break; + + default: + assert_not_reached(); + } + + // Process any remaining async tasks the deserializer might + // have left over. + while (this.main_loop.pending()) { + this.main_loop.iteration(true); + } + + return message; + } + +} diff -Nru geary-0.12.0/test/js/client-page-state-test.vala geary-0.12.4/test/js/client-page-state-test.vala --- geary-0.12.0/test/js/client-page-state-test.vala 1970-01-01 00:00:00.000000000 +0000 +++ geary-0.12.4/test/js/client-page-state-test.vala 2018-08-29 13:57:20.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Michael Gratton + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +class ClientPageStateTest : ClientWebViewTestCase { + + + public ClientPageStateTest() { + base("ClientPageStateTest"); + add_test("content_loaded", content_loaded); + + try { + ClientWebView.load_scripts(); + } catch (Error err) { + assert_not_reached(); + } + + } + + public void content_loaded() { + bool content_loaded_triggered = false; + this.test_view.content_loaded.connect(() => { + content_loaded_triggered = true; + }); + + assert(!this.test_view.is_content_loaded); + + // XXX sketchy - this call will never return if the thing we + // are testing does not work + load_body_fixture("OHHAI"); + + assert(this.test_view.is_content_loaded); + assert(content_loaded_triggered); + } + + protected override ClientWebView set_up_test_view() { + WebKit.UserScript test_script; + test_script = new WebKit.UserScript( + "var geary = new PageState()", + WebKit.UserContentInjectedFrames.TOP_FRAME, + WebKit.UserScriptInjectionTime.START, + null, + null + ); + + ClientWebView view = new ClientWebView(this.config); + view.get_user_content_manager().add_script(test_script); + return view; + } + +} diff -Nru geary-0.12.0/test/js/composer-page-state-test.vala geary-0.12.4/test/js/composer-page-state-test.vala --- geary-0.12.0/test/js/composer-page-state-test.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/test/js/composer-page-state-test.vala 2018-08-29 13:57:20.000000000 +0000 @@ -7,7 +7,7 @@ class ComposerPageStateTest : ClientWebViewTestCase { - private const string COMPLETE_BODY_TEMPLATE = """
%s


"""; + private const string COMPLETE_BODY_TEMPLATE = """
%s


"""; private const string CLEAN_BODY_TEMPLATE = "%s


"; public ComposerPageStateTest() { diff -Nru geary-0.12.0/test/main.vala geary-0.12.4/test/main.vala --- geary-0.12.0/test/main.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/test/main.vala 2018-08-29 13:57:20.000000000 +0000 @@ -40,6 +40,9 @@ engine.add_suite(new Geary.AttachmentTest().get_suite()); engine.add_suite(new Geary.EngineTest().get_suite()); engine.add_suite(new Geary.HTML.UtilTest().get_suite()); + engine.add_suite(new Geary.Imap.DataFormatTest().get_suite()); + engine.add_suite(new Geary.Imap.DeserializerTest().get_suite()); + engine.add_suite(new Geary.Imap.MailboxSpecifierTest().get_suite()); engine.add_suite(new Geary.IdleManagerTest().get_suite()); engine.add_suite(new Geary.Inet.Test().get_suite()); engine.add_suite(new Geary.JS.Test().get_suite()); @@ -61,6 +64,7 @@ TestSuite js = new TestSuite("js"); + js.add_suite(new ClientPageStateTest().get_suite()); js.add_suite(new ComposerPageStateTest().get_suite()); js.add_suite(new ConversationPageStateTest().get_suite()); diff -Nru geary-0.12.0/test/testcase.vala geary-0.12.4/test/testcase.vala --- geary-0.12.0/test/testcase.vala 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/test/testcase.vala 2018-08-29 13:57:20.000000000 +0000 @@ -24,6 +24,8 @@ public abstract class Gee.TestCase : Object { + protected MainContext main_loop = MainContext.default(); + private GLib.TestSuite suite; private Adaptor[] adaptors = new Adaptor[0]; private AsyncQueue async_results = new AsyncQueue(); @@ -56,12 +58,15 @@ protected void async_complete(AsyncResult result) { this.async_results.push(result); + // notify the loop so that if async_result() has already been + // called, that method won't block + this.main_loop.wakeup(); } protected AsyncResult async_result() { AsyncResult? result = null; while (result == null) { - Gtk.main_iteration(); + this.main_loop.iteration(true); result = this.async_results.try_pop(); } return result; diff -Nru geary-0.12.0/THANKS geary-0.12.4/THANKS --- geary-0.12.0/THANKS 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/THANKS 2018-08-29 13:57:20.000000000 +0000 @@ -56,6 +56,7 @@ Mario Sanchez Prada Tiago Quelhas Viko Adi Rahmawan +nick richards ritchiew Leonardo Robol Didier Roche diff -Nru geary-0.12.0/ui/client-web-view.js geary-0.12.4/ui/client-web-view.js --- geary-0.12.0/ui/client-web-view.js 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/ui/client-web-view.js 2018-08-29 13:57:20.000000000 +0000 @@ -73,6 +73,7 @@ }, loaded: function() { this.isLoaded = true; + window.webkit.messageHandlers.contentLoaded.postMessage(null); }, loadRemoteImages: function() { this.allowRemoteImages = true; diff -Nru geary-0.12.0/ui/composer-headerbar.ui geary-0.12.4/ui/composer-headerbar.ui --- geary-0.12.0/ui/composer-headerbar.ui 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/ui/composer-headerbar.ui 2018-08-29 13:57:20.000000000 +0000 @@ -26,6 +26,7 @@ Detach (Ctrl+D) + True detach-symbolic 16 diff -Nru geary-0.12.0/ui/composer-web-view.js geary-0.12.4/ui/composer-web-view.js --- geary-0.12.0/ui/composer-web-view.js 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/ui/composer-web-view.js 2018-08-29 13:57:20.000000000 +0000 @@ -59,7 +59,19 @@ let state = this; this.bodyPart = document.getElementById("geary-body"); - if (this.bodyPart == null) { + if (this.bodyPart != null) { + // Capture clicks on the document that aren't on an + // existing part and prevent focus leaving it. Bug 779369. + document.addEventListener("mousedown", function(e) { + if (!state.containedInPart(e.target)) { + e.preventDefault(); + e.stopPropagation(); + } + }); + } else { + // This happens if we are loading a draft created by a MUA + // that isn't Geary, so we can't rely on any of the + // expected HTML structure to be in place. this.bodyPart = document.body; } @@ -381,6 +393,16 @@ this.focusedPart = newFocus; this.focusedPart.classList.add("geary-focus"); } + }, + containedInPart: function(target) { + let inPart = false; + for (let part of [this.bodyPart, this.quotePart, this.signaturePart]) { + if (part != null && (part == target || part.contains(target))) { + inPart = true; + break; + } + } + return inPart; } }; @@ -616,7 +638,7 @@ let styles = window.getComputedStyle(node); let fontFamily = styles.getPropertyValue("font-family"); - if (fontFamily.charAt() == "'") { + if (["'", "\""].indexOf(fontFamily.charAt()) != -1) { fontFamily = fontFamily.substr(1, fontFamily.length - 2); } this.fontFamily = fontFamily; diff -Nru geary-0.12.0/ui/composer-widget.ui geary-0.12.4/ui/composer-widget.ui --- geary-0.12.0/ui/composer-widget.ui 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/ui/composer-widget.ui 2018-08-29 13:57:20.000000000 +0000 @@ -699,6 +699,8 @@ True True + end + 6 diff -Nru geary-0.12.0/ui/conversation-email.ui geary-0.12.4/ui/conversation-email.ui --- geary-0.12.0/ui/conversation-email.ui 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/ui/conversation-email.ui 2018-08-29 13:57:20.000000000 +0000 @@ -310,19 +310,6 @@ False 6 end - - - Try Again - True - True - True - - - True - True - 0 - - False @@ -372,9 +359,6 @@ 0 - - button1 - True diff -Nru geary-0.12.0/ui/conversation-message.ui geary-0.12.4/ui/conversation-message.ui --- geary-0.12.0/ui/conversation-message.ui 2017-10-02 09:53:11.000000000 +0000 +++ geary-0.12.4/ui/conversation-message.ui 2018-08-29 13:57:20.000000000 +0000 @@ -5,6 +5,7 @@