[geary/mjog/plugin-support: 7/13] Convert NewMessagesMonitor into a plugin context



commit 526b12094ffaaea2ddb0634355b51e4efa2948a2
Author: Michael Gratton <mike vee net>
Date:   Fri Sep 27 00:43:08 2019 +1000

    Convert NewMessagesMonitor into a plugin context
    
    Rename class to Application.NotificationContext, add missing API docs
    and make members that shouldn't be public internal or private. Keep an
    instance with the PluginManager instead of with the app controller.
    Update uses of both.

 po/POTFILES.in                                     |   2 +-
 src/client/application/application-controller.vala |  69 ++++---
 .../application-notification-context.vala}         | 211 ++++++++++++---------
 .../application/application-plugin-manager.vala    |   2 +
 src/client/folder-list/folder-list-tree.vala       |   4 +-
 src/client/meson.build                             |   2 +-
 src/client/notification/libmessagingmenu.vala      |   2 +-
 .../notification/new-messages-indicator.vala       |   6 +-
 src/client/notification/notification-desktop.vala  |  58 +++---
 src/client/notification/null-indicator.vala        |   3 +-
 src/client/notification/unity-launcher.vala        |  13 +-
 11 files changed, 216 insertions(+), 156 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5ca2387f..db79d4b8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -20,6 +20,7 @@ src/client/application/application-command.vala
 src/client/application/application-contact-store.vala
 src/client/application/application-contact.vala
 src/client/application/application-controller.vala
+src/client/application/application-notification-context.vala
 src/client/application/application-plugin-manager.vala
 src/client/application/application-startup-manager.vala
 src/client/application/geary-application.vala
@@ -79,7 +80,6 @@ src/client/folder-list/folder-list-tree.vala
 src/client/notification/in-app-notification.vala
 src/client/notification/libmessagingmenu.vala
 src/client/notification/new-messages-indicator.vala
-src/client/notification/new-messages-monitor.vala
 src/client/notification/notification-desktop.vala
 src/client/notification/null-indicator.vala
 src/client/notification/unity-launcher.vala
