[geary/wip/account-ux: 2/4] Convert from using AccountInformation.email to an id - client changes.



commit 793299b6a597b40cbf4ad121698687642efce66a
Author: Michael James Gratton <mike vee net>
Date:   Thu Jul 14 02:22:09 2016 +1000

    Convert from using AccountInformation.email to an id - client changes.
    
    * src/engine/api/geary-account-information.vala (AccountInformation):
      Add a display_name property, use that in the client wherever a unique
      name for an account has to be shown to the user. Update all other cases
      to use `id` or `primary_mailbox`.
    
    * src/client/accounts/add-edit-page.vala: Add id property, use that when
      determining if an account is new or is being edited.
    
    * src/client/accounts/account-dialog-account-list-pane.vala
      (AccountDialogAccountListPane): Add the account's id to the list model,
      use that instead of the email address as the primary key.

 .../accounts/account-dialog-account-list-pane.vala |   84 +++++----
 .../account-dialog-edit-alternate-emails-pane.vala |   22 +--
 .../account-dialog-remove-confirm-pane.vala        |    8 +-
 src/client/accounts/add-edit-page.vala             |  195 +++++++++++---------
 src/client/application/geary-controller.vala       |   14 +-
 src/client/application/secret-mediator.vala        |   10 +-
 src/client/composer/composer-widget.vala           |    6 +-
 .../conversation-viewer/conversation-viewer.vala   |    3 +-
 src/client/dialogs/certificate-warning-dialog.vala |    2 +-
 src/client/notification/libmessagingmenu.vala      |    6 +-
 src/client/notification/libnotify.vala             |   10 +-
 src/engine/api/geary-account-information.vala      |   31 +++-
 12 files changed, 212 insertions(+), 179 deletions(-)
