[geary/mjog/email-templates: 40/72] Application.FolderContext: New class for aggregating client folder state



commit c4b44b41f67982728a82745aa87a0fd6d7274746
Author: Michael Gratton <mike vee net>
Date:   Thu Apr 2 14:12:55 2020 +1100

    Application.FolderContext: New class for aggregating client folder state
    
    Add new `FolderContext` class to encapsulate client state and policy
    about a specific engine folder. Use it for display name, icon and email
    count bubble policy for now.
    
    Update AccountContext to maintain a set of folder-policy instances per
    account, and convert the folder list over to using the new objects.

 po/POTFILES.in                                     |   1 +
 .../application/application-account-context.vala   |  24 ++++
 src/client/application/application-controller.vala |  45 +++++--
 .../application/application-folder-context.vala    | 108 ++++++++++++++++
 .../application/application-main-window.vala       | 141 ++++++++-------------
 .../folder-list/folder-list-account-branch.vala    |  29 +++--
 .../folder-list/folder-list-folder-entry.vala      | 113 +++++++----------
 .../folder-list-inbox-folder-entry.vala            |   8 +-
 .../folder-list/folder-list-inboxes-branch.vala    |   6 +-
 src/client/folder-list/folder-list-tree.vala       |  31 +++--
 src/client/meson.build                             |   1 +
 11 files changed, 304 insertions(+), 203 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 86341bdb..fafe20ba 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -26,6 +26,7 @@ src/client/application/application-contact.vala
 src/client/application/application-controller.vala
 src/client/application/application-email-plugin-context.vala
 src/client/application/application-email-store-factory.vala
+src/client/application/application-folder-context.vala
 src/client/application/application-folder-plugin-context.vala
 src/client/application/application-folder-store-factory.vala
 src/client/application/application-main-window.vala
diff --git a/src/client/application/application-account-context.vala 
b/src/client/application/application-account-context.vala
index 28a6ed1c..5705677e 100644
--- a/src/client/application/application-account-context.vala
+++ b/src/client/application/application-account-context.vala
@@ -66,6 +66,9 @@ internal class Application.AccountContext : Geary.BaseObject {
         get; internal set; default = false;
     }
 
+    private Gee.Map<Geary.FolderPath,FolderContext> folders =
+        new Gee.HashMap<Geary.FolderPath,FolderContext>();
+
 
     public AccountContext(Geary.Account account,
                           Geary.App.SearchFolder search,
@@ -99,4 +102,25 @@ internal class Application.AccountContext : Geary.BaseObject {
         return effective;
     }
 
+    /**
+     * Returns context for a folder belonging to this context's account.
+     */
+    internal FolderContext? get_folder(Geary.Folder target) {
+        FolderContext? context = null;
+        if (this.account == target.account) {
+            context = this.folders.get(target.path);
+        }
+        return context;
+    }
+
+    /** Adds a context for a folder belonging to the account. */
+    internal void add_folder(FolderContext to_add) {
+        this.folders.set(to_add.folder.path, to_add);
+    }
+
+    /** Adds a context for a folder belonging to the account. */
+    internal void remove_folder(FolderContext to_remove) {
+        this.folders.unset(to_remove.folder.path);
+    }
+
 }
diff --git a/src/client/application/application-controller.vala 
b/src/client/application/application-controller.vala
index dc95c9c7..0be69e63 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -1,6 +1,6 @@
 /*
- * Copyright 2016 Software Freedom Conservancy Inc.
- * Copyright 2016-2019 Michael Gratton <mike vee net>
+ * Copyright © 2016 Software Freedom Conservancy Inc.
+ * Copyright © 2016-2020 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.
@@ -30,15 +30,16 @@ internal class Application.Controller : Geary.BaseObject {
     }
 
     /** Determines if folders should be added to main windows. */
