[geary/wip/714104-refine-account-dialog: 3/5] Tidy up account info sender mailbox implementation



commit fa5ecf0c22c2db1e468a10df1e728e9dd448dba1
Author: Michael Gratton <mike vee net>
Date:   Sun Dec 2 12:43:38 2018 +1100

    Tidy up account info sender mailbox implementation
    
    This finishes conversion from the old approach (primary+aliase list) to
    the new (a single ordered list). API is simplified a bit, and some
    convenience properties are added.

 .../account-dialog-edit-alternate-emails-pane.vala |   6 +-
 src/client/accounts/accounts-editor-add-pane.vala  |   4 +-
 src/client/accounts/accounts-editor-edit-pane.vala |  24 +--
 src/client/accounts/accounts-manager.vala          |  22 +--
 src/client/accounts/add-edit-page.vala             |   6 +-
 src/client/composer/composer-widget.vala           |  56 +++---
 .../conversation-list/conversation-list-store.vala |   2 +-
 .../conversation-viewer/conversation-list-box.vala |   2 +-
 src/engine/api/geary-account-information.vala      | 187 +++++++--------------
 src/engine/rfc822/rfc822-mailbox-address.vala      |  17 +-
 src/engine/smtp/smtp-client-service.vala           |   2 +-
 .../engine/api/geary-account-information-test.vala |  23 ++-
 12 files changed, 156 insertions(+), 195 deletions(-)