---
diff --git a/src/client/accounts/account-dialog-account-list-pane.vala 
b/src/client/accounts/account-dialog-account-list-pane.vala
index e82c379..e96b7ad 100644
--- a/src/client/accounts/account-dialog-account-list-pane.vala
+++ b/src/client/accounts/account-dialog-account-list-pane.vala
@@ -7,21 +7,22 @@
 // List of accounts.  Used with AccountDialog.
 public class AccountDialogAccountListPane : AccountDialogPane {
     public enum Column {
-        ACCOUNT_NICKNAME = 0,
+        ACCOUNT_ID = 0,
+        ACCOUNT_NAME,
         ACCOUNT_ADDRESS;
     }
-    
+
     private Gtk.TreeView list_view;
-    private Gtk.ListStore list_model = new Gtk.ListStore(2, typeof (string), typeof (string));
+    private Gtk.ListStore list_model = new Gtk.ListStore(3, typeof(string), typeof(string), typeof(string));
     private Gtk.Action edit_action;
     private Gtk.Action delete_action;
     
     public signal void add_account();
-    
-    public signal void edit_account(string email_address);
-    
-    public signal void delete_account(string email_address);
-    
+
+    public signal void edit_account(string id);
+
+    public signal void delete_account(string id);
+
     public AccountDialogAccountListPane(Gtk.Stack stack) {
         base(stack);
         Gtk.Builder builder = GearyApplication.instance.create_builder("account_list.glade");
@@ -33,14 +34,14 @@ public class AccountDialogAccountListPane : AccountDialogPane {
         // Set up list.
         list_view = (Gtk.TreeView) builder.get_object("account_list");
         list_view.set_model(list_model);
-        list_view.insert_column_with_attributes(-1, "Nickname", new Gtk.CellRendererText(), "text",
-            Column.ACCOUNT_NICKNAME);
-        list_view.get_column(Column.ACCOUNT_NICKNAME).set_expand(true);
-        list_view.insert_column_with_attributes(-1, "Address", new Gtk.CellRendererText(), "text",
+        list_view.insert_column_with_attributes(-1, "Name", new Gtk.CellRendererText(), "text",
+            Column.ACCOUNT_NAME);
+        list_view.get_column(0).set_expand(true);
+        list_view.insert_column_with_attributes(-1, "Email", new Gtk.CellRendererText(), "text",
             Column.ACCOUNT_ADDRESS);
-        list_view.get_column(Column.ACCOUNT_ADDRESS).set_expand(true);
+        list_view.get_column(1).set_expand(true);
         list_view.reorderable = true;
-        
+
         // Get all accounts and add them to a list.
         Gee.LinkedList<Geary.AccountInformation> account_list =
             new Gee.LinkedList<Geary.AccountInformation>();
@@ -102,8 +103,8 @@ public class AccountDialogAccountListPane : AccountDialogPane {
         notify_edit_account();
         return true;
     }
-    
-    // Returns the email address of the selected account.  Returns null if no account is selected.
+
+    // Returns the id of the selected account.  Returns null if no account is selected.
     private string? get_selected_account() {
         if (list_view.get_selection().count_selected_rows() != 1)
             return null;
@@ -115,7 +116,7 @@ public class AccountDialogAccountListPane : AccountDialogPane {
             return null;
         
         string? account = null;
-        list_model.get(iter, Column.ACCOUNT_ADDRESS, out account);
+        list_model.get(iter, Column.ACCOUNT_ID, out account);
         return account;
     }
     
@@ -126,18 +127,18 @@ public class AccountDialogAccountListPane : AccountDialogPane {
     }
     
     private void on_account_added(Geary.AccountInformation account) {
-        Gtk.TreeIter? iter = list_contains(account.email);
+        Gtk.TreeIter? iter = list_contains(account.id);
         if (iter != null)
             return; // Already listed.
-        
-        add_account_to_list(account.nickname, account.email);
+
+        add_account_to_list(account);
         account.notify.connect(on_account_changed);
         update_buttons();
         update_ordinals();
     }
     
     private void on_account_removed(Geary.AccountInformation account) {
-        remove_account_from_list(account.email);
+        remove_account_from_list(account.id);
         account.notify.disconnect(on_account_changed);
         update_buttons();
         update_ordinals();
@@ -145,16 +146,17 @@ public class AccountDialogAccountListPane : AccountDialogPane {
     
     // Adds an account to the list.
     // Note: does NOT check if the account is already listed.
-    private void add_account_to_list(string nickname, string address) {
+    private void add_account_to_list(Geary.AccountInformation account) {
         Gtk.TreeIter iter;
         list_model.append(out iter);
-        list_model.set(iter, Column.ACCOUNT_NICKNAME, nickname);
-        list_model.set(iter, Column.ACCOUNT_ADDRESS, address);
+        list_model.set(iter, Column.ACCOUNT_ID, account.id);
+        list_model.set(iter, Column.ACCOUNT_NAME, account.display_name);
+        list_model.set(iter, Column.ACCOUNT_ADDRESS, account.primary_mailbox.address);
     }
     
     // Removes an account on the list.
-    private void remove_account_from_list(string address) {
-        Gtk.TreeIter? iter = list_contains(address);
+    private void remove_account_from_list(string id) {
+        Gtk.TreeIter? iter = list_contains(id);
         if (iter == null)
             return;
         
@@ -164,25 +166,25 @@ public class AccountDialogAccountListPane : AccountDialogPane {
     private void on_account_changed(Object object, ParamSpec p) {
         Geary.AccountInformation account = (Geary.AccountInformation) object;
         
-        Gtk.TreeIter? iter = list_contains(account.email);
+        Gtk.TreeIter? iter = list_contains(account.id);
         if (iter == null)
             return;
-        
-        // Since nickname is the only column that can change, just set it.
-        list_model.set_value(iter, Column.ACCOUNT_NICKNAME, account.nickname);
+
+        list_model.set_value(iter, Column.ACCOUNT_NAME, account.display_name);
+        list_model.set_value(iter, Column.ACCOUNT_ADDRESS, account.primary_mailbox.address);
     }
-    
-    // Returns TreeIter of the address in the account list, else null.
-    private Gtk.TreeIter? list_contains(string address) {
+
+    // Returns TreeIter of the id in the account list, else null.
+    private Gtk.TreeIter? list_contains(string id) {
         Gtk.TreeIter iter;
         
         if (!list_model.get_iter_first(out iter))
             return null;
         
         do {
-            string list_address = "";
-            list_model.get(iter, Column.ACCOUNT_ADDRESS, out list_address);
-            if (list_address == address)
+            string list_id = "";
+            list_model.get(iter, Column.ACCOUNT_ID, out list_id);
+            if (list_id == id)
                 return iter;
         } while (list_model.iter_next(ref iter));
         
@@ -206,11 +208,11 @@ public class AccountDialogAccountListPane : AccountDialogPane {
         
         int i = 0;
         do {
-            string? list_address = null;
-            list_model.get(iter, Column.ACCOUNT_ADDRESS, out list_address);
-            if (list_address != null) {
-                Geary.AccountInformation account = all_accounts.get(list_address);
-                
+            string? list_id = null;
+            list_model.get(iter, Column.ACCOUNT_ID, out list_id);
+            if (list_id != null) {
+                Geary.AccountInformation account = all_accounts.get(list_id);
+
                 // To prevent unnecessary work, only set ordinal if there's a change.
                 if (i != account.ordinal) {
                     account.ordinal = i;
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 4a9a185..c558650 100644
--- a/src/client/accounts/account-dialog-edit-alternate-emails-pane.vala
+++ b/src/client/accounts/account-dialog-edit-alternate-emails-pane.vala
@@ -17,9 +17,7 @@ public class AccountDialogEditAlternateEmailsPane : AccountDialogPane {
             GtkUtil.set_label_xalign(this, 0.0f);
         }
     }
-    
-    public string? email { get; private set; default = null; }
-    
+
     public bool changed { get; private set; default = false; }
     
     private Gtk.Label title_label;
@@ -114,18 +112,16 @@ public class AccountDialogEditAlternateEmailsPane : AccountDialogPane {
     
     public void set_account(Geary.AccountInformation account_info) {
         this.account_info = account_info;
-        
-        email = account_info.email;
-        primary_mailbox = account_info.get_primary_mailbox_address();
-        mailboxes.clear();
-        changed = false;
-        
+        this.primary_mailbox = account_info.primary_mailbox;
+        this.mailboxes.clear();
+        this.changed = false;
+
         // reset/clear widgets
-        title_label.label = _("Additional addresses for %s").printf(account_info.email);
-        email_entry.text = "";
-        
+        this.title_label.label = _("Additional addresses for %s").printf(this.account_info.display_name);
+        this.email_entry.text = "";
+
         // clear listbox
-        foreach (Gtk.Widget widget in address_listbox.get_children())
+        foreach (Gtk.Widget widget in this.address_listbox.get_children())
             address_listbox.remove(widget);
         
         // Add all email addresses; add_email_address() silently drops the primary address
diff --git a/src/client/accounts/account-dialog-remove-confirm-pane.vala 
b/src/client/accounts/account-dialog-remove-confirm-pane.vala
index 4e7e33c..808ef77 100644
--- a/src/client/accounts/account-dialog-remove-confirm-pane.vala
+++ b/src/client/accounts/account-dialog-remove-confirm-pane.vala
@@ -27,11 +27,11 @@ public class AccountDialogRemoveConfirmPane : AccountDialogPane {
         actions.get_action("cancel_action").activate.connect(() => { cancel(); });
         actions.get_action("remove_action").activate.connect(() => { ok(account); });
     }
-    
+
     public void set_account(Geary.AccountInformation a) {
-        account = a;
-        account_nickname_label.label = account.nickname;
-        email_address_label.label = account.email;
+        this.account = a;
+        account_nickname_label.label = a.nickname;
+        email_address_label.label = a.primary_mailbox.address;
     }
 }
 
diff --git a/src/client/accounts/add-edit-page.vala b/src/client/accounts/add-edit-page.vala
index 49f6b2b..33d88aa 100644
--- a/src/client/accounts/add-edit-page.vala
+++ b/src/client/accounts/add-edit-page.vala
@@ -14,7 +14,9 @@ public class AddEditPage : Gtk.Box {
         ADD,
         EDIT
     }
-    
+
+    private string? id = null;
+
     public string real_name {
         get { return entry_real_name.text; }
         set { entry_real_name.text = value; }
@@ -357,9 +359,11 @@ public class AddEditPage : Gtk.Box {
     
     // Sets the account information to display on this page.
     public void set_account_information(Geary.AccountInformation info, Geary.Engine.ValidationResult result) 
{
-        set_all_info(info.real_name,
+        set_all_info(
+            info.id,
+            info.real_name,
             info.nickname,
-            info.email,
+            info.primary_mailbox.address,
             info.imap_credentials.user,
             info.imap_credentials.pass,
             info.imap_remember_password && info.smtp_remember_password,
@@ -387,6 +391,7 @@ public class AddEditPage : Gtk.Box {
     
     // Can use this instead of set_account_information(), both do the same thing.
     public void set_all_info(
+        string? initial_id = null,
         string? initial_real_name = null,
         string? initial_nickname = null,
         string? initial_email = null,
@@ -413,60 +418,61 @@ public class AddEditPage : Gtk.Box {
         bool initial_use_email_signature = false,
         string? initial_email_signature = null,
         Geary.Engine.ValidationResult result = Geary.Engine.ValidationResult.OK) {
-        
+
         // Set defaults
-        real_name = initial_real_name ?? "";
-        nickname = initial_nickname ?? "";
-        email_address = initial_email ?? "";
-        password = initial_imap_password != null ? initial_imap_password : "";
-        remember_password = initial_remember_password;
-        save_sent_mail = initial_save_sent_mail;
-        check_save_sent_mail.sensitive = allow_save_sent_mail;
-        set_service_provider((Geary.ServiceProvider) initial_service_provider);
-        combo_imap_encryption.active = Encryption.NONE; // Must be default; set to real value below.
-        combo_smtp_encryption.active = Encryption.NONE;
-        use_email_signature = initial_use_email_signature;
-        email_signature = initial_email_signature;
-        signature_stack.set_visible_child_name("edit_window");
-        
+        this.id = initial_id;
+        this.real_name = initial_real_name ?? "";
+        this.nickname = initial_nickname ?? "";
+        this.email_address = initial_email ?? "";
+        this.password = initial_imap_password != null ? initial_imap_password : "";
+        this.remember_password = initial_remember_password;
+        this.save_sent_mail = initial_save_sent_mail;
+        this.check_save_sent_mail.sensitive = allow_save_sent_mail;
+        this.set_service_provider((Geary.ServiceProvider) initial_service_provider);
+        this.combo_imap_encryption.active = Encryption.NONE; // Must be default; set to real value below.
+        this.combo_smtp_encryption.active = Encryption.NONE;
+        this.use_email_signature = initial_use_email_signature;
+        this.email_signature = initial_email_signature;
+        this.signature_stack.set_visible_child_name("edit_window");
+
         // Set defaults for IMAP info
-        imap_host = initial_default_imap_host ?? "";
-        imap_port = initial_default_imap_port;
-        imap_username = initial_imap_username ?? "";
-        imap_password = initial_imap_password ?? "";
-        imap_ssl = initial_default_imap_ssl;
-        imap_starttls = initial_default_imap_starttls;
-        
+        this.imap_host = initial_default_imap_host ?? "";
+        this.imap_port = initial_default_imap_port;
+        this.imap_username = initial_imap_username ?? "";
+        this.imap_password = initial_imap_password ?? "";
+        this.imap_ssl = initial_default_imap_ssl;
+        this.imap_starttls = initial_default_imap_starttls;
+
         // Set defaults for SMTP info
-        smtp_host = initial_default_smtp_host ?? "";
-        smtp_port = initial_default_smtp_port;
-        smtp_username = initial_smtp_username ?? "";
-        smtp_password = initial_smtp_password ?? "";
-        smtp_ssl = initial_default_smtp_ssl;
-        smtp_starttls = initial_default_smtp_starttls;
-        smtp_use_imap_credentials = initial_default_smtp_use_imap_credentials;
-        smtp_noauth = initial_default_smtp_noauth;
-        
-        save_drafts = initial_save_drafts;
-        
+        this.smtp_host = initial_default_smtp_host ?? "";
+        this.smtp_port = initial_default_smtp_port;
+        this.smtp_username = initial_smtp_username ?? "";
+        this.smtp_password = initial_smtp_password ?? "";
+        this.smtp_ssl = initial_default_smtp_ssl;
+        this.smtp_starttls = initial_default_smtp_starttls;
+        this.smtp_use_imap_credentials = initial_default_smtp_use_imap_credentials;
+        this.smtp_noauth = initial_default_smtp_noauth;
+
+        this.save_drafts = initial_save_drafts;
+
         set_validation_result(result);
-        
+
         set_storage_length(prefetch_period_days);
     }
-    
+
     public void set_validation_result(Geary.Engine.ValidationResult result) {
         last_validation_result = result;
     }
-    
+
     // Resets all fields to their defaults.
     public void reset_all() {
         // Take advantage of set_all_info()'s defaults.
-        set_all_info(get_default_real_name());
-        
+        set_all_info(null, get_default_real_name());
+
         edited_imap_port = false;
         edited_smtp_port = false;
     }
-    
+
     /** Puts this page into one of three different modes:
      *  WELCOME: The first screen when Geary is started.
      *      ADD: Add account screen is like the Welcome screen, but without the welcome message.
@@ -636,62 +642,71 @@ public class AddEditPage : Gtk.Box {
         
         return true;
     }
-    
+
     public Geary.AccountInformation? get_account_information() {
-        Geary.AccountInformation account_information;
         fix_credentials_for_supported_provider();
-        
-        Geary.Credentials imap_credentials = new Geary.Credentials(imap_username.strip(), 
imap_password.strip());
+
+        Geary.Credentials imap_credentials = new Geary.Credentials(
+            imap_username.strip(), imap_password.strip());
         Geary.Credentials smtp_credentials = new Geary.Credentials(
             (smtp_use_imap_credentials ? imap_username.strip() : smtp_username.strip()),
             (smtp_use_imap_credentials ? imap_password.strip() : smtp_password.strip()));
-        
-        try {
-            Geary.AccountInformation original_account = 
Geary.Engine.instance.get_accounts().get(email_address);
-            if (original_account == null) {
-                // New account.
-                account_information = Geary.Engine.instance.create_orphan_account(email_address);
-            } else {
-                // Existing account: create a copy so we don't mess up the original.
-                account_information = new Geary.AccountInformation.temp_copy(original_account);
+
+        Geary.AccountInformation? info = null;
+        if (this.id == null) {
+            // New account
+            try {
+                info = Geary.Engine.instance.create_orphan_account(this.email_address);
+            } catch (Error err) {
+                debug("Unable to create account %s for %s: %s",
+                      this.id, this.email_address, err.message);
+            }
+        } else {
+            // Existing account: create a copy so we don't mess up the original.
+            try {
+                info = new Geary.AccountInformation.temp_copy(
+                    Geary.Engine.instance.get_account(this.id)
+                );
+            } catch (Error err) {
+                debug("Unable get existing account %s: %s", this.id, err.message);
             }
-        } catch (Error err) {
-            debug("Unable to open account information for %s: %s", email_address, err.message);
-            
-            return null;
         }
-        
-        account_information.real_name = real_name.strip();
-        account_information.nickname = nickname.strip();
-        account_information.imap_credentials = imap_credentials;
-        account_information.smtp_credentials = smtp_credentials;
-        account_information.imap_remember_password = remember_password;
-        account_information.smtp_remember_password = remember_password;
-        account_information.service_provider = get_service_provider();
-        account_information.save_sent_mail = save_sent_mail;
-        account_information.default_imap_server_host = imap_host;
-        account_information.default_imap_server_port = imap_port;
-        account_information.default_imap_server_ssl = imap_ssl;
-        account_information.default_imap_server_starttls = imap_starttls;
-        account_information.default_smtp_server_host = smtp_host.strip();
-        account_information.default_smtp_server_port = smtp_port;
-        account_information.default_smtp_server_ssl = smtp_ssl;
-        account_information.default_smtp_server_starttls = smtp_starttls;
-        account_information.default_smtp_use_imap_credentials = smtp_use_imap_credentials;
-        account_information.default_smtp_server_noauth = smtp_noauth;
-        account_information.prefetch_period_days = get_storage_length();
-        account_information.save_drafts = save_drafts;
-        account_information.use_email_signature = use_email_signature;
-        account_information.email_signature = email_signature;
-        
-        if (smtp_noauth)
-            account_information.smtp_credentials = null;
-        
-        on_changed();
-        
-        return account_information;
+
+        if (info != null) {
+            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;
+            info.imap_remember_password = this.remember_password;
+            info.smtp_remember_password = this.remember_password;
+            info.service_provider = this.get_service_provider();
+            info.save_sent_mail = this.save_sent_mail;
+            info.default_imap_server_host = this.imap_host;
+            info.default_imap_server_port = this.imap_port;
+            info.default_imap_server_ssl = this.imap_ssl;
+            info.default_imap_server_starttls = this.imap_starttls;
+            info.default_smtp_server_host = this.smtp_host.strip();
+            info.default_smtp_server_port = this.smtp_port;
+            info.default_smtp_server_ssl = this.smtp_ssl;
+            info.default_smtp_server_starttls = this.smtp_starttls;
+            info.default_smtp_use_imap_credentials = this.smtp_use_imap_credentials;
+            info.default_smtp_server_noauth = this.smtp_noauth;
+            info.prefetch_period_days = get_storage_length();
+            info.save_drafts = this.save_drafts;
+            info.use_email_signature = this.use_email_signature;
+            info.email_signature = this.email_signature;
+
+            if (smtp_noauth)
+                info.smtp_credentials = null;
+
+            on_changed();
+        }
+
+        return info;
     }
-    
+
     // Assembles credentials for supported providers.
     private void fix_credentials_for_supported_provider() {
         if (get_service_provider() != Geary.ServiceProvider.OTHER) {
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index 4403b09..3e6d772 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -742,7 +742,7 @@ public class GearyController : Geary.BaseObject {
                 
                 // close the account; can't go any further w/o offline mode
                 try {
-                    if (Geary.Engine.instance.get_accounts().has_key(account_information.email)) {
+                    if (Geary.Engine.instance.get_accounts().has_key(account_information.id)) {
                         Geary.Account account = 
Geary.Engine.instance.get_account_instance(account_information);
                         close_account(account);
                     }
@@ -927,7 +927,7 @@ public class GearyController : Geary.BaseObject {
         Geary.AccountInformation account_information) {
         if (account_information.is_copy()) {
             try {
-                 return Geary.Engine.instance.get_accounts().get(account_information.email);
+                 return Geary.Engine.instance.get_accounts().get(account_information.id);
             } catch (Error e) {
                 error("Account information is out of sync: %s", e.message);
             }
@@ -1136,7 +1136,7 @@ public class GearyController : Geary.BaseObject {
         // could be done to leave the Account in an unopened state, but we don't currently
         // have provisions for that.
         AlertDialog dialog = new QuestionDialog(main_window,
-            _("Unable to open the database for %s").printf(account.information.email),
+            _("Unable to open the database for %s").printf(account.information.id),
             _("There was an error opening the local mail database for this account. This is possibly due to 
corruption of the database file in this directory:\n\n%s\n\nGeary can rebuild the database and re-synchronize 
with the server or exit.\n\nRebuilding the database will destroy all local email and its attachments. <b>The 
mail on the your server will not be affected.</b>")
                 .printf(account.information.data_dir.get_path()),
             _("_Rebuild"), _("E_xit"));
@@ -1148,7 +1148,7 @@ public class GearyController : Geary.BaseObject {
                     yield account.rebuild_async();
                 } catch (Error err) {
                     dialog = new ErrorDialog(main_window,
-                        _("Unable to rebuild database for \"%s\"").printf(account.information.email),
+                        _("Unable to rebuild database for \"%s\"").printf(account.information.id),
                         _("Error during rebuild:\n\n%s").printf(err.message));
                     dialog.run();
                     
@@ -1171,7 +1171,7 @@ public class GearyController : Geary.BaseObject {
         // some other problem opening the account ... as with other flow path, can't run
         // Geary today with an account in unopened state, so have to exit
         ErrorDialog dialog = new ErrorDialog(main_window,
-            _("Unable to open local mailbox for %s").printf(account.information.email),
+            _("Unable to open local mailbox for %s").printf(account.information.id),
             _("There was an error opening the local mail database for this account. This is possibly due to 
a file permissions problem.\n\nPlease check that you have read/write permissions for all files in this 
directory:\n\n%s")
                 .printf(account.information.data_dir.get_path()));
         dialog.run();
@@ -1181,7 +1181,7 @@ public class GearyController : Geary.BaseObject {
     
     private async void account_database_version_async(Geary.Account account) {
         ErrorDialog dialog = new ErrorDialog(main_window,
-            _("Unable to open local mailbox for %s").printf(account.information.email),
+            _("Unable to open local mailbox for %s").printf(account.information.id),
             _("The version number of the local mail database is formatted for a newer version of Geary. 
Unfortunately, the database cannot be \"rolled back\" to work with this version of Geary.\n\nPlease install 
the latest version of Geary and try again."));
         dialog.run();
         
@@ -1192,7 +1192,7 @@ public class GearyController : Geary.BaseObject {
         // some other problem opening the account ... as with other flow path, can't run
         // Geary today with an account in unopened state, so have to exit
         ErrorDialog dialog = new ErrorDialog(main_window,
-            _("Unable to open local mailbox for %s").printf(account.information.email),
+            _("Unable to open local mailbox for %s").printf(account.information.id),
             _("There was an error opening the local account. This is probably due to connectivity 
issues.\n\nPlease check your network connection and restart Geary."));
         dialog.run();
         
diff --git a/src/client/application/secret-mediator.vala b/src/client/application/secret-mediator.vala
index 1d777cd..b246e6f 100644
--- a/src/client/application/secret-mediator.vala
+++ b/src/client/application/secret-mediator.vala
@@ -53,7 +53,7 @@ public class SecretMediator : Geary.CredentialsMediator, Object {
     public virtual async string? get_password_async(
         Geary.Service service, Geary.AccountInformation account_information, Cancellable? cancellable = null)
         throws Error {
-        string key_name = get_key_name(service, account_information.email);
+        string key_name = get_key_name(service, account_information.id);
         string? password = yield Secret.password_lookup(Secret.SCHEMA_COMPAT_NETWORK, cancellable,
             "user", key_name);
         
@@ -73,15 +73,15 @@ public class SecretMediator : Geary.CredentialsMediator, Object {
         }
         
         if (password == null)
-            debug("Unable to fetch password in libsecret keyring for %s", account_information.email);
-        
+            debug("Unable to fetch password in libsecret keyring for %s", account_information.id);
+
         return password;
     }
     
     public virtual async void set_password_async(
         Geary.Service service, Geary.AccountInformation account_information,
         Cancellable? cancellable = null) throws Error {
-        string key_name = get_key_name(service, account_information.email);
+        string key_name = get_key_name(service, account_information.id);
         Geary.Credentials credentials = get_credentials(service, account_information);
         
         bool result = yield Secret.password_store(Secret.SCHEMA_COMPAT_NETWORK,
@@ -97,7 +97,7 @@ public class SecretMediator : Geary.CredentialsMediator, Object {
         Geary.Credentials credentials = get_credentials(service, account_information);
         // new-style
         yield Secret.password_clear(Secret.SCHEMA_COMPAT_NETWORK, cancellable, "user",
-            get_key_name(service, account_information.email));
+            get_key_name(service, account_information.id));
         // <= 0.6
         yield Secret.password_clear(Secret.SCHEMA_COMPAT_NETWORK, cancellable, "user",
             get_key_name(service, credentials.user));
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 159c21a..2472a6e 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -458,7 +458,7 @@ public class ComposerWidget : Gtk.EventBox {
         
         add_extra_accelerators();
 
-        from = account.information.get_primary_from();
+        from = new Geary.RFC822.MailboxAddresses.single(account.information.primary_mailbox);
 
         if (referred != null) {
             if (compose_type != ComposeType.NEW_MESSAGE) {
@@ -2335,7 +2335,7 @@ public class ComposerWidget : Gtk.EventBox {
     
     private bool add_account_emails_to_from_list(Geary.Account account, bool set_active = false) {
         Geary.RFC822.MailboxAddresses primary_address = new Geary.RFC822.MailboxAddresses.single(
-            account.information.get_primary_mailbox_address());
+            account.information.primary_mailbox);
         from_multiple.append_text(primary_address.to_rfc822_string());
         from_list.add(new FromAddressMap(account, primary_address));
         if (!set_active && from.equal_to(primary_address)) {
@@ -2351,7 +2351,7 @@ public class ComposerWidget : Gtk.EventBox {
                 // 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_rfc822_string(), 
account.information.email);
+                string display = _("%1$s via %2$s").printf(addresses.to_rfc822_string(), 
account.information.display_name);
                 from_multiple.append_text(display);
                 from_list.add(new FromAddressMap(account, addresses));
                 
diff --git a/src/client/conversation-viewer/conversation-viewer.vala 
b/src/client/conversation-viewer/conversation-viewer.vala
index 225ed93..e819ed3 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -677,7 +677,8 @@ public class ConversationViewer : Gtk.Box {
             if (email.is_unread() == Geary.Trillian.FALSE) {
                 div_message.get_class_list().add("hide");
             }
-            if (email.from != null && email.from.contains_normalized(current_account_information.email)) {
+            // Update to use all addresses on the account. Bug 768779
+            if (email.from != null && 
email.from.contains_normalized(current_account_information.primary_mailbox.address)) {
                 div_message.get_class_list().add("sent");
             }
         } catch (Error setup_error) {
diff --git a/src/client/dialogs/certificate-warning-dialog.vala 
b/src/client/dialogs/certificate-warning-dialog.vala
index 5d03430..f84641f 100644
--- a/src/client/dialogs/certificate-warning-dialog.vala
+++ b/src/client/dialogs/certificate-warning-dialog.vala
@@ -30,7 +30,7 @@ public class CertificateWarningDialog {
         Gtk.Label dont_trust_label = (Gtk.Label) builder.get_object("dont_trust_label");
         Gtk.Label contact_label = (Gtk.Label) builder.get_object("contact_label");
         
-        title_label.label = _("Untrusted Connection: %s").printf(account_information.email);
+        title_label.label = _("Untrusted Connection: %s").printf(account_information.display_name);
         
         Geary.Endpoint endpoint = account_information.get_endpoint_for_service(service);
         top_label.label = _("The identity of the %s mail server at %s:%u could not be verified.").printf(
diff --git a/src/client/notification/libmessagingmenu.vala b/src/client/notification/libmessagingmenu.vala
index a9b80dd..f1d4c0a 100644
--- a/src/client/notification/libmessagingmenu.vala
+++ b/src/client/notification/libmessagingmenu.vala
@@ -37,11 +37,11 @@ public class Libmessagingmenu : NewMessagesIndicator {
             monitor.new_messages_retired.disconnect(on_new_messages_changed);
         }
     }
-    
+
     private string get_source_id(Geary.Folder folder) {
-        return "new-messages-id-%s-%s".printf(folder.account.information.email, folder.path.to_string());
+        return "new-messages-id-%s-%s".printf(folder.account.information.id, folder.path.to_string());
     }
-    
+
     private void on_activate_source(string source_id) {
         foreach (Geary.Folder folder in monitor.get_folders()) {
             if (source_id == get_source_id(folder)) {
diff --git a/src/client/notification/libnotify.vala b/src/client/notification/libnotify.vala
index bb25268..17475ff 100644
--- a/src/client/notification/libnotify.vala
+++ b/src/client/notification/libnotify.vala
@@ -75,10 +75,10 @@ public class Libnotify : Geary.BaseObject {
             body = ngettext("%s, %d new message total", "%s, %d new messages total", total).printf(
                 body, total);
         }
-        
-        issue_current_notification(folder.account.information.email, body, null);
+
+        issue_current_notification(folder.account.information.display_name, body, null);
     }
-    
+
     private async void notify_one_message_async(Geary.Folder folder, Geary.Email email,
         GLib.Cancellable? cancellable) throws GLib.Error {
         assert(email.fields.fulfills(REQUIRED_FIELDS));
@@ -105,9 +105,9 @@ public class Libnotify : Geary.BaseObject {
             body = EmailUtil.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(
-                EmailUtil.strip_subject_prefixes(email), count - 1, folder.account.information.email);
+                EmailUtil.strip_subject_prefixes(email), count - 1, folder.account.information.display_name);
         }
-        
+
         // get the avatar
         Gdk.Pixbuf? avatar = null;
         InputStream? ins = null;
diff --git a/src/engine/api/geary-account-information.vala b/src/engine/api/geary-account-information.vala
index f6fab31..c0dbef4 100644
--- a/src/engine/api/geary-account-information.vala
+++ b/src/engine/api/geary-account-information.vala
@@ -69,22 +69,41 @@ public class Geary.AccountInformation : BaseObject {
     //
 
     /**
-     * Unique identifier for this account.
+     * A unique, immutable, machine-readable identifier for this account.
      *
      * This string's value should be treated as an opaque, private
      * implementation detail and not parsed at all. For older accounts
      * it will be an email address, for newer accounts it will be
-     * something else.
+     * something else. Once created, this string will never change.
      */
     public string id { get; private set; }
 
     /**
+     * A unique human-readable display name for this account.
+     *
+     * Use this to display a string to the user that can uniquely
+     * identify this account. Note this value is mutable - it may
+     * change as a result of user action, so do not rely on it staying
+     * the same.
+     */
+    public string display_name {
+        get {
+            return (!String.is_empty_or_whitespace(this.nickname))
+                ? this.nickname
+                : this.primary_mailbox.address;
+        }
+    }
+
+    /**
      * User's name for the {@link get_primary_mailbox_address}.
      */
     public string real_name { get; set; }
     
     /**
-     * User label for primary account (not transmitted on wire or used in correspondence).
+     * User-provided label for the account.
+     *
+     * This is not to be used in the UI (use `display_name` instead)
+     * and not transmitted on the wire or used in correspondence.
      */
     public string nickname { get; set; }
 
@@ -949,11 +968,11 @@ public class Geary.AccountInformation : BaseObject {
         int diff = a.ordinal - b.ordinal;
         if (diff != 0)
             return diff;
-        
+
         // Stabilize on nickname, which should always be unique.
-        return a.nickname.collate(b.nickname);
+        return a.display_name.collate(b.display_name);
     }
-    
+
     // Returns true if this is a copy.
     public bool is_copy() {
         return file == null;



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