-    public static bool should_add_folder(Gee.Collection<Geary.Folder>? all,
-                                         Geary.Folder folder) {
+    private static bool should_add_folder(Gee.Collection<Geary.Folder>? all,
+                                          Geary.Folder folder) {
         // if folder is openable, add it
         if (folder.properties.is_openable != Geary.Trillian.FALSE)
             return true;
         else if (folder.properties.has_children == Geary.Trillian.FALSE)
             return false;
 
-        // if folder contains children, we must ensure that there is at least one of the same type
+        // if folder contains children, we must ensure that there is
+        // at least one of the same type
         Geary.Folder.SpecialUse type = folder.used_as;
         foreach (Geary.Folder other in all) {
             if (other.used_as == type && other.path.parent == folder.path)
@@ -1248,17 +1249,24 @@ internal class Application.Controller : Geary.BaseObject {
         AccountContext context = this.accounts.get(account.information);
 
         if (available != null && available.size > 0) {
-            foreach (Geary.Folder folder in available) {
-                if (!Controller.should_add_folder(available, folder)) {
-                    continue;
-                }
+            foreach (var folder in available) {
+                if (Controller.should_add_folder(available, folder)) {
+                    if (folder.used_as == INBOX) {
+                        if (context.inbox == null) {
+                            context.inbox = folder;
+                        }
+                        folder.open_async.begin(
+                            NO_DELAY, context.cancellable
+                        );
+                    }
 
-                GLib.Cancellable cancellable = context.cancellable;
-                if (folder.used_as == INBOX) {
-                    if (context.inbox == null) {
-                        context.inbox = folder;
+                    var folder_context = new FolderContext(folder);
+                    context.add_folder(folder_context);
+
+                    foreach (MainWindow main in
+                             this.application.get_main_windows()) {
+                        main.add_folder(folder_context);
                     }
-                    folder.open_async.begin(NO_DELAY, cancellable);
                 }
             }
         }
@@ -1274,6 +1282,15 @@ internal class Application.Controller : Geary.BaseObject {
                     context.inbox = null;
                 }
 
+                var folder_context = context.get_folder(folder);
+                if (folder_context != null) {
+                    context.remove_folder(folder_context);
+                    foreach (MainWindow main in
+                             this.application.get_main_windows()) {
+                        main.remove_folder(folder_context);
+                    }
+                }
+
                 has_prev = unavailable_iterator.previous();
             }
 
diff --git a/src/client/application/application-folder-context.vala 
b/src/client/application/application-folder-context.vala
new file mode 100644
index 00000000..b85c901b
--- /dev/null
+++ b/src/client/application/application-folder-context.vala
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2020 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.
+ */
+
+
+/**
+ * Collects application state related to a single folder.
+ */
+public class Application.FolderContext : Geary.BaseObject {
+
+
+    /** Specifies different kinds of displayable email counts. */
+    public enum EmailCount {
+        /** No email count should be displayed. */
+        NONE,
+        /** The unread email count should be displayed. */
+        UNREAD,
+        /** The total email count should be displayed. */
+        TOTAL;
+    }
+
+    /** The account for this context. */
+    public Geary.Folder folder { get; private set; }
+
+    /** Returns the human-readable name of the folder */
+    public string display_name { get; set; }
+
+    /** The icon to use for the folder */
+    public string icon_name { get; set; }
+
+    /** The count to be displayed for the folder. */
+    public EmailCount displayed_count { get; set; }
+
+
+    public FolderContext(Geary.Folder folder) {
+        this.folder = folder;
+        this.folder.use_changed.connect(() => update());
+        update();
+    }
+
+    private void update() {
+        this.display_name = Util.I18n.to_folder_display_name(this.folder);
+
+        switch (this.folder.used_as) {
+        case INBOX:
+            this.icon_name = "mail-inbox-symbolic";
+            break;
+
+        case DRAFTS:
+            this.icon_name = "mail-drafts-symbolic";
+            break;
+
+        case SENT:
+            this.icon_name = "mail-sent-symbolic";
+            break;
+
+        case FLAGGED:
+            this.icon_name = "starred-symbolic";
+            break;
+
+        case IMPORTANT:
+            this.icon_name = "task-due-symbolic";
+            break;
+
+        case ALL_MAIL:
+        case ARCHIVE:
+            this.icon_name = "mail-archive-symbolic";
+            break;
+
+        case JUNK:
+            this.icon_name = "dialog-warning-symbolic";
+            break;
+
+        case TRASH:
+            this.icon_name = "user-trash-symbolic";
+            break;
+
+        case OUTBOX:
+            this.icon_name = "mail-outbox-symbolic";
+            break;
+
+        default:
+            this.icon_name = "tag-symbolic";
+            break;
+        }
+
+        switch (this.folder.used_as) {
+        case DRAFTS:
+        case OUTBOX:
+            this.displayed_count = TOTAL;
+            break;
+
+        case INBOX:
+        case JUNK:
+        case NONE:
+            this.displayed_count = UNREAD;
+            break;
+
+        default:
+            this.displayed_count = NONE;
+            break;
+        }
+    }
+
+}
diff --git a/src/client/application/application-main-window.vala 
b/src/client/application/application-main-window.vala
index 18327b4d..c058b33a 100644
--- a/src/client/application/application-main-window.vala
+++ b/src/client/application/application-main-window.vala
@@ -985,6 +985,31 @@ public class Application.MainWindow :
         return success;
     }
 
+    /** Adds a folder to the window. */
+    internal void add_folder(FolderContext to_add) {
+        this.folder_list.add_folder(to_add);
+        if (to_add.folder.account == this.selected_account) {
+            this.main_toolbar.copy_folder_menu.add_folder(to_add.folder);
+            this.main_toolbar.move_folder_menu.add_folder(to_add.folder);
+        }
+        to_add.folder.use_changed.connect(
+            on_use_changed
+        );
+    }
+
+    /** Removes a folder from the window. */
+    internal void remove_folder(FolderContext to_remove) {
+        Geary.Folder folder = to_remove.folder;
+        folder.use_changed.disconnect(
+            on_use_changed
+        );
+        if (folder.account == this.selected_account) {
+            this.main_toolbar.copy_folder_menu.remove_folder(folder);
+            this.main_toolbar.move_folder_menu.remove_folder(folder);
+        }
+        this.folder_list.remove_folder(to_remove);
+    }
+
     private void add_account(AccountContext to_add) {
         if (!this.accounts.contains(to_add)) {
             this.folder_list.set_user_folders_root_name(
@@ -1003,18 +1028,13 @@ public class Application.MainWindow :
             to_add.commands.undone.connect(on_command_undo);
             to_add.commands.redone.connect(on_command_redo);
 
-            to_add.account.folders_available_unavailable.connect(
-                on_folders_available_unavailable
-            );
-
-            folders_available(
-                to_add.account,
-                Geary.Account.sort_by_path(to_add.account.list_folders())
-            );
-
-            add_folder(
-                ((Geary.Smtp.ClientService) to_add.account.outgoing).outbox
-            );
+            foreach (Geary.Folder folder in
+                     Geary.Account.sort_by_path(to_add.account.list_folders())) {
+                var folder_context = to_add.get_folder(folder);
+                if (folder_context != null) {
+                    add_folder(folder_context);
+                }
+            }
 
             this.accounts.add(to_add);
         }
@@ -1047,10 +1067,6 @@ public class Application.MainWindow :
                 }
             }
 
-            to_remove.account.folders_available_unavailable.disconnect(
-                on_folders_available_unavailable
-            );
-
             to_remove.commands.executed.disconnect(on_command_execute);
             to_remove.commands.undone.disconnect(on_command_undo);
             to_remove.commands.redone.disconnect(on_command_redo);
@@ -1069,30 +1085,6 @@ public class Application.MainWindow :
         }
     }
 
-    /** Adds a folder to the window. */
-    private void add_folder(Geary.Folder to_add) {
-        this.folder_list.add_folder(to_add);
-        if (to_add.account == this.selected_account) {
-            this.main_toolbar.copy_folder_menu.add_folder(to_add);
-            this.main_toolbar.move_folder_menu.add_folder(to_add);
-        }
-        to_add.use_changed.connect(
-            on_use_changed
-        );
-    }
-
-    /** Removes a folder from the window. */
-    private void remove_folder(Geary.Folder to_remove) {
-        to_remove.use_changed.disconnect(
-            on_use_changed
-        );
-        if (to_remove.account == this.selected_account) {
-            this.main_toolbar.copy_folder_menu.remove_folder(to_remove);
-            this.main_toolbar.move_folder_menu.remove_folder(to_remove);
-        }
-        this.folder_list.remove_folder(to_remove);
-    }
-
     private AccountContext? get_selected_account_context() {
         AccountContext? context = null;
         if (this.selected_account != null) {
@@ -1511,27 +1503,6 @@ public class Application.MainWindow :
         }
     }
 
-    private void folders_available(Geary.Account account,
-                                   Gee.BidirSortedSet<Geary.Folder> available) {
-        foreach (Geary.Folder folder in available) {
-            if (Controller.should_add_folder(available, folder)) {
-                add_folder(folder);
-            }
-        }
-    }
-
-    private void folders_unavailable(Geary.Account account,
-                                     Gee.BidirSortedSet<Geary.Folder> unavailable) {
-        var unavailable_iterator = unavailable.bidir_iterator();
-        bool has_prev = unavailable_iterator.last();
-        while (has_prev) {
-            Geary.Folder folder = unavailable_iterator.get();
-            remove_folder(folder);
-
-            has_prev = unavailable_iterator.previous();
-        }
-    }
-
     private async void open_conversation_monitor(Geary.App.ConversationMonitor to_open,
                                                  GLib.Cancellable cancellable) {
         to_open.scan_completed.connect(on_scan_completed);
@@ -1978,36 +1949,34 @@ public class Application.MainWindow :
         this.remove_account.begin(account, to_select);
     }
 
-    private void on_folders_available_unavailable(
-        Geary.Account account,
-        Gee.BidirSortedSet<Geary.Folder>? available,
-        Gee.BidirSortedSet<Geary.Folder>? unavailable
-    ) {
-        if (available != null) {
-            folders_available(account, available);
-        }
-        if (unavailable != null) {
-            folders_unavailable(account, unavailable);
-        }
-    }
-
     private void on_use_changed(Geary.Folder folder,
                                 Geary.Folder.SpecialUse old_type,
                                 Geary.Folder.SpecialUse new_type) {
         // Update the main window
-        this.folder_list.remove_folder(folder);
-        this.folder_list.add_folder(folder);
-
-        // Since removing the folder will also remove its children
-        // from the folder list, we need to check for any and re-add
-        // them. See issue #11.
-        try {
-            foreach (Geary.Folder child in
-                     folder.account.list_matching_folders(folder.path)) {
-                this.folder_list.add_folder(child);
+        AccountContext? context = this.controller.get_context_for_account(
+            folder.account.information
+        );
+        if (context != null) {
+            FolderContext? folder_context = context.get_folder(folder);
+            if (folder_context != null) {
+                this.folder_list.remove_folder(folder_context);
+                this.folder_list.add_folder(folder_context);
+
+                // Since removing the folder will also remove its children
+                // from the folder list, we need to check for any and re-add
+                // them. See issue #11.
+                try {
+                    foreach (Geary.Folder child in
+                             folder.account.list_matching_folders(folder.path)) {
+                        FolderContext? child_context = context.get_folder(child);
+                        if (child_context != null) {
+                            this.folder_list.add_folder(child_context);
+                        }
+                    }
+                } catch (Error err) {
+                    // Oh well
+                }
             }
-        } catch (Error err) {
-            // Oh well
         }
     }
 
diff --git a/src/client/folder-list/folder-list-account-branch.vala 
b/src/client/folder-list/folder-list-account-branch.vala
index 7aeca9fc..2f94952f 100644
--- a/src/client/folder-list/folder-list-account-branch.vala
+++ b/src/client/folder-list/folder-list-account-branch.vala
@@ -74,17 +74,17 @@ public class FolderList.AccountBranch : Sidebar.Branch {
         return folder_entries.get(folder_path);
     }
 
-    public void add_folder(Geary.Folder folder) {
+    public void add_folder(Application.FolderContext context) {
         Sidebar.Entry? graft_point = null;
-        FolderEntry folder_entry = new FolderEntry(folder);
-        Geary.Folder.SpecialUse used_as = folder.used_as;
+        FolderEntry folder_entry = new FolderEntry(context);
+        Geary.Folder.SpecialUse used_as = context.folder.used_as;
         if (used_as != NONE) {
             if (used_as == SEARCH)
                 return; // Don't show search folder under the account.
 
             // Special folders go in the root of the account.
             graft_point = get_root();
-        } else if (folder.path.is_top_level) {
+        } else if (context.folder.path.is_top_level) {
             // Top-level folders get put in our special user folders group.
             graft_point = user_folder_group;
 
@@ -92,7 +92,7 @@ public class FolderList.AccountBranch : Sidebar.Branch {
                 graft(get_root(), user_folder_group);
             }
         } else {
-            Sidebar.Entry? entry = folder_entries.get(folder.path.parent);
+            var entry = folder_entries.get(context.folder.path.parent);
             if (entry != null)
                 graft_point = entry;
         }
@@ -111,22 +111,25 @@ public class FolderList.AccountBranch : Sidebar.Branch {
 
         if (graft_point != null) {
             graft(graft_point, folder_entry);
-            folder_entries.set(folder.path, folder_entry);
+            folder_entries.set(context.folder.path, folder_entry);
         } else {
-            debug("Could not add folder %s of type %s to folder list", folder.to_string(),
-                  used_as.to_string());
+            debug(
+                "Could not add folder %s of type %s to folder list",
+                context.folder.to_string(),
+                used_as.to_string()
+            );
         }
     }
 
-    public void remove_folder(Geary.Folder folder) {
-        Sidebar.Entry? entry = folder_entries.get(folder.path);
-        if(entry == null) {
-            debug("Could not remove folder %s", folder.to_string());
+    public void remove_folder(Geary.FolderPath path) {
+        Sidebar.Entry? entry = this.folder_entries.get(path);
+        if (entry == null) {
+            debug("Could not remove folder %s", path.to_string());
             return;
         }
 
         prune(entry);
-        folder_entries.unset(folder.path);
+        this.folder_entries.unset(path);
     }
 
     private void on_entry_removed(Sidebar.Entry entry) {
diff --git a/src/client/folder-list/folder-list-folder-entry.vala 
b/src/client/folder-list/folder-list-folder-entry.vala
index 7c23495a..d27c46fc 100644
--- a/src/client/folder-list/folder-list-folder-entry.vala
+++ b/src/client/folder-list/folder-list-folder-entry.vala
@@ -5,80 +5,61 @@
  */
 
 // A folder of any type in the folder list.
-public class FolderList.FolderEntry : FolderList.AbstractFolderEntry, Sidebar.InternalDropTargetEntry,
+public class FolderList.FolderEntry :
+    FolderList.AbstractFolderEntry,
+    Sidebar.InternalDropTargetEntry,
     Sidebar.EmphasizableEntry {
+
+
+    private Application.FolderContext context;
     private bool has_new;
 
-    public FolderEntry(Geary.Folder folder) {
-        base(folder);
-        has_new = false;
-        folder.properties.notify[Geary.FolderProperties.PROP_NAME_EMAIL_TOTAL].connect(on_counts_changed);
-        folder.properties.notify[Geary.FolderProperties.PROP_NAME_EMAIL_UNREAD].connect(on_counts_changed);
+
+    public FolderEntry(Application.FolderContext context) {
+        base(context.folder);
+        this.context = context;
+        this.has_new = false;
+        
this.folder.properties.notify[Geary.FolderProperties.PROP_NAME_EMAIL_TOTAL].connect(on_counts_changed);
+        
this.folder.properties.notify[Geary.FolderProperties.PROP_NAME_EMAIL_UNREAD].connect(on_counts_changed);
     }
 
     ~FolderEntry() {
-        folder.properties.notify[Geary.FolderProperties.PROP_NAME_EMAIL_TOTAL].disconnect(on_counts_changed);
-        
folder.properties.notify[Geary.FolderProperties.PROP_NAME_EMAIL_UNREAD].disconnect(on_counts_changed);
+        
this.folder.properties.notify[Geary.FolderProperties.PROP_NAME_EMAIL_TOTAL].disconnect(on_counts_changed);
+        
this.folder.properties.notify[Geary.FolderProperties.PROP_NAME_EMAIL_UNREAD].disconnect(on_counts_changed);
     }
 
     public override string get_sidebar_name() {
-        return Util.I18n.to_folder_display_name(this.folder);
+        return this.context.display_name;
     }
 
     public override string? get_sidebar_tooltip() {
-        // Label displaying total number of email messages in a folder
-        string total_msg = ngettext("%d message", "%d messages", folder.properties.email_total).
-            printf(folder.properties.email_total);
+        // Translators: Label displaying total number of email
+        // messages in a folder. String substitution is the actual
+        // number.
+        string total_msg = ngettext(
+            "%d message", "%d messages", folder.properties.email_total
+        ).printf(folder.properties.email_total);
 
         if (folder.properties.email_unread == 0)
             return total_msg;
 
-        /// Label displaying number of unread email messages in a folder
-        string unread_msg = ngettext("%d unread", "%d unread", folder.properties.email_unread).
-            printf(folder.properties.email_unread);
-
-        /// This string represents the divider between two messages: "n messages" and "n unread",
-        /// shown in the folder list as a tooltip.  Please use your languages conventions for
-        /// combining the two, i.e. a comma (",") for English; "6 messages, 3 unread"
+        // Translators: Label displaying number of unread email
+        // messages in a folder. String substitution is the actual
+        // number.
+        string unread_msg = ngettext(
+            "%d unread", "%d unread", folder.properties.email_unread
+        ).printf(folder.properties.email_unread);
+
+        // Translators: This string represents the divider between two
+        // messages: "n messages" and "n unread", shown in the folder
+        // list as a tooltip.  Please use your languages conventions
+        // for combining the two, i.e. a comma (",") for English; "6
+        // messages, 3 unread"
         return _("%s, %s").printf(total_msg, unread_msg);
     }
 
     public override string? get_sidebar_icon() {
-        switch (folder.used_as) {
-            case NONE:
-                return "tag-symbolic";
-
-            case INBOX:
-                return "mail-inbox-symbolic";
-
-            case DRAFTS:
-                return "mail-drafts-symbolic";
-
-            case SENT:
-                return "mail-sent-symbolic";
-
-            case FLAGGED:
-                return "starred-symbolic";
-
-            case IMPORTANT:
-                return "task-due-symbolic";
-
-            case ALL_MAIL:
-            case ARCHIVE:
-                return "mail-archive-symbolic";
-
-            case JUNK:
-                return "dialog-warning-symbolic";
-
-            case TRASH:
-                return "user-trash-symbolic";
-
-            case OUTBOX:
-                return "mail-outbox-symbolic";
-
-            default:
-                assert_not_reached();
-        }
+        return this.context.icon_name;
     }
 
     public override string to_string() {
@@ -119,21 +100,15 @@ public class FolderList.FolderEntry : FolderList.AbstractFolderEntry, Sidebar.In
     }
 
     public override int get_count() {
-        switch (folder.used_as) {
-            // for Drafts and Outbox, interested in showing total count, not unread count
-            case DRAFTS:
-            case OUTBOX:
-                return folder.properties.email_total;
-
-            // only show counts for Inbox, Junk, and user folders
-            case INBOX:
-            case JUNK:
-            case NONE:
-                return folder.properties.email_unread;
-
-            // otherwise, to avoid clutter, no counts displayed (but are available in tooltip)
-            default:
-                return 0;
+        switch (this.context.displayed_count) {
+        case TOTAL:
+            return folder.properties.email_total;
+
+        case UNREAD:
+            return folder.properties.email_unread;
+
+        default:
+            return 0;
         }
     }
 }
diff --git a/src/client/folder-list/folder-list-inbox-folder-entry.vala 
b/src/client/folder-list/folder-list-inbox-folder-entry.vala
index 652ad3b3..53c7a50e 100644
--- a/src/client/folder-list/folder-list-inbox-folder-entry.vala
+++ b/src/client/folder-list/folder-list-inbox-folder-entry.vala
@@ -11,10 +11,10 @@ public class FolderList.InboxFolderEntry : FolderList.FolderEntry {
     private string display_name = "";
 
 
-    public InboxFolderEntry(Geary.Folder folder) {
-        base(folder);
-        this.display_name = folder.account.information.display_name;
-        folder.account.information.changed.connect(on_information_changed);
+    public InboxFolderEntry(Application.FolderContext context) {
+        base(context);
+        this.display_name = context.folder.account.information.display_name;
+        context.folder.account.information.changed.connect(on_information_changed);
     }
 
     ~InboxFolderEntry() {
diff --git a/src/client/folder-list/folder-list-inboxes-branch.vala 
b/src/client/folder-list/folder-list-inboxes-branch.vala
index 0e7d1ba8..e971f402 100644
--- a/src/client/folder-list/folder-list-inboxes-branch.vala
+++ b/src/client/folder-list/folder-list-inboxes-branch.vala
@@ -29,12 +29,12 @@ public class FolderList.InboxesBranch : Sidebar.Branch {
         return folder_entries.get(account);
     }
 
-    public void add_inbox(Geary.Folder inbox) {
+    public void add_inbox(Application.FolderContext inbox) {
         InboxFolderEntry folder_entry = new InboxFolderEntry(inbox);
         graft(get_root(), folder_entry);
 
-        folder_entries.set(inbox.account, folder_entry);
-        inbox.account.information.notify["ordinal"].connect(on_ordinal_changed);
+        folder_entries.set(inbox.folder.account, folder_entry);
+        inbox.folder.account.information.notify["ordinal"].connect(on_ordinal_changed);
     }
 
     public void remove_inbox(Geary.Account account) {
diff --git a/src/client/folder-list/folder-list-tree.vala b/src/client/folder-list/folder-list-tree.vala
index a3c8432f..fb91347e 100644
--- a/src/client/folder-list/folder-list-tree.vala
+++ b/src/client/folder-list/folder-list-tree.vala
@@ -92,36 +92,39 @@ public class FolderList.Tree : Sidebar.Tree, Geary.BaseInterface {
             account_branches.get(account).user_folder_group.rename(name);
     }
 
-    public void add_folder(Geary.Folder folder) {
+    public void add_folder(Application.FolderContext context) {
+        Geary.Folder folder = context.folder;
         Geary.Account account = folder.account;
+
         if (!account_branches.has_key(account)) {
             this.account_branches.set(account, new AccountBranch(account));
             account.information.notify["ordinal"].connect(on_ordinal_changed);
         }
 
-        AccountBranch account_branch = account_branches.get(folder.account);
+        var account_branch = this.account_branches.get(account);
         if (!has_branch(account_branch))
-            graft(account_branch, folder.account.information.ordinal);
+            graft(account_branch, account.information.ordinal);
 
         if (account_branches.size > 1 && !has_branch(inboxes_branch))
             graft(inboxes_branch, INBOX_ORDINAL); // The Inboxes branch comes first.
         if (folder.used_as == INBOX)
-            inboxes_branch.add_inbox(folder);
+            inboxes_branch.add_inbox(context);
 
-        account_branch.add_folder(folder);
+        account_branch.add_folder(context);
     }
 
-    public void remove_folder(Geary.Folder folder) {
-        AccountBranch? account_branch = account_branches.get(folder.account);
-        assert(account_branch != null);
-        assert(has_branch(account_branch));
+    public void remove_folder(Application.FolderContext context) {
+        Geary.Folder folder = context.folder;
+        Geary.Account account = folder.account;
+
+        var account_branch = this.account_branches.get(account);
 
         // If this is the current folder, unselect it.
-        Sidebar.Entry? entry = account_branch.get_entry_for_path(folder.path);
+        var entry = account_branch.get_entry_for_path(folder.path);
 
         // if not found or found but not selected, see if the folder is in the Inboxes branch
-        if (has_branch(inboxes_branch) && (entry == null || !is_selected(entry))) {
-            InboxFolderEntry? inbox_entry = inboxes_branch.get_entry_for_account(folder.account);
+        if (has_branch(this.inboxes_branch) && (entry == null || !is_selected(entry))) {
+            var inbox_entry = this.inboxes_branch.get_entry_for_account(account);
             if (inbox_entry != null && inbox_entry.folder == folder)
                 entry = inbox_entry;
         }
@@ -133,9 +136,9 @@ public class FolderList.Tree : Sidebar.Tree, Geary.BaseInterface {
 
         // if Inbox, remove from inboxes branch, selected or not
         if (folder.used_as == INBOX)
-            inboxes_branch.remove_inbox(folder.account);
+            inboxes_branch.remove_inbox(account);
 
-        account_branch.remove_folder(folder);
+        account_branch.remove_folder(folder.path);
     }
 
     public void remove_account(Geary.Account account) {
diff --git a/src/client/meson.build b/src/client/meson.build
index 75c1712b..7fcb3a43 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -23,6 +23,7 @@ geary_client_vala_sources = files(
   'application/application-controller.vala',
   'application/application-email-plugin-context.vala',
   'application/application-email-store-factory.vala',
+  'application/application-folder-context.vala',
   'application/application-folder-plugin-context.vala',
   'application/application-folder-store-factory.vala',
   'application/application-main-window.vala',


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