diff --git a/src/client/application/application-controller.vala 
b/src/client/application/application-controller.vala
index da6c7b2e..4be6860c 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -148,7 +148,6 @@ public class Application.Controller : Geary.BaseObject {
     private UpgradeDialog upgrade_dialog;
     private Folks.IndividualAggregator folks;
     private Canberra.Context sound_context;
-    private NewMessagesMonitor new_messages_monitor;
     private NewMessagesIndicator new_messages_indicator;
     private UnityLauncher unity_launcher;
 
@@ -276,6 +275,12 @@ public class Application.Controller : Geary.BaseObject {
         this.plugin_manager = new PluginManager(
             application.get_app_plugins_dir()
         );
+        this.plugin_manager.notifications = new NotificationContext(
+            this.avatars,
+            this.get_contact_store_for_account,
+            this.should_notify_new_messages
+        );
+
 
         // Create the main window (must be done after creating actions.)
         main_window = new MainWindow(this.application);
@@ -302,27 +307,22 @@ public class Application.Controller : Geary.BaseObject {
         main_window.conversation_viewer.conversation_added.connect(
             on_conversation_view_added
         );
-        this.new_messages_monitor = new NewMessagesMonitor(
-            this.avatars,
-            this.get_contact_store_for_account,
-            this.should_notify_new_messages
-        );
         this.main_window.folder_list.set_new_messages_monitor(
-            this.new_messages_monitor
+            this.plugin_manager.notifications
         );
 
         // New messages indicator (Ubuntuism)
         this.new_messages_indicator = NewMessagesIndicator.create(
-            this.new_messages_monitor, this.application.config
+            this.plugin_manager.notifications, this.application.config
         );
         this.new_messages_indicator.application_activated.connect(on_indicator_activated_application);
         this.new_messages_indicator.composer_activated.connect(on_indicator_activated_composer);
         this.new_messages_indicator.inbox_activated.connect(on_indicator_activated_inbox);
 
-        this.unity_launcher = new UnityLauncher(this.new_messages_monitor);
+        this.unity_launcher = new UnityLauncher(this.plugin_manager.notifications);
 
         this.notifications = new Notification.Desktop(
-            this.new_messages_monitor,
+            this.plugin_manager.notifications,
             this.application,
             cancellable
         );
@@ -423,8 +423,9 @@ public class Application.Controller : Geary.BaseObject {
         // seconds under certain conditions
         this.main_window.hide();
 
-        // Release monitoring early so held resources can be freed up
-        this.new_messages_monitor.clear_folders();
+        // Release notification monitoring early so held resources can
+        // be freed up
+        this.plugin_manager.notifications.clear_folders();
 
         // drop the Revokable, which will commit it if necessary
         save_revokable(null, null);
@@ -1298,11 +1299,11 @@ public class Application.Controller : Geary.BaseObject {
         }
 
         // Update notifications
-        this.new_messages_monitor.remove_folder(folder);
+        this.plugin_manager.notifications.remove_folder(folder);
         if (folder.special_folder_type == Geary.SpecialFolderType.INBOX ||
             (folder.special_folder_type == Geary.SpecialFolderType.NONE &&
              is_inbox_descendant(folder))) {
-            this.new_messages_monitor.add_folder(
+            this.plugin_manager.notifications.add_folder(
                 folder, this.accounts.get(info).cancellable
             );
         }
@@ -1359,14 +1360,18 @@ public class Application.Controller : Geary.BaseObject {
                     folder.open_async.begin(Geary.Folder.OpenFlags.NO_DELAY, cancellable);
 
                     // Always notify for new messages in the Inbox
-                    this.new_messages_monitor.add_folder(folder, cancellable);
+                    this.plugin_manager.notifications.add_folder(
+                        folder, cancellable
+                    );
                     break;
 
                 case Geary.SpecialFolderType.NONE:
                     // Only notify for new messages in non-special
                     // descendants of the Inbox
                     if (is_inbox_descendant(folder)) {
-                        this.new_messages_monitor.add_folder(folder, cancellable);
+                        this.plugin_manager.notifications.add_folder(
+                            folder, cancellable
+                        );
                     }
                     break;
                 }
@@ -1393,14 +1398,14 @@ public class Application.Controller : Geary.BaseObject {
                 switch (folder.special_folder_type) {
                 case Geary.SpecialFolderType.INBOX:
                     context.inbox = null;
-                    new_messages_monitor.remove_folder(folder);
+                    this.plugin_manager.notifications.remove_folder(folder);
                     break;
 
                 case Geary.SpecialFolderType.NONE:
                     // Only notify for new messages in non-special
                     // descendants of the Inbox
                     if (is_inbox_descendant(folder)) {
-                        this.new_messages_monitor.remove_folder(folder);
+                        this.plugin_manager.notifications.remove_folder(folder);
                     }
                     break;
                 }
@@ -1580,19 +1585,25 @@ public class Application.Controller : Geary.BaseObject {
     // Clears messages if conditions are true: anything in should_notify_new_messages() is
     // false and the supplied visible messages are visible in the conversation list view
     private void clear_new_messages(string caller, Gee.Set<Geary.App.Conversation>? supplied) {
-        if (current_folder == null || !new_messages_monitor.get_folders().contains(current_folder)
-            || should_notify_new_messages(current_folder))
-            return;
+        NotificationContext notifications = this.plugin_manager.notifications;
+        if (current_folder != null && (
+                !notifications.get_folders().contains(current_folder) ||
+                should_notify_new_messages(current_folder))) {
 
-        Gee.Set<Geary.App.Conversation> visible =
-            supplied ?? main_window.conversation_list_view.get_visible_conversations();
+            Gee.Set<Geary.App.Conversation> visible =
+                supplied ?? main_window.conversation_list_view.get_visible_conversations();
 
-        foreach (Geary.App.Conversation conversation in visible) {
-            if (new_messages_monitor.are_any_new_messages(current_folder, conversation.get_email_ids())) {
-                debug("Clearing new messages: %s", caller);
-                new_messages_monitor.clear_new_messages(current_folder);
-
-                break;
+            foreach (Geary.App.Conversation conversation in visible) {
+                try {
+                    if (notifications.are_any_new_messages(current_folder,
+                                                           conversation.get_email_ids())) {
+                        debug("Clearing new messages: %s", caller);
+                        notifications.clear_new_messages(current_folder);
+                        break;
+                    }
+                } catch (Geary.EngineError.NOT_FOUND err) {
+                    // all good
+                }
             }
         }
     }
diff --git a/src/client/notification/new-messages-monitor.vala 
b/src/client/application/application-notification-context.vala
similarity index 53%
rename from src/client/notification/new-messages-monitor.vala
rename to src/client/application/application-notification-context.vala
index 85ea6c6d..4aa30911 100644
--- a/src/client/notification/new-messages-monitor.vala
+++ b/src/client/application/application-notification-context.vala
@@ -1,50 +1,75 @@
-/* Copyright 2016 Software Freedom Conservancy Inc.
+/*
+ * Copyright 2016 Software Freedom Conservancy Inc.
+ * Copyright 2019 Michael Gratton <mike vee net>
  *
  * This software is licensed under the GNU Lesser General Public License
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
 
-// NewMessagesMonitor is a central data store for new message information that the various
-// notification methods (GLibNotification, libunity, etc.) can monitor to do their thing.
-// Subclasses should trap the "notify::count" signal and use that to perform whatever magic
-// they need for their implementation, or trap "new-messages" to receive notifications of the emails
-// themselves as they're added.  In the latter case, subscribers should add required Email.Field
-// flags to the object with add_required_fields().
-
-public class NewMessagesMonitor : Geary.BaseObject {
+/**
+ * Provides a context for notification plugins.
+ *
+ * The context provides an interface for notification plugins to
+ * interface with the Geary client application. Notification plugins
+ * will be passed an instance of this class as the `context`
+ * parameter.
+ *
+ * Plugins can connect to the "notify::count", the {@link
+ * new_messages_arrived} or the {@link new_messages_retired} signals
+ * and update their state as these change.
+ */
+public class Application.NotificationContext : Geary.BaseObject {
 
 
     /** Monitor hook for obtaining a contact store for an account. */
-    public delegate Application.ContactStore? GetContactStore(
+    internal delegate Application.ContactStore? GetContactStore(
         Geary.Account account
     );
 
     /** Monitor hook to determine if a folder should be notified about. */
-    public delegate bool ShouldNotifyNewMessages(Geary.Folder folder);
+    internal delegate bool ShouldNotifyNewMessages(Geary.Folder folder);
 
 
     private class MonitorInformation : Geary.BaseObject {
         public Geary.Folder folder;
-        public Cancellable? cancellable = null;
+        public GLib.Cancellable? cancellable = null;
         public int count = 0;
         public Gee.HashSet<Geary.EmailIdentifier> new_ids
             = new Gee.HashSet<Geary.EmailIdentifier>();
 
-        public MonitorInformation(Geary.Folder folder, Cancellable? cancellable) {
+        public MonitorInformation(Geary.Folder folder, GLib.Cancellable? cancellable) {
             this.folder = folder;
             this.cancellable = cancellable;
         }
     }
 
-    public Geary.Email.Field required_fields { get; private set; default = Geary.Email.Field.FLAGS; }
+    /** Current total new message count across all accounts and folders. */
     public int total_new_messages { get; private set; default = 0; }
-    public Geary.Folder? last_new_message_folder { get; private set; default = null; }
-    public Geary.Email? last_new_message { get; private set; default = null; }
 
-    /** Returns an avatar store to lookup avatars for notifications. */
+    /**
+     * Folder containing the recent new message received, if any.
+     *
+     * @see last_new_message
+     */
+    public Geary.Folder? last_new_message_folder {
+        get; private set; default = null;
+    }
+
+    /**
+     * Most recent new message received, if any.
+     *
+     * @see last_new_message_folder
+     */
+    public Geary.Email? last_new_message {
+        get; private set; default = null;
+    }
+
+    /** Returns a store to lookup avatars for notifications. */
     public Application.AvatarStore avatars { get; private set; }
 
 
+    private Geary.Email.Field required_fields { get; private set; default = FLAGS; }
+
     private Gee.Map<Geary.Folder, MonitorInformation> folder_information =
         new Gee.HashMap<Geary.Folder, MonitorInformation>();
 
@@ -52,24 +77,22 @@ public class NewMessagesMonitor : Geary.BaseObject {
     private unowned ShouldNotifyNewMessages notify_delegate;
 
 
+    /** Emitted when a new folder will be monitored. */
     public signal void folder_added(Geary.Folder folder);
 
+    /** Emitted when a folder should no longer be monitored. */
     public signal void folder_removed(Geary.Folder folder);
 
-    /**
-     * Fired when the monitor finds new messages on a folder.
-     */
-    public signal void new_messages_arrived(Geary.Folder folder, int total, int added);
+    /** Emitted when new messages have been downloaded. */
+    public signal void new_messages_arrived(Geary.Folder parent, int total, int added);
 
-    /**
-     * Fired when the monitor clears the "new" status of some messages in the
-     * folder.
-     */
-    public signal void new_messages_retired(Geary.Folder folder, int total);
+    /** Emitted when a folder has been cleared of new messages. */
+    public signal void new_messages_retired(Geary.Folder parent, int total);
 
-    public NewMessagesMonitor(Application.AvatarStore avatars,
-                              GetContactStore contact_store_delegate,
-                              ShouldNotifyNewMessages notify_delegate) {
+    /** Constructs a new context instance. */
+    internal NotificationContext(AvatarStore avatars,
+                                 GetContactStore contact_store_delegate,
+                                 ShouldNotifyNewMessages notify_delegate) {
         this.avatars = avatars;
         this.contact_store_delegate = contact_store_delegate;
         this.notify_delegate = notify_delegate;
@@ -85,66 +108,94 @@ public class NewMessagesMonitor : Geary.BaseObject {
         return this.contact_store_delegate(account);
     }
 
-    public void add_folder(Geary.Folder folder, Cancellable? cancellable = null) {
-        assert(!folder_information.has_key(folder));
+    /** Returns a read-only set the context's monitored folders. */
+    public Gee.Collection<Geary.Folder> get_folders() {
+        return this.folder_information.keys.read_only_view;
+    }
 
-        folder.email_locally_appended.connect(on_email_locally_appended);
-        folder.email_flags_changed.connect(on_email_flags_changed);
-        folder.email_removed.connect(on_email_removed);
+    /** Returns the new message count for a specific folder. */
+    public int get_new_message_count(Geary.Folder folder)
+        throws Geary.EngineError.NOT_FOUND {
+        MonitorInformation? info = folder_information.get(folder);
+        if (info == null) {
+            throw new Geary.EngineError.NOT_FOUND(
+                "No such folder: %s", folder.path.to_string()
+            );
+        }
+        return info.count;
+    }
 
-        folder_information.set(folder, new MonitorInformation(folder, cancellable));
+    /** Adds fields for loaded email required by a plugin. */
+    public void add_required_fields(Geary.Email.Field fields) {
+        this.required_fields |= fields;
+    }
 
-        folder_added(folder);
+    /** Removes fields for loaded email no longer required by a plugin. */
+    public void remove_required_fields(Geary.Email.Field fields) {
+        this.required_fields ^= fields;
     }
 
-    public void remove_folder(Geary.Folder folder) {
-        if (!folder_information.has_key(folder))
-            return;
+    internal void add_folder(Geary.Folder folder, GLib.Cancellable? cancellable) {
+        if (!this.folder_information.has_key(folder)) {
+            folder.email_locally_appended.connect(on_email_locally_appended);
+            folder.email_flags_changed.connect(on_email_flags_changed);
+            folder.email_removed.connect(on_email_removed);
+
+            this.folder_information.set(
+                folder, new MonitorInformation(folder, cancellable)
+            );
 
-        folder.email_locally_appended.disconnect(on_email_locally_appended);
-        folder.email_flags_changed.disconnect(on_email_flags_changed);
-        folder.email_removed.disconnect(on_email_removed);
+            folder_added(folder);
+        }
+    }
 
-        total_new_messages -= folder_information.get(folder).count;
+    internal void remove_folder(Geary.Folder folder) {
+        if (folder_information.has_key(folder)) {
+            folder.email_locally_appended.disconnect(on_email_locally_appended);
+            folder.email_flags_changed.disconnect(on_email_flags_changed);
+            folder.email_removed.disconnect(on_email_removed);
 
-        folder_information.unset(folder);
+            this.total_new_messages -= this.folder_information.get(folder).count;
 
-        folder_removed(folder);
+            this.folder_information.unset(folder);
+
+            folder_removed(folder);
+        }
     }
 
-    /** Releases all monitored folders. */
-    public void clear_folders() {
+    internal void clear_folders() {
         // Get an array so the loop does not blow up when removing values.
         foreach (Geary.Folder monitored in this.folder_information.keys.to_array()) {
             remove_folder(monitored);
         }
     }
 
-    public Gee.Collection<Geary.Folder> get_folders() {
-        return folder_information.keys;
-    }
-
-    public int get_new_message_count(Geary.Folder folder) {
-        assert(folder_information.has_key(folder));
-
-        return folder_information.get(folder).count;
-    }
-
-    public void add_required_fields(Geary.Email.Field fields) {
-        required_fields |= fields;
+    internal bool are_any_new_messages(Geary.Folder folder,
+                                     Gee.Collection<Geary.EmailIdentifier> ids)
+        throws Geary.EngineError.NOT_FOUND {
+        MonitorInformation? info = folder_information.get(folder);
+        if (info == null) {
+            throw new Geary.EngineError.NOT_FOUND(
+                "No such folder: %s", folder.path.to_string()
+            );
+        }
+        return Geary.traverse(ids).any((id) => info.new_ids.contains(id));
     }
 
-    public bool are_any_new_messages(Geary.Folder folder,
-        Gee.Collection<Geary.EmailIdentifier> ids) {
-        assert(folder_information.has_key(folder));
-        MonitorInformation info = folder_information.get(folder);
-
-        foreach (Geary.EmailIdentifier id in ids) {
-            if (info.new_ids.contains(id))
-                return true;
+    internal void clear_new_messages(Geary.Folder folder)
+        throws Geary.EngineError.NOT_FOUND {
+        MonitorInformation? info = folder_information.get(folder);
+        if (info == null) {
+            throw new Geary.EngineError.NOT_FOUND(
+                "No such folder: %s", folder.path.to_string()
+            );
         }
 
-        return false;
+        info.new_ids.clear();
+        last_new_message_folder = null;
+        last_new_message = null;
+
+        update_count(info, false, 0);
     }
 
     private void on_email_locally_appended(Geary.Folder folder,
@@ -225,31 +276,9 @@ public class NewMessagesMonitor : Geary.BaseObject {
         update_count(info, false, removed_count);
     }
 
-    public void clear_new_messages(Geary.Folder folder) {
-        assert(folder_information.has_key(folder));
-        MonitorInformation info = folder_information.get(folder);
-
-        info.new_ids.clear();
-        last_new_message_folder = null;
-        last_new_message = null;
-
-        update_count(info, false, 0);
-    }
-
-    public void clear_all_new_messages() {
-        foreach(Geary.Folder folder in folder_information.keys)
-            clear_new_messages(folder);
-    }
-
     private void update_count(MonitorInformation info, bool arrived, int delta) {
         int new_size = info.new_ids.size;
 
-        // Documentation for "notify" signal seems to suggest that it's possible for the signal to
-        // fire even if the value of the property doesn't change.  Since this signal can trigger
-        // big events, want to avoid firing it unless necessary
-        if (info.count == new_size)
-            return;
-
         total_new_messages += new_size - info.count;
         info.count = new_size;
 
@@ -258,5 +287,5 @@ public class NewMessagesMonitor : Geary.BaseObject {
         else
             new_messages_retired(info.folder, info.count);
     }
-}
 
+}
diff --git a/src/client/application/application-plugin-manager.vala 
b/src/client/application/application-plugin-manager.vala
index 8582fead..9f472478 100644
--- a/src/client/application/application-plugin-manager.vala
+++ b/src/client/application/application-plugin-manager.vala
@@ -11,6 +11,8 @@
 public class Application.PluginManager : GLib.Object {
 
 
+    public NotificationContext notifications { get; set; }
+
     private Peas.Engine engine;
 
 
diff --git a/src/client/folder-list/folder-list-tree.vala b/src/client/folder-list/folder-list-tree.vala
index d7dc2419..dd85275d 100644
--- a/src/client/folder-list/folder-list-tree.vala
+++ b/src/client/folder-list/folder-list-tree.vala
@@ -20,7 +20,7 @@ public class FolderList.Tree : Sidebar.Tree, Geary.BaseInterface {
         = new Gee.HashMap<Geary.Account, AccountBranch>();
     private InboxesBranch inboxes_branch = new InboxesBranch();
     private SearchBranch? search_branch = null;
-    private NewMessagesMonitor? monitor = null;
+    private Application.NotificationContext? monitor = null;
 
     public Tree() {
         base(new Gtk.TargetEntry[0], Gdk.DragAction.ASK, drop_handler);
@@ -80,7 +80,7 @@ public class FolderList.Tree : Sidebar.Tree, Geary.BaseInterface {
         }
     }
 
-    public void set_new_messages_monitor(NewMessagesMonitor? monitor) {
+    public void set_new_messages_monitor(Application.NotificationContext? monitor) {
         if (this.monitor != null) {
             this.monitor.new_messages_arrived.disconnect(on_new_messages_changed);
             this.monitor.new_messages_retired.disconnect(on_new_messages_changed);
diff --git a/src/client/meson.build b/src/client/meson.build
index dc2cdf93..961b19da 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -6,6 +6,7 @@ geary_client_vala_sources = files(
   'application/application-contact-store.vala',
   'application/application-contact.vala',
   'application/application-controller.vala',
+  'application/application-notification-context.vala',
   'application/application-plugin-manager.vala',
   'application/application-startup-manager.vala',
   'application/geary-application.vala',
@@ -87,7 +88,6 @@ geary_client_vala_sources = files(
   'notification/in-app-notification.vala',
   'notification/libmessagingmenu.vala',
   'notification/new-messages-indicator.vala',
-  'notification/new-messages-monitor.vala',
   'notification/null-indicator.vala',
   'notification/unity-launcher.vala',
 
diff --git a/src/client/notification/libmessagingmenu.vala b/src/client/notification/libmessagingmenu.vala
index 7b112529..72b6338c 100644
--- a/src/client/notification/libmessagingmenu.vala
+++ b/src/client/notification/libmessagingmenu.vala
@@ -12,7 +12,7 @@ public class Libmessagingmenu : NewMessagesIndicator {
     private Configuration config;
 
 
-    public Libmessagingmenu(NewMessagesMonitor monitor,
+    public Libmessagingmenu(Application.NotificationContext monitor,
                             Configuration config) {
         base(monitor);
         this.config = config;
diff --git a/src/client/notification/new-messages-indicator.vala 
b/src/client/notification/new-messages-indicator.vala
index 3b8eba6c..1aa96a85 100644
--- a/src/client/notification/new-messages-indicator.vala
+++ b/src/client/notification/new-messages-indicator.vala
@@ -8,7 +8,7 @@
 // compiled at same time) and minimize the exposure of differences to the rest of the application.
 
 public abstract class NewMessagesIndicator : Geary.BaseObject {
-    protected NewMessagesMonitor monitor;
+    protected Application.NotificationContext monitor;
 
     public signal void application_activated(uint32 timestamp);
 
@@ -16,11 +16,11 @@ public abstract class NewMessagesIndicator : Geary.BaseObject {
 
     public signal void composer_activated(uint32 timestamp);
 
-    protected NewMessagesIndicator(NewMessagesMonitor monitor) {
+    protected NewMessagesIndicator(Application.NotificationContext monitor) {
         this.monitor = monitor;
     }
 
-    public static NewMessagesIndicator create(NewMessagesMonitor monitor,
+    public static NewMessagesIndicator create(Application.NotificationContext monitor,
                                               Configuration config) {
         NewMessagesIndicator? indicator = null;
 
diff --git a/src/client/notification/notification-desktop.vala 
b/src/client/notification/notification-desktop.vala
index 6bff58ec..057321ce 100644
--- a/src/client/notification/notification-desktop.vala
+++ b/src/client/notification/notification-desktop.vala
@@ -16,14 +16,14 @@ public class Notification.Desktop : Geary.BaseObject {
     private const string ARRIVED_ID = "email-arrived";
     private const string ERROR_ID = "error";
 
-    private weak NewMessagesMonitor monitor;
+    private weak Application.NotificationContext monitor;
     private weak GearyApplication application;
     private GLib.Notification? arrived_notification = null;
     private GLib.Notification? error_notification = null;
     private GLib.Cancellable load_cancellable;
 
 
-    public Desktop(NewMessagesMonitor monitor,
+    public Desktop(Application.NotificationContext monitor,
                    GearyApplication application,
                    GLib.Cancellable load_cancellable) {
         this.monitor = monitor;
@@ -89,7 +89,14 @@ public class Notification.Desktop : Geary.BaseObject {
                 /// new messages are already awaiting.
                 "%d new message", "%d new messages", added
             ).printf(added);
-            int total = monitor.get_new_message_count(folder);
+
+            int total = 0;
+            try {
+                total = monitor.get_new_message_count(folder);
+            } catch (Geary.EngineError.NOT_FOUND err) {
+                // All good
+            }
+
             if (total > added) {
                 body = ngettext(
                     /// Notification body text for new email when
@@ -121,27 +128,34 @@ public class Notification.Desktop : Geary.BaseObject {
                 originator, cancellable
             );
 
-            string body;
-            int count = monitor.get_new_message_count(folder);
-            if (count <= 1) {
-                body = Util.Email.strip_subject_prefixes(email);
-            } else {
-                body = ngettext(
-                    "%s\n(%d other new message for %s)",
-                    "%s\n(%d other new messages for %s)", count - 1).printf(
-                        Util.Email.strip_subject_prefixes(email),
-                        count - 1,
-                        folder.account.information.display_name
-                    );
+            int count = -1;
+            try {
+                count = monitor.get_new_message_count(folder);
+            } catch (Geary.EngineError.NOT_FOUND err) {
+                // All good
             }
-
-            issue_arrived_notification(
-                contact.is_trusted
+            if (count > -1) {
+                string body = "";
+                if (count <= 1) {
+                    body = Util.Email.strip_subject_prefixes(email);
+                } else {
+                    body = ngettext(
+                        "%s\n(%d other new message for %s)",
+                        "%s\n(%d other new messages for %s)", count - 1).printf(
+                            Util.Email.strip_subject_prefixes(email),
+                            count - 1,
+                            folder.account.information.display_name
+                        );
+                }
+
+                issue_arrived_notification(
+                    contact.is_trusted
                     ? contact.display_name : originator.to_short_display(),
-                body,
-                folder,
-                email.id
-            );
+                    body,
+                    folder,
+                    email.id
+                );
+            }
         } else {
             notify_new_mail(folder, 1);
         }
diff --git a/src/client/notification/null-indicator.vala b/src/client/notification/null-indicator.vala
index ca3950e8..a3a175f3 100644
--- a/src/client/notification/null-indicator.vala
+++ b/src/client/notification/null-indicator.vala
@@ -7,10 +7,9 @@
 // Do-nothing NewMessagesIndicator, used on non-Ubuntu compiles.
 
 public class NullIndicator : NewMessagesIndicator {
-    public NullIndicator(NewMessagesMonitor monitor) {
+    public NullIndicator(Application.NotificationContext monitor) {
         base (monitor);
 
         debug("No messaging menu support in this build");
     }
 }
-
diff --git a/src/client/notification/unity-launcher.vala b/src/client/notification/unity-launcher.vala
index 6fcdfe44..7d44eb94 100644
--- a/src/client/notification/unity-launcher.vala
+++ b/src/client/notification/unity-launcher.vala
@@ -6,10 +6,10 @@
 
 public class UnityLauncher : Geary.BaseObject {
 #if HAVE_LIBUNITY
-    private NewMessagesMonitor? monitor = null;
+    private Application.NotificationContext? monitor = null;
     private Unity.LauncherEntry? entry = null;
 
-    public UnityLauncher(NewMessagesMonitor monitor) {
+    public UnityLauncher(Application.NotificationContext monitor) {
         this.monitor = monitor;
 
         entry = Unity.LauncherEntry.get_for_desktop_id(GearyApplication.APP_ID + ".desktop");
@@ -31,8 +31,13 @@ public class UnityLauncher : Geary.BaseObject {
         // doesn't seem like it's worth too much effort.
         int count = 0;
         foreach (Geary.Folder folder in monitor.get_folders()) {
-            if (monitor.should_notify_new_messages(folder))
-                count += monitor.get_new_message_count(folder);
+            try {
+                if (monitor.should_notify_new_messages(folder)) {
+                    count += monitor.get_new_message_count(folder);
+                }
+            } catch (Geary.EngineError.NOT_FOUND err) {
+                // All good
+            }
         }
 
         set_count(count);


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