[geary/wip/714104-refine-account-dialog: 19/69] Add initial replacement accounts editor dialog.



commit 05be1c1014d5edb6669e148299448fbc41eb6915
Author: Michael James Gratton <mike vee net>
Date:   Sun Jun 3 00:56:02 2018 +0300

    Add initial replacement accounts editor dialog.

 po/POTFILES.in                                |   4 +
 src/client/accounts/account-manager.vala      |  22 +++
 src/client/accounts/accounts-editor.vala      | 211 ++++++++++++++++++++++++++
 src/client/application/geary-application.vala |  10 +-
 src/client/meson.build                        |   1 +
 src/engine/api/geary-account-information.vala |   7 +
 ui/accounts_editor.ui                         | 119 +++++++++++++++
 ui/geary.css                                  |  17 +++
 ui/org.gnome.Geary.gresource.xml              |   1 +
 9 files changed, 388 insertions(+), 4 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 367b87ea..4cd98244 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -14,9 +14,12 @@ src/client/accounts/account-dialog-remove-confirm-pane.vala
 src/client/accounts/account-dialog-remove-fail-pane.vala
 src/client/accounts/account-dialog-spinner-pane.vala
 src/client/accounts/account-dialog.vala
+src/client/accounts/account-dialogs.vala
 src/client/accounts/account-manager.vala
 src/client/accounts/account-spinner-page.vala
+src/client/accounts/accounts-editor.vala
 src/client/accounts/add-edit-page.vala
+src/client/accounts/editor.vala
 src/client/accounts/goa-service-information.vala
 src/client/accounts/local-service-information.vala
 src/client/accounts/login-dialog.vala
@@ -404,6 +407,7 @@ src/mailer/main.vala
 ui/account_cannot_remove.glade
 ui/account_list.glade
 ui/account_spinner.glade
+ui/accounts_editor.ui
 ui/certificate_warning_dialog.glade
 ui/composer-headerbar.ui
 ui/composer-link-popover.ui
diff --git a/src/client/accounts/account-manager.vala b/src/client/accounts/account-manager.vala
index 2247b955..949c3f12 100644
--- a/src/client/accounts/account-manager.vala
+++ b/src/client/accounts/account-manager.vala
@@ -187,6 +187,12 @@ public class AccountManager : GLib.Object {
         return (state != null) ? state.account : null;
     }
 