---
diff --git a/src/client/accounts/account-dialog-edit-alternate-emails-pane.vala 
b/src/client/accounts/account-dialog-edit-alternate-emails-pane.vala
index 07cda614..65e7f4bd 100644
--- a/src/client/accounts/account-dialog-edit-alternate-emails-pane.vala
+++ b/src/client/accounts/account-dialog-edit-alternate-emails-pane.vala
@@ -125,8 +125,8 @@ public class AccountDialogEditAlternateEmailsPane : AccountDialogPane {
             address_listbox.remove(widget);
         
         // Add all email addresses; add_email_address() silently drops the primary address
-        foreach (Geary.RFC822.MailboxAddress mailbox in account_info.get_all_mailboxes())
-            add_mailbox(mailbox, false);
+        //foreach (Geary.RFC822.MailboxAddress mailbox in account_info.get_all_mailboxes())
+        //    add_mailbox(mailbox, false);
     }
     
     public override void present() {
@@ -193,7 +193,7 @@ public class AccountDialogEditAlternateEmailsPane : AccountDialogPane {
     }
     
     private void on_update_clicked() {
-        account_info.replace_alternate_mailboxes(mailboxes);
+        //account_info.replace_alternate_mailboxes(mailboxes);
         
         done();
     }
diff --git a/src/client/accounts/accounts-editor-add-pane.vala 
b/src/client/accounts/accounts-editor-add-pane.vala
index 468d0c0b..bb85ab25 100644
--- a/src/client/accounts/accounts-editor-add-pane.vala
+++ b/src/client/accounts/accounts-editor-add-pane.vala
@@ -165,10 +165,10 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
         Geary.AccountInformation account =
             this.accounts.new_orphan_account(this.provider, imap, smtp);
 
-        account.primary_mailbox = new Geary.RFC822.MailboxAddress(
+        account.append_sender(new Geary.RFC822.MailboxAddress(
             this.real_name.value.text.strip(),
             this.email.value.text.strip()
-        );
+        ));
         account.nickname = account.primary_mailbox.address;
 
         if (this.provider == Geary.ServiceProvider.OTHER) {
diff --git a/src/client/accounts/accounts-editor-edit-pane.vala 
b/src/client/accounts/accounts-editor-edit-pane.vala
index 5bbbef14..4e8c1c30 100644
--- a/src/client/accounts/accounts-editor-edit-pane.vala
+++ b/src/client/accounts/accounts-editor-edit-pane.vala
@@ -346,7 +346,7 @@ private class Accounts.MailboxRow : AccountRow<EditorEditPane,Gtk.Label> {
         MailboxEditorPopover popover = new MailboxEditorPopover(
             this.mailbox.name ?? "",
             this.mailbox.address,
-            this.account.get_sender_mailboxes().size > 1
+            this.account.has_sender_aliases
         );
         popover.activated.connect(() => {
                 pane.commands.execute.begin(
@@ -517,7 +517,7 @@ internal class Accounts.AppendMailboxCommand : Application.Command {
         this.senders_list = senders_list;
         this.new_row = new_row;
 
-        this.mailbox_index = new_row.account.get_sender_mailboxes().size;
+        this.mailbox_index = new_row.account.sender_mailboxes.size;
 
         // Translators: Label used as the undo tooltip after adding an
         // new sender email address to an account. The string
@@ -527,13 +527,13 @@ internal class Accounts.AppendMailboxCommand : Application.Command {
 
     public async override void execute(GLib.Cancellable? cancellable) {
         this.senders_list.insert(this.new_row, this.mailbox_index);
-        this.new_row.account.append_sender_mailbox(this.new_row.mailbox);
+        this.new_row.account.append_sender(this.new_row.mailbox);
         this.new_row.account.information_changed();
     }
 
     public async override void undo(GLib.Cancellable? cancellable) {
         this.senders_list.remove(this.new_row);
-        this.new_row.account.remove_sender_mailbox(this.new_row.mailbox);
+        this.new_row.account.remove_sender(this.new_row.mailbox);
         this.new_row.account.information_changed();
     }
 
@@ -557,7 +557,7 @@ internal class Accounts.UpdateMailboxCommand : Application.Command {
 
         this.old_mailbox = row.mailbox;
         this.mailbox_index =
-            row.account.get_sender_mailboxes().index_of(this.old_mailbox);
+            row.account.sender_mailboxes.index_of(this.old_mailbox);
 
         // Translators: Label used as the undo tooltip after editing a
         // sender address for an account. The string substitution is
@@ -569,15 +569,15 @@ internal class Accounts.UpdateMailboxCommand : Application.Command {
 
     public async override void execute(GLib.Cancellable? cancellable) {
         this.row.mailbox = this.new_mailbox;
-        this.row.account.remove_sender_mailbox(this.old_mailbox);
-        this.row.account.insert_sender_mailbox(this.mailbox_index, this.new_mailbox);
+        this.row.account.remove_sender(this.old_mailbox);
+        this.row.account.insert_sender(this.mailbox_index, this.new_mailbox);
         this.row.account.information_changed();
     }
 
     public async override void undo(GLib.Cancellable? cancellable) {
         this.row.mailbox = this.old_mailbox;
-        this.row.account.remove_sender_mailbox(this.new_mailbox);
-        this.row.account.insert_sender_mailbox(this.mailbox_index, this.old_mailbox);
+        this.row.account.remove_sender(this.new_mailbox);
+        this.row.account.insert_sender(this.mailbox_index, this.old_mailbox);
         this.row.account.information_changed();
     }
 
@@ -599,7 +599,7 @@ internal class Accounts.RemoveMailboxCommand : Application.Command {
 
         this.mailbox = row.mailbox;
         this.mailbox_index =
-            row.account.get_sender_mailboxes().index_of(mailbox);
+            row.account.sender_mailboxes.index_of(mailbox);
         this.list = (Gtk.ListBox) row.get_parent();
 
         // Translators: Label used as the undo tooltip after removing
@@ -610,13 +610,13 @@ internal class Accounts.RemoveMailboxCommand : Application.Command {
 
     public async override void execute(GLib.Cancellable? cancellable) {
         this.list.remove(this.row);
-        this.row.account.remove_sender_mailbox(this.mailbox);
+        this.row.account.remove_sender(this.mailbox);
         this.row.account.information_changed();
     }
 
     public async override void undo(GLib.Cancellable? cancellable) {
         this.list.insert(this.row, this.mailbox_index);
-        this.row.account.insert_sender_mailbox(this.mailbox_index, this.mailbox);
+        this.row.account.insert_sender(this.mailbox_index, this.mailbox);
         this.row.account.information_changed();
     }
 
diff --git a/src/client/accounts/accounts-manager.vala b/src/client/accounts/accounts-manager.vala
index fbbf5b46..836085bd 100644
--- a/src/client/accounts/accounts-manager.vala
+++ b/src/client/accounts/accounts-manager.vala
@@ -551,9 +551,9 @@ public class Accounts.Manager : GLib.Object {
         if (info.ordinal >= Geary.AccountInformation.next_ordinal)
             Geary.AccountInformation.next_ordinal = info.ordinal + 1;
 
-        info.primary_mailbox = new Geary.RFC822.MailboxAddress(
+        info.append_sender(new Geary.RFC822.MailboxAddress(
             config.get_string(REAL_NAME_KEY), primary_email
-        );
+        ));
 
         info.nickname = config.get_string(NICKNAME_KEY);
 
@@ -565,7 +565,7 @@ public class Accounts.Manager : GLib.Object {
             foreach (string alt_email in alt_email_list) {
                 Geary.RFC822.MailboxAddresses mailboxes = new 
Geary.RFC822.MailboxAddresses.from_rfc822_string(alt_email);
                 foreach (Geary.RFC822.MailboxAddress mailbox in mailboxes.get_all())
-                info.add_alternate_mailbox(mailbox);
+                info.append_sender(mailbox);
             }
         }
 
@@ -680,14 +680,16 @@ public class Accounts.Manager : GLib.Object {
         config.set_bool(SAVE_SENT_MAIL_KEY, info.save_sent_mail);
         config.set_bool(USE_EMAIL_SIGNATURE_KEY, info.use_email_signature);
         config.set_escaped_string(EMAIL_SIGNATURE_KEY, info.email_signature);
-        if (info.alternate_mailboxes != null && info.alternate_mailboxes.size > 0) {
-            string[] list = new string[info.alternate_mailboxes.size];
-            for (int ctr = 0; ctr < info.alternate_mailboxes.size; ctr++)
-                list[ctr] = info.alternate_mailboxes[ctr].to_rfc822_string();
+        if (info.has_sender_aliases) {
+            Gee.List<Geary.RFC822.MailboxAddress> alts = info.sender_mailboxes;
+            alts.remove_at(0);
 
-            config.set_string_list(
-                ALTERNATE_EMAILS_KEY, Geary.Collection.array_list_wrap<string>(list)
-            );
+            Gee.List<string> values = new Gee.LinkedList<string>();
+            foreach (Geary.RFC822.MailboxAddress alt in alts) {
+                values.add(alt.to_rfc822_string());
+            }
+
+            config.set_string_list(ALTERNATE_EMAILS_KEY, values);
         }
 
         Gee.LinkedList<string> empty = new Gee.LinkedList<string>();
diff --git a/src/client/accounts/add-edit-page.vala b/src/client/accounts/add-edit-page.vala
index 07d399f1..a022c9fe 100644
--- a/src/client/accounts/add-edit-page.vala
+++ b/src/client/accounts/add-edit-page.vala
@@ -716,9 +716,9 @@ public class AddEditPage : Gtk.Box {
         }
 
         if (info != null) {
-            info.primary_mailbox = new Geary.RFC822.MailboxAddress(
-                this.real_name.strip(), this.email_address.strip()
-            );
+            //info.primary_mailbox = new Geary.RFC822.MailboxAddress(
+            //    this.real_name.strip(), this.email_address.strip()
+            //);
             info.nickname = this.nickname.strip();
             info.imap.credentials = imap_credentials;
             info.smtp.credentials = smtp_credentials;
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 978cdd08..f774761e 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -403,7 +403,8 @@ public class ComposerWidget : Gtk.EventBox {
         this.compose_type = compose_type;
         if (this.compose_type == ComposeType.NEW_MESSAGE)
             this.state = ComposerState.PANED;
-        else if (this.compose_type == ComposeType.FORWARD || this.account.information.alternate_mailboxes != 
null)
+        else if (this.compose_type == ComposeType.FORWARD ||
+                 this.account.information.has_sender_aliases)
             this.state = ComposerState.INLINE;
         else
             this.state = ComposerState.INLINE_COMPACT;
@@ -715,7 +716,7 @@ public class ComposerWidget : Gtk.EventBox {
             this.state = ComposerState.PANED;
         } else if (this.compose_type == ComposeType.FORWARD || this.to_entry.modified
                    || this.cc_entry.modified || this.bcc_entry.modified
-                   || this.account.information.alternate_mailboxes != null) {
+                   || this.account.information.has_sender_aliases) {
             this.state = ComposerState.INLINE;
         } else {
             this.state = ComposerState.INLINE_COMPACT;
@@ -1039,7 +1040,7 @@ public class ComposerWidget : Gtk.EventBox {
     private void add_recipients_and_ids(ComposeType type, Geary.Email referred,
         bool modify_headers = true) {
         Gee.List<Geary.RFC822.MailboxAddress> sender_addresses =
-            account.information.get_all_mailboxes();
+            account.information.sender_mailboxes;
 
         // Set the preferred from address. New messages should retain
         // the account default and drafts should retain the draft's
@@ -2013,25 +2014,32 @@ public class ComposerWidget : Gtk.EventBox {
             set_active = true;
         }
 
-        if (other_account.information.alternate_mailboxes != null) {
-            foreach (Geary.RFC822.MailboxAddress alternate_mailbox in 
other_account.information.alternate_mailboxes) {
-                Geary.RFC822.MailboxAddresses addresses = new Geary.RFC822.MailboxAddresses.single(
-                    alternate_mailbox);
-                
-                // 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.
-                string display = _("%1$s via %2$s").printf(
-                    addresses.to_full_display(),
-                    other_account.information.display_name
+        bool is_primary = true;
+        foreach (Geary.RFC822.MailboxAddress alternate_mailbox in
+                 other_account.information.sender_mailboxes) {
+            Geary.RFC822.MailboxAddresses addresses =
+            new Geary.RFC822.MailboxAddresses.single(alternate_mailbox);
+
+            string display = primary_address.to_full_display();
+            if (!is_primary) {
+                // 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.
+                display = _("%1$s via %2$s").printf(
+                    display, other_account.information.display_name
                 );
-                this.from_multiple.append_text(display);
-                this.from_list.add(new FromAddressMap(other_account, addresses));
-                
-                if (!set_active && this.from.equal_to(addresses)) {
-                    this.from_multiple.set_active(this.from_list.size - 1);
-                    set_active = true;
-                }
+            } else {
+                is_primary = false;
+            }
+
+            this.from_multiple.append_text(display);
+            this.from_list.add(new FromAddressMap(other_account, addresses));
+
+            if (!set_active && this.from.equal_to(addresses)) {
+                this.from_multiple.set_active(this.from_list.size - 1);
+                set_active = true;
             }
         }
         return set_active;
@@ -2067,12 +2075,12 @@ public class ComposerWidget : Gtk.EventBox {
         // Don't show in inline, compact, or paned modes, unless the current
         // account has multiple emails.
         if ((this.state == ComposerState.INLINE || this.state == ComposerState.INLINE_COMPACT ||
-             this.state == ComposerState.PANED) && this.account.information.alternate_mailboxes == null)
+             this.state == ComposerState.PANED) && !this.account.information.has_sender_aliases)
             return false;
 
         // If there's only one account, show nothing. (From fields are hidden above.)
-        if (accounts.size < 1 || (accounts.size == 1 && Geary.traverse<Geary.AccountInformation>(
-            accounts.values).first().alternate_mailboxes == null))
+        if (accounts.size < 1 || (accounts.size == 1 && !Geary.traverse<Geary.AccountInformation>(
+            accounts.values).first().has_sender_aliases))
             return false;
 
         this.from_label.visible = true;
diff --git a/src/client/conversation-list/conversation-list-store.vala 
b/src/client/conversation-list/conversation-list-store.vala
index 7b82381a..be3e3998 100644
--- a/src/client/conversation-list/conversation-list-store.vala
+++ b/src/client/conversation-list/conversation-list-store.vala
@@ -280,7 +280,7 @@ public class ConversationListStore : Gtk.ListStore {
             conversation,
             preview,
             this.conversations.base_folder,
-            this.conversations.base_folder.account.information.get_all_mailboxes()
+            this.conversations.base_folder.account.information.sender_mailboxes
         );
 
         Gtk.TreePath? path = get_path(iter);
diff --git a/src/client/conversation-viewer/conversation-list-box.vala 
b/src/client/conversation-viewer/conversation-list-box.vala
index 70365506..9c4e767d 100644
--- a/src/client/conversation-viewer/conversation-list-box.vala
+++ b/src/client/conversation-viewer/conversation-list-box.vala
@@ -777,7 +777,7 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
         bool is_sent = false;
         if (email.from != null) {
             foreach (Geary.RFC822.MailboxAddress from in email.from) {
-                if (this.account_info.has_email_address(from)) {
+                if (this.account_info.has_sender_mailbox(from)) {
                     is_sent = true;
                     break;
                 }
diff --git a/src/engine/api/geary-account-information.vala b/src/engine/api/geary-account-information.vala
index aed9397f..793ad2dd 100644
--- a/src/engine/api/geary-account-information.vala
+++ b/src/engine/api/geary-account-information.vala
@@ -102,21 +102,28 @@ public class Geary.AccountInformation : BaseObject {
     public string nickname { get; set; default = ""; }
 
     /**
-     * The default email address for the account.
+     * The default sender mailbox address for the account.
+     *
+     * This is the first mailbox in the {@link sender_mailboxes} list.
      */
     public Geary.RFC822.MailboxAddress primary_mailbox {
-        get; set; default = new RFC822.MailboxAddress("", "");
+        owned get { return this.sender_mailboxes.get(0); }
     }
 
     /**
-     * A list of additional email addresses this account accepts.
-     *
-     * Use {@link add_alternate_mailbox} or {@link replace_alternate_mailboxes} rather than edit
-     * this collection directly.
+     * A read-only list of sender mailbox address for the account.
      *
-     * @see get_all_mailboxes
+     * The first address in the list is the default address, others
+     * are essentially aliases.
      */
-    public Gee.List<Geary.RFC822.MailboxAddress>? alternate_mailboxes { get; private set; default = null; }
+    public Gee.List<Geary.RFC822.MailboxAddress>? sender_mailboxes {
+        owned get { return this.mailboxes.read_only_view; }
+    }
+
+    /** Determines if the account has more than one sender mailbox. */
+    public bool has_sender_aliases {
+        get { return this.sender_mailboxes.size > 1; }
+    }
 
     public int prefetch_period_days {
         get; set; default = DEFAULT_PREFETCH_PERIOD_DAYS;
@@ -167,6 +174,11 @@ public class Geary.AccountInformation : BaseObject {
 
     public bool is_copy { get; set; default = false; }
 
+    private Gee.List<Geary.RFC822.MailboxAddress> mailboxes {
+        get; private set;
+        default = new Gee.LinkedList<Geary.RFC822.MailboxAddress>();
+    }
+
     private bool _save_sent_mail = true;
 
 
@@ -226,11 +238,8 @@ public class Geary.AccountInformation : BaseObject {
     public void copy_from(AccountInformation from) {
         this.id = from.id;
         this.nickname = from.nickname;
-        this.primary_mailbox = from.primary_mailbox;
-        if (from.alternate_mailboxes != null) {
-            foreach (RFC822.MailboxAddress alternate_mailbox in from.alternate_mailboxes)
-                add_alternate_mailbox(alternate_mailbox);
-        }
+        this.mailboxes.clear();
+        this.mailboxes.add_all(from.sender_mailboxes);
         this.prefetch_period_days = from.prefetch_period_days;
         this.save_sent_mail = from.save_sent_mail;
         this.ordinal = from.ordinal;
@@ -253,120 +262,61 @@ public class Geary.AccountInformation : BaseObject {
     }
 
     /**
-     * Return a read only, ordered list of the account's sender mailboxes.
-     */
-    public Gee.List<Geary.RFC822.MailboxAddress> get_sender_mailboxes() {
-        Gee.List<RFC822.MailboxAddress> all =
-            new Gee.LinkedList<RFC822.MailboxAddress>();
-
-        all.add(this.primary_mailbox);
-        if (alternate_mailboxes != null) {
-            all.add_all(alternate_mailboxes);
-        }
-
-        return all.read_only_view;
-    }
-
-    /**
-     * Appends a sender mailbox to the account.
+     * Determines if a mailbox is in the sender mailbox list.
+     *
+     * Returns true if the given address is equal to one of the
+     * addresses in {@link sender_mailboxes}, by case-insensitive
+     * matching the address parts.
+     *
+     * @see Geary.RFC822.MailboxAddress.equal_to
      */
-    public void append_sender_mailbox(Geary.RFC822.MailboxAddress mailbox) {
-        if (this.primary_mailbox == null) {
-            this.primary_mailbox = mailbox;
-        } else {
-            if (this.alternate_mailboxes == null) {
-                this.alternate_mailboxes =
-                    new Gee.LinkedList<Geary.RFC822.MailboxAddress>();
-            }
-            this.alternate_mailboxes.add(mailbox);
-        }
+    public bool has_sender_mailbox(Geary.RFC822.MailboxAddress email) {
+        return this.mailboxes.any_match((alt) => alt.equal_to(email));
     }
 
     /**
-     * Appends a sender mailbox to the account.
+     * Appends a mailbox to the list of sender mailboxes.
+     *
+     * Mailboxes with duplicate addresses will not be added.
+     *
+     * Returns true if the mailbox was appended.
      */
-    public void insert_sender_mailbox(int index,
-                                      Geary.RFC822.MailboxAddress mailbox) {
-        Geary.RFC822.MailboxAddress? alt_insertion = null;
-        int actual_index = index;
-        if (actual_index == 0) {
-            if (this.primary_mailbox == null) {
-                this.primary_mailbox = mailbox;
-            } else {
-                this.primary_mailbox = mailbox;
-                alt_insertion = this.primary_mailbox;
-                actual_index = 0;
-            }
-        } else {
-            alt_insertion = mailbox;
-            actual_index--;
-        }
-
-        if (alt_insertion != null) {
-            if (this.alternate_mailboxes == null) {
-                this.alternate_mailboxes =
-                    new Gee.LinkedList<Geary.RFC822.MailboxAddress>();
-            }
-            this.alternate_mailboxes.insert(actual_index, alt_insertion);
+    public bool append_sender(Geary.RFC822.MailboxAddress mailbox) {
+        bool add = !has_sender_mailbox(mailbox);
+        if (add) {
+            this.mailboxes.add(mailbox);
         }
+        return add;
     }
 
     /**
-     * Removes a sender mailbox for the account.
+     * Inserts a mailbox into the list of sender mailboxes.
+     *
+     * Mailboxes with duplicate addresses will not be added.
+     *
+     * Returns true if the mailbox was inserted.
      */
-    public void remove_sender_mailbox(Geary.RFC822.MailboxAddress mailbox) {
-        if (this.primary_mailbox == mailbox) {
-            this.primary_mailbox = (
-                this.alternate_mailboxes != null &&
-                !this.alternate_mailboxes.is_empty
-            ) ? this.alternate_mailboxes.remove_at(0) : null;
-        } else if (this.alternate_mailboxes != null) {
-            this.alternate_mailboxes.remove_at(
-                this.alternate_mailboxes.index_of(mailbox)
-            );
+    public bool insert_sender(int index, Geary.RFC822.MailboxAddress mailbox) {
+        bool add = !has_sender_mailbox(mailbox);
+        if (add) {
+            this.mailboxes.insert(index, mailbox);
         }
+        return add;
     }
 
     /**
-     * Return a list of the primary and all alternate email addresses.
-     */
-    public Gee.List<Geary.RFC822.MailboxAddress> get_all_mailboxes() {
-        Gee.ArrayList<RFC822.MailboxAddress> all = new Gee.ArrayList<RFC822.MailboxAddress>();
-
-        all.add(this.primary_mailbox);
-
-        if (alternate_mailboxes != null)
-            all.add_all(alternate_mailboxes);
-
-        return all;
-    }
-
-    /**
-     * Add an alternate email address to the account.
+     * Removes a mailbox from the list of sender mailboxes.
      *
-     * Duplicates will be ignored.
-     */
-    public void add_alternate_mailbox(Geary.RFC822.MailboxAddress mailbox) {
-        if (alternate_mailboxes == null)
-            alternate_mailboxes = new Gee.ArrayList<RFC822.MailboxAddress>();
-
-        if (!alternate_mailboxes.contains(mailbox))
-            alternate_mailboxes.add(mailbox);
-    }
-
-    /**
-     * Replaces the list of alternate email addresses with the supplied collection.
+     * The last mailbox cannot be removed.
      *
-     * Duplicates will be ignored.
+     * Returns true if the mailbox was removed.
      */
-    public void replace_alternate_mailboxes(Gee.Collection<Geary.RFC822.MailboxAddress>? mailboxes) {
-        alternate_mailboxes = null;
-
-        if (mailboxes == null || mailboxes.size == 0)
-            return;
-
-        foreach (RFC822.MailboxAddress mailbox in mailboxes)
-            add_alternate_mailbox(mailbox);
+    public bool remove_sender(Geary.RFC822.MailboxAddress mailbox) {
+        bool removed = false;
+        if (this.mailboxes.size > 1) {
+            removed = this.mailboxes.remove(mailbox);
+        }
+        return removed;
     }
 
     /**
@@ -445,23 +395,6 @@ public class Geary.AccountInformation : BaseObject {
         information_changed();
     }
 
-    /**
-     * Determines if this account contains a specific email address.
-     *
-     * Returns true if the address part of `email` is equal to (case
-     * insensitive) the address part of this account's primary mailbox
-     * or any of its secondary mailboxes.
-     */
-    public bool has_email_address(Geary.RFC822.MailboxAddress email) {
-        return (
-            this.primary_mailbox.equal_to(email) ||
-            (this.alternate_mailboxes != null &&
-             this.alternate_mailboxes.any_match((alt) => {
-                     return alt.equal_to(email);
-                 }))
-        );
-    }
-
     /**
      * Returns the best credentials to use for SMTP authentication.
      *
diff --git a/src/engine/rfc822/rfc822-mailbox-address.vala b/src/engine/rfc822/rfc822-mailbox-address.vala
index b3c5d411..869ca76a 100644
--- a/src/engine/rfc822/rfc822-mailbox-address.vala
+++ b/src/engine/rfc822/rfc822-mailbox-address.vala
@@ -453,14 +453,27 @@ public class Geary.RFC822.MailboxAddress :
     }
 
     /**
-     * Equality is defined as a case-insensitive comparison of the {@link address}.
+     * Determines if this mailbox is equal to another by address.
+     *
+     * Equality is defined as case-insensitive comparison of the
+     * {@link address} of both mailboxes.
      */
     public bool equal_to(MailboxAddress other) {
         return this == other || String.stri_equal(address, other.address);
     }
 
+    /**
+     * Determines if this mailbox is equal to another by address.
+     *
+     * This is suitable for determining equality for weaker cases such
+     * as user searches. Here equality is defined as case-insensitive
+     * comparison of the normalised, case-folded {@link address} and
+     * the same for the given string.
+     */
     public bool equal_normalized(string address) {
-        return this.address.normalize().casefold() == address.normalize().casefold();
+        return (
+            this.address.normalize().casefold() == address.normalize().casefold()
+        );
     }
 
     /**
diff --git a/src/engine/smtp/smtp-client-service.vala b/src/engine/smtp/smtp-client-service.vala
index 9cdfe62b..911790ee 100644
--- a/src/engine/smtp/smtp-client-service.vala
+++ b/src/engine/smtp/smtp-client-service.vala
@@ -336,7 +336,7 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
                 // that is accountured for this account.
                 if (rfc822.from != null) {
                     foreach (RFC822.MailboxAddress from in rfc822.from) {
-                        if (this.account.has_email_address(from)) {
+                        if (this.account.has_sender_mailbox(from)) {
                             reverse_path = from;
                             break;
                         }
diff --git a/test/engine/api/geary-account-information-test.vala 
b/test/engine/api/geary-account-information-test.vala
index 5215b8de..42e97879 100644
--- a/test/engine/api/geary-account-information-test.vala
+++ b/test/engine/api/geary-account-information-test.vala
@@ -10,10 +10,10 @@ class Geary.AccountInformationTest : TestCase {
 
     public AccountInformationTest() {
         base("Geary.AccountInformationTest");
-        add_test("has_email_address", has_email_address);
+        add_test("test_sender_mailboxes", test_sender_mailboxes);
     }
 
-    public void has_email_address() throws GLib.Error {
+    public void test_sender_mailboxes() throws GLib.Error {
         AccountInformation test = new AccountInformation(
             "test",
             ServiceProvider.OTHER,
@@ -21,24 +21,29 @@ class Geary.AccountInformationTest : TestCase {
             new MockServiceInformation()
         );
 
-        test.primary_mailbox = (new RFC822.MailboxAddress(null, "test1 example com"));
-        test.add_alternate_mailbox(new RFC822.MailboxAddress(null, "test2 example com"));
-        test.add_alternate_mailbox(new RFC822.MailboxAddress(null, "test3 example com"));
+        test.append_sender(new RFC822.MailboxAddress(null, "test1 example com"));
+        assert_false(test.has_sender_aliases);
 
+        test.append_sender(new RFC822.MailboxAddress(null, "test2 example com"));
+        test.append_sender(new RFC822.MailboxAddress(null, "test3 example com"));
+        assert_true(test.has_sender_aliases);
+
+        assert_true(test.primary_mailbox.equal_to(
+                        new RFC822.MailboxAddress(null, "test1 example com")));
         assert_true(
-            test.has_email_address(new RFC822.MailboxAddress(null, "test1 example com")),
+            test.has_sender_mailbox(new RFC822.MailboxAddress(null, "test1 example com")),
             "Primary address not found"
         );
         assert_true(
-            test.has_email_address(new RFC822.MailboxAddress(null, "test2 example com")),
+            test.has_sender_mailbox(new RFC822.MailboxAddress(null, "test2 example com")),
             "First alt address not found"
         );
         assert_true(
-            test.has_email_address(new RFC822.MailboxAddress(null, "test3 example com")),
+            test.has_sender_mailbox(new RFC822.MailboxAddress(null, "test3 example com")),
             "Second alt address not found"
         );
         assert_false(
-            test.has_email_address(new RFC822.MailboxAddress(null, "unknowne example com")),
+            test.has_sender_mailbox(new RFC822.MailboxAddress(null, "unknowne example com")),
             "Unknown address found"
         );
     }


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