+    /** Returns the status for the given account. */
+    public Status get_status(Geary.AccountInformation account) {
+        AccountState? state = this.accounts.get(account.id);
+        return (state != null) ? state.status : Status.UNAVAILABLE;
+    }
+
     /** Returns a read-only iterable of all currently known accounts. */
     public Geary.Iterable<Geary.AccountInformation> iterable() {
         return Geary.traverse<AccountState>(
@@ -686,6 +692,20 @@ public class AccountManager : GLib.Object {
             id, imap, smtp
         );
         info.service_provider = provider;
+
+        // Known providers such as GMail will have a label specified
+        // by clients, but other accounts can only really be
+        // identified by their server names. Try to extract a 'nice'
+        // value for the label here.
+        if (provider == Geary.ServiceProvider.OTHER) {
+            string imap_host = imap.host;
+            string[] host_parts = imap_host.split(".");
+            if (host_parts.length > 1) {
+                host_parts = host_parts[1:host_parts.length];
+            }
+            info.service_label = string.joinv(".", host_parts);
+        }
+
         return info;
     }
 
@@ -698,6 +718,8 @@ public class AccountManager : GLib.Object {
             new GoaServiceInformation(Geary.Protocol.SMTP, mediator, account)
         );
 
+        info.service_label = account.get_account().provider_name;
+
         switch (account.get_account().provider_type) {
         case "google":
             info.service_provider = Geary.ServiceProvider.GMAIL;
diff --git a/src/client/accounts/accounts-editor.vala b/src/client/accounts/accounts-editor.vala
new file mode 100644
index 00000000..eb4729ab
--- /dev/null
+++ b/src/client/accounts/accounts-editor.vala
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2018 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.
+ */
+
+/**
+ * The main account editor window.
+ */
+[GtkTemplate (ui = "/org/gnome/Geary/accounts_editor.ui")]
+public class Accounts.Editor : Gtk.Dialog {
+
+
+    private static int ordinal_sort(Gtk.ListBoxRow a, Gtk.ListBoxRow b) {
+        AccountRow? account_a = a as AccountRow;
+        AccountRow? account_b = b as AccountRow;
+
+        if (account_a == null) {
+            return (account_b == null) ? 0 : 1;
+        } else if (account_b == null) {
+            return -1;
+        }
+
+        return Geary.AccountInformation.compare_ascending(
+            account_a.account, account_b.account
+        );
+    }
+
+    private static void update_header(Gtk.ListBoxRow row, Gtk.ListBoxRow? first) {
+        if (first == null) {
+            row.set_header(null);
+        } else if (row.get_header() == null) {
+            row.set_header(new Gtk.Separator(Gtk.Orientation.HORIZONTAL));
+        }
+    }
+
+    private AccountManager accounts;
+
+    [GtkChild]
+    private Gtk.ListBox accounts_list;
+
+
+    public Editor(AccountManager accounts, Gtk.Window parent) {
+        this.accounts = accounts;
+        set_transient_for(parent);
+
+        this.accounts_list.set_header_func(update_header);
+        this.accounts_list.set_sort_func(ordinal_sort);
+
+        foreach (Geary.AccountInformation account in accounts.iterable()) {
+            add_account(account, accounts.get_status(account));
+        }
+
+        this.accounts_list.add(new AddRow());
+
+        accounts.account_added.connect(on_account_added);
+        accounts.account_status_changed.connect(on_account_status_changed);
+        accounts.account_removed.connect(on_account_removed);
+    }
+
+    ~Editor() {
+        this.accounts.account_added.disconnect(on_account_added);
+        this.accounts.account_status_changed.disconnect(on_account_status_changed);
+        this.accounts.account_removed.disconnect(on_account_removed);
+    }
+
+    private void add_account(Geary.AccountInformation account,
+                             AccountManager.Status status) {
+        this.accounts_list.add(new AccountRow(account, status));
+    }
+
+    private AccountRow? get_account_row(Geary.AccountInformation account) {
+        AccountRow? row = null;
+        this.accounts_list.foreach((child) => {
+                AccountRow? account_row = child as AccountRow;
+                if (account_row != null && account_row.account == account) {
+                    row = account_row;
+                }
+            });
+        return row;
+    }
+
+    private void on_account_added(Geary.AccountInformation account,
+                                  AccountManager.Status status) {
+        add_account(account, status);
+    }
+
+    private void on_account_status_changed(Geary.AccountInformation account,
+                                           AccountManager.Status status) {
+        AccountRow? row = get_account_row(account);
+        if (row != null) {
+            row.update(status);
+        }
+    }
+
+    private void on_account_removed(Geary.AccountInformation account) {
+        AccountRow? row = get_account_row(account);
+        if (row != null) {
+            this.accounts_list.remove(row);
+        }
+    }
+
+}
+
+private class Accounts.AccountRow : Gtk.ListBoxRow {
+
+
+    public Geary.AccountInformation account;
+
+    private Gtk.Image unavailable_icon = new Gtk.Image.from_icon_name(
+        "dialog-warning-symbolic", Gtk.IconSize.BUTTON
+    );
+    private Gtk.Label account_name = new Gtk.Label("");
+    private Gtk.Label account_details = new Gtk.Label("");
+
+
+    public AccountRow(Geary.AccountInformation account,
+                      AccountManager.Status status) {
+        this.account = account;
+        get_style_context().add_class("geary-settings");
+
+        this.unavailable_icon.no_show_all = true;
+
+        this.account_name.set_hexpand(true);
+        this.account_name.halign = Gtk.Align.START;
+
+        Gtk.Grid layout = new Gtk.Grid();
+        layout.orientation = Gtk.Orientation.HORIZONTAL;
+        layout.add(this.unavailable_icon);
+        layout.add(this.account_name);
+        layout.add(this.account_details);
+
+        add(layout);
+
+        update(status);
+    }
+
+    public void update(AccountManager.Status status) {
+        if (status != AccountManager.Status.UNAVAILABLE) {
+            this.unavailable_icon.hide();
+            this.set_tooltip_text("");
+        } else {
+            this.unavailable_icon.show();
+            this.set_tooltip_text(
+                _("This account has encountered a problem and is unavailable")
+            );
+        }
+
+        string name = this.account.nickname;
+        if (Geary.String.is_empty(name)) {
+            name = account.primary_mailbox.to_address_display("", "");
+        }
+        this.account_name.set_text(name);
+
+        string? details = this.account.service_label;
+        switch (account.service_provider) {
+        case Geary.ServiceProvider.GMAIL:
+            details = _("GMail");
+            break;
+
+        case Geary.ServiceProvider.OUTLOOK:
+            details = _("Outlook.com");
+            break;
+
+        case Geary.ServiceProvider.YAHOO:
+            details = _("Yahoo");
+            break;
+        }
+        this.account_details.set_text(details);
+
+        if (status == AccountManager.Status.ENABLED) {
+            this.account_name.get_style_context().remove_class(
+                Gtk.STYLE_CLASS_DIM_LABEL
+            );
+            this.account_details.get_style_context().remove_class(
+                Gtk.STYLE_CLASS_DIM_LABEL
+            );
+        } else {
+            this.account_name.get_style_context().add_class(
+                Gtk.STYLE_CLASS_DIM_LABEL
+            );
+            this.account_details.get_style_context().add_class(
+                Gtk.STYLE_CLASS_DIM_LABEL
+            );
+        }
+    }
+
+}
+
+private class Accounts.AddRow : Gtk.ListBoxRow {
+
+
+    public AddRow() {
+        get_style_context().add_class("geary-settings");
+
+        Gtk.Image add_icon = new Gtk.Image.from_icon_name(
+            "list-add-symbolic", Gtk.IconSize.BUTTON
+        );
+        add_icon.set_hexpand(true);
+
+        Gtk.Grid layout = new Gtk.Grid();
+        layout.orientation = Gtk.Orientation.HORIZONTAL;
+
+        layout.add(add_icon);
+
+        add(layout);
+    }
+
+
+}
diff --git a/src/client/application/geary-application.vala b/src/client/application/geary-application.vala
index 25d3a110..d3cf494b 100644
--- a/src/client/application/geary-application.vala
+++ b/src/client/application/geary-application.vala
@@ -422,10 +422,12 @@ public class GearyApplication : Gtk.Application {
     }
 
     private void on_activate_accounts() {
-        AccountDialog dialog = new AccountDialog(this, get_active_window());
-        dialog.show_all();
-        dialog.run();
-        dialog.destroy();
+        Accounts.Editor editor = new Accounts.Editor(
+            this.controller.account_manager, get_active_window()
+        );
+        editor.show_all();
+        editor.run();
+        editor.destroy();
     }
 
     private void on_activate_compose() {
diff --git a/src/client/meson.build b/src/client/meson.build
index 6f8a75d2..906a274e 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -19,6 +19,7 @@ geary_client_vala_sources = files(
   'accounts/account-dialog-spinner-pane.vala',
   'accounts/account-manager.vala',
   'accounts/account-spinner-page.vala',
+  'accounts/accounts-editor.vala',
   'accounts/add-edit-page.vala',
   'accounts/goa-service-information.vala',
   'accounts/local-service-information.vala',
diff --git a/src/engine/api/geary-account-information.vala b/src/engine/api/geary-account-information.vala
index ce0d3140..7efab6d7 100644
--- a/src/engine/api/geary-account-information.vala
+++ b/src/engine/api/geary-account-information.vala
@@ -133,9 +133,16 @@ public class Geary.AccountInformation : BaseObject {
      */
     public Gee.List<Geary.RFC822.MailboxAddress>? alternate_mailboxes { get; private set; default = null; }
 
+    /** Specifies the email provider for this account. */
     public Geary.ServiceProvider service_provider {
         get; set; default = Geary.ServiceProvider.OTHER;
     }
+
+    /** A human-readable label describing the service. */
+    public string service_label {
+        get; set; default = "";
+    }
+
     public int prefetch_period_days {
         get; set; default = DEFAULT_PREFETCH_PERIOD_DAYS;
     }
diff --git a/ui/accounts_editor.ui b/ui/accounts_editor.ui
new file mode 100644
index 00000000..7750d947
--- /dev/null
+++ b/ui/accounts_editor.ui
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <template class="AccountsEditor" parent="GtkDialog">
+    <property name="can_focus">False</property>
+    <property name="modal">True</property>
+    <property name="default_width">700</property>
+    <property name="default_height">450</property>
+    <property name="icon_name">org.gnome.Geary</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkStack">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkGrid">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkScrolledWindow">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
+                    <property name="hscrollbar_policy">never</property>
+                    <property name="min_content_height">400</property>
+                    <child>
+                      <object class="GtkViewport">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkGrid">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <child>
+                              <object class="GtkFrame">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="margin_top">32</property>
+                                <property name="margin_bottom">32</property>
+                                <property name="label_xalign">0</property>
+                                <property name="shadow_type">in</property>
+                                <child>
+                                  <object class="GtkListBox" id="accounts_list">
+                                    <property name="width_request">0</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="selection_mode">none</property>
+                                  </object>
+                                </child>
+                                <child type="label_item">
+                                  <placeholder/>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">0</property>
+                              </packing>
+                            </child>
+                            <style>
+                              <class name="geary-account-view"/>
+                            </style>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="name">account_list</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="titlebar">
+      <object class="GtkHeaderBar">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="title">Accounts</property>
+        <property name="show_close_button">True</property>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/ui/geary.css b/ui/geary.css
index eec6250f..e34940e5 100644
--- a/ui/geary.css
+++ b/ui/geary.css
@@ -180,3 +180,20 @@ grid.geary-message-summary {
 .geary-empty-placeholder > .title {
   font-weight: bold;
 }
+
+/* Accounts.Editor */
+
+grid.geary-account-view {
+  margin: 32px 128px;
+}
+
+grid.geary-account-view image:dir(ltr) {
+  margin-right: 6px;
+}
+grid.geary-account-view image:dir(rtl) {
+  margin-left: 6px;
+}
+
+row.geary-settings  {
+  padding: 16px;
+}
diff --git a/ui/org.gnome.Geary.gresource.xml b/ui/org.gnome.Geary.gresource.xml
index e69af90b..9b8e3bd2 100644
--- a/ui/org.gnome.Geary.gresource.xml
+++ b/ui/org.gnome.Geary.gresource.xml
@@ -4,6 +4,7 @@
     <file compressed="true" preprocess="xml-stripblanks">account_cannot_remove.glade</file>
     <file compressed="true" preprocess="xml-stripblanks">account_list.glade</file>
     <file compressed="true" preprocess="xml-stripblanks">account_spinner.glade</file>
+    <file compressed="true" preprocess="xml-stripblanks">accounts_editor.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">certificate_warning_dialog.glade</file>
     <file compressed="true">client-web-view.js</file>
     <file compressed="true">client-web-view-allow-remote-images.js</file>


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