[geary/wip/714104-refine-account-dialog] Improve handling of GOA accounts in the account editor
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/714104-refine-account-dialog] Improve handling of GOA accounts in the account editor
- Date: Wed, 12 Sep 2018 11:55:02 +0000 (UTC)
commit 1013e462e6f2dc87eb58aeb3725e2284206b3e30
Author: Michael Gratton <mike vee net>
Date: Sun Sep 9 18:39:44 2018 +1000
Improve handling of GOA accounts in the account editor
Show GNOME settings when adding a supported GOA service type and
it is installed, otherwise show Geary's custom password-based impl.
For GOA accounts, hide the Remove button, and enable opening the
account in GNOME Settings from the server pane.
src/client/accounts/accounts-editor-edit-pane.vala | 11 ++-
src/client/accounts/accounts-editor-list-pane.vala | 30 +++++-
.../accounts/accounts-editor-servers-pane.vala | 50 +++++++++-
src/client/accounts/accounts-editor.vala | 5 +-
src/client/accounts/accounts-manager.vala | 103 +++++++++++++++++++++
src/client/accounts/goa-service-information.vala | 2 +-
ui/accounts_editor_edit_pane.ui | 2 +-
ui/accounts_editor_servers_pane.ui | 3 +
8 files changed, 192 insertions(+), 14 deletions(-)
---
diff --git a/src/client/accounts/accounts-editor-edit-pane.vala
b/src/client/accounts/accounts-editor-edit-pane.vala
index ee2fb119..8df1f45c 100644
--- a/src/client/accounts/accounts-editor-edit-pane.vala
+++ b/src/client/accounts/accounts-editor-edit-pane.vala
@@ -48,6 +48,9 @@ internal class Accounts.EditorEditPane : Gtk.Grid, EditorPane, AccountPane {
[GtkChild]
private Gtk.Button undo_button;
+ [GtkChild]
+ private Gtk.Button remove_button;
+
public EditorEditPane(Editor editor, Geary.AccountInformation account) {
this.editor = editor;
@@ -106,6 +109,10 @@ internal class Accounts.EditorEditPane : Gtk.Grid, EditorPane, AccountPane {
this.settings_list.set_header_func(Editor.seperator_headers);
this.settings_list.add(new EmailPrefetchRow(this));
+ this.remove_button.set_visible(
+ !this.editor.accounts.is_goa_account(account)
+ );
+
this.account.information_changed.connect(on_account_changed);
update_header();
@@ -189,7 +196,9 @@ internal class Accounts.EditorEditPane : Gtk.Grid, EditorPane, AccountPane {
[GtkCallback]
private void on_remove_account_clicked() {
- this.editor.push(new EditorRemovePane(this.editor, this.account));
+ if (!this.editor.accounts.is_goa_account(account)) {
+ this.editor.push(new EditorRemovePane(this.editor, this.account));
+ }
}
[GtkCallback]
diff --git a/src/client/accounts/accounts-editor-list-pane.vala
b/src/client/accounts/accounts-editor-list-pane.vala
index 4f3ad517..c54afb14 100644
--- a/src/client/accounts/accounts-editor-list-pane.vala
+++ b/src/client/accounts/accounts-editor-list-pane.vala
@@ -28,9 +28,9 @@ internal class Accounts.EditorListPane : Gtk.Grid, EditorPane {
}
- protected weak Accounts.Editor editor { get; set; }
+ internal Manager accounts { get; private set; }
- private Manager accounts;
+ protected weak Accounts.Editor editor { get; set; }
private Application.CommandStack commands = new Application.CommandStack();
@@ -67,8 +67,10 @@ internal class Accounts.EditorListPane : Gtk.Grid, EditorPane {
public EditorListPane(Editor editor) {
this.editor = editor;
- this.accounts =
- ((GearyApplication) editor.application).controller.account_manager;
+
+ // keep our own copy of this so we can disconnect from its signals
+ // without worrying about the editor's lifecycle
+ this.accounts = editor.accounts;
this.pane_content.set_focus_vadjustment(this.pane_adjustment);
@@ -404,7 +406,25 @@ private class Accounts.AddServiceProviderRow : EditorRow<EditorListPane> {
}
public override void activated(EditorListPane pane) {
- pane.show_add_account(this.provider);
+ pane.accounts.add_goa_account.begin(
+ this.provider, null,
+ (obj, res) => {
+ bool add_local = false;
+ try {
+ pane.accounts.add_goa_account.end(res);
+ } catch (Error.INVALID err) {
+ // Not a supported type, so don't bother logging the error
+ add_local = true;
+ } catch (GLib.Error err) {
+ debug("Failed to add %s via GOA: %s",
+ this.provider.to_string(), err.message);
+ add_local = true;
+ }
+
+ if (add_local) {
+ pane.show_add_account(this.provider);
+ }
+ });
}
}
diff --git a/src/client/accounts/accounts-editor-servers-pane.vala
b/src/client/accounts/accounts-editor-servers-pane.vala
index 43cd001d..733ae331 100644
--- a/src/client/accounts/accounts-editor-servers-pane.vala
+++ b/src/client/accounts/accounts-editor-servers-pane.vala
@@ -51,7 +51,9 @@ internal class Accounts.EditorServersPane : Gtk.Grid, EditorPane, AccountPane {
);
// Only add an account provider if it is esoteric enough.
if (this.account.imap.mediator is GoaMediator) {
- this.details_list.add(new AccountProviderRow(this.account));
+ this.details_list.add(
+ new AccountProviderRow(editor.accounts, this.account)
+ );
}
this.details_list.add(new SaveDraftsRow(this.account));
@@ -119,14 +121,25 @@ internal class Accounts.EditorServersPane : Gtk.Grid, EditorPane, AccountPane {
update_header();
}
+ [GtkCallback]
+ private void on_activate(Gtk.ListBoxRow row) {
+ Accounts.EditorRow<EditorServersPane> server_row =
+ row as Accounts.EditorRow<EditorServersPane>;
+ if (server_row != null) {
+ server_row.activated(this);
+ }
+ }
+
}
private class Accounts.AccountProviderRow :
AccountRow<EditorServersPane,Gtk.Label> {
+ private Manager accounts;
- public AccountProviderRow(Geary.AccountInformation account) {
+ public AccountProviderRow(Manager accounts,
+ Geary.AccountInformation account) {
base(
account,
// Translators: This label describes the program that
@@ -136,21 +149,48 @@ private class Accounts.AccountProviderRow :
new Gtk.Label("")
);
- // Can't change this, so dim it out
- this.value.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
- this.set_activatable(false);
+ this.accounts = accounts;
update();
}
public override void update() {
string? source = null;
+ bool enabled = false;
if (this.account.imap.mediator is GoaMediator) {
source = _("GNOME Online Accounts");
+ enabled = true;
} else {
source = _("Geary");
}
+
this.value.set_text(source);
+ this.set_activatable(enabled);
+ Gtk.StyleContext style = this.value.get_style_context();
+ if (enabled) {
+ style.remove_class(Gtk.STYLE_CLASS_DIM_LABEL);
+ } else {
+ style.add_class(Gtk.STYLE_CLASS_DIM_LABEL);
+ }
+ }
+
+ public override void activated(EditorServersPane pane) {
+ if (this.accounts.is_goa_account(this.account)) {
+ this.accounts.show_goa_account.begin(
+ account, null,
+ (obj, res) => {
+ try {
+ this.accounts.show_goa_account.end(res);
+ } catch (GLib.Error err) {
+ // XXX display an error to the user
+ debug(
+ "Failed to show GOA account \"%s\": %s",
+ account.id,
+ err.message
+ );
+ }
+ });
+ }
}
}
diff --git a/src/client/accounts/accounts-editor.vala b/src/client/accounts/accounts-editor.vala
index f69c116e..9f37b86b 100644
--- a/src/client/accounts/accounts-editor.vala
+++ b/src/client/accounts/accounts-editor.vala
@@ -27,8 +27,10 @@ public class Accounts.Editor : Gtk.Dialog {
}
- private SimpleActionGroup actions = new SimpleActionGroup();
+ internal Manager accounts { get; private set; }
+
+ private SimpleActionGroup actions = new SimpleActionGroup();
private Gtk.Stack editor_panes = new Gtk.Stack();
private EditorListPane editor_list_pane;
@@ -39,6 +41,7 @@ public class Accounts.Editor : Gtk.Dialog {
public Editor(GearyApplication application, Gtk.Window parent) {
this.application = application;
+ this.accounts = application.controller.account_manager;
set_default_size(700, 450);
set_icon_name(GearyApplication.APP_ID);
diff --git a/src/client/accounts/accounts-manager.vala b/src/client/accounts/accounts-manager.vala
index 8a6fed26..fe53b3c4 100644
--- a/src/client/accounts/accounts-manager.vala
+++ b/src/client/accounts/accounts-manager.vala
@@ -417,6 +417,56 @@ public class Accounts.Manager : GLib.Object {
}
}
+ /**
+ * Determines if an account is a GOA account or not.
+ */
+ public bool is_goa_account(Geary.AccountInformation account) {
+ return (account.imap is GoaServiceInformation);
+ }
+
+ /**
+ * Opens GNOME Settings to add an account of a particular type.
+ *
+ * Throws an error if it was not possible to open GNOME Settings,
+ * or if the given type is not supported for by GOA.
+ */
+ public async void add_goa_account(Geary.ServiceProvider type,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ switch (type) {
+ case Geary.ServiceProvider.GMAIL:
+ yield open_goa_settings("add", "google", cancellable);
+ break;
+
+ case Geary.ServiceProvider.OUTLOOK:
+ yield open_goa_settings("add", "windows_live", cancellable);
+ break;
+
+ default:
+ throw new Error.INVALID("Not supported for GOA");
+ }
+ }
+
+ /**
+ * Opens GOA settings for the given account in GNOME Settings.
+ *
+ * Throws an error if it was not possible to open GNOME Settings,
+ * or if the given account is not backed by GOA.
+ */
+ public async void show_goa_account(Geary.AccountInformation account,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ GoaServiceInformation? goa_service =
+ account.imap as GoaServiceInformation;
+ if (goa_service == null) {
+ throw new Error.INVALID("Not a GOA Account");
+ }
+
+ yield open_goa_settings(
+ goa_service.account.account.id, null, cancellable
+ );
+ }
+
/**
* Loads an account info from a config directory.
*
@@ -864,6 +914,59 @@ public class Accounts.Manager : GLib.Object {
}
}
+ private async void open_goa_settings(string action,
+ string? param,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ // This method was based on the implementation from:
+ // https://gitlab.gnome.org/GNOME/gnome-calendar/blob/master/src/gcal-source-dialog.c,
+ // Courtesy Georges Basile Stavracas Neto <georges stavracas gmail com>
+ GLib.DBusProxy settings = yield new GLib.DBusProxy.for_bus(
+ GLib.BusType.SESSION,
+ GLib.DBusProxyFlags.NONE,
+ null,
+ "org.gnome.ControlCenter",
+ "/org/gnome/ControlCenter",
+ "org.gtk.Actions",
+ cancellable
+ );
+
+ // @s "launch-panel"
+ // @av [<@(sav) ("online-accounts", [<@s "add">, <@s "google">])>]
+ // @a{sv} {}
+
+ GLib.Variant[] args = new GLib.Variant[] {
+ new GLib.Variant.variant(new GLib.Variant.string(action))
+ };
+ if (param != null) {
+ args += new GLib.Variant.variant(new GLib.Variant.string(param));
+ }
+
+ GLib.Variant command = new GLib.Variant.tuple(
+ new GLib.Variant[] {
+ new GLib.Variant.string("online-accounts"),
+ new GLib.Variant.array(GLib.VariantType.VARIANT, args)
+ }
+ );
+
+ GLib.Variant params = new GLib.Variant.tuple(
+ new GLib.Variant[] {
+ new GLib.Variant.string("launch-panel"),
+ new GLib.Variant.array(
+ GLib.VariantType.VARIANT,
+ new GLib.Variant[] {
+ new GLib.Variant.variant(command)
+ }
+ ),
+ new GLib.Variant("a{sv}")
+ }
+ );
+
+ yield settings.call(
+ "Activate", params, GLib.DBusCallFlags.NONE, -1, cancellable
+ );
+ }
+
private void on_goa_account_added(Goa.Object account) {
// XXX get a cancellable for this.
this.create_goa_account.begin(account, null);
diff --git a/src/client/accounts/goa-service-information.vala
b/src/client/accounts/goa-service-information.vala
index d976a0c6..06e81f2a 100644
--- a/src/client/accounts/goa-service-information.vala
+++ b/src/client/accounts/goa-service-information.vala
@@ -10,7 +10,7 @@
public class GoaServiceInformation : Geary.ServiceInformation {
- private Goa.Object account;
+ internal Goa.Object account { get; private set; }
public GoaServiceInformation(Geary.Protocol protocol,
GoaMediator mediator,
diff --git a/ui/accounts_editor_edit_pane.ui b/ui/accounts_editor_edit_pane.ui
index cd02476b..b59a88b7 100644
--- a/ui/accounts_editor_edit_pane.ui
+++ b/ui/accounts_editor_edit_pane.ui
@@ -254,7 +254,7 @@
</packing>
</child>
<child>
- <object class="GtkButton">
+ <object class="GtkButton" id="remove_button">
<property name="label" translatable="yes" comments="This is the remove account
button in the account settings.">Remove Account</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
diff --git a/ui/accounts_editor_servers_pane.ui b/ui/accounts_editor_servers_pane.ui
index f2e5da9f..f54e07f2 100644
--- a/ui/accounts_editor_servers_pane.ui
+++ b/ui/accounts_editor_servers_pane.ui
@@ -93,6 +93,7 @@
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<signal name="keynav-failed" handler="on_list_keynav_failed" swapped="no"/>
+ <signal name="row-activated" handler="on_activate" swapped="no"/>
</object>
</child>
<child type="label_item">
@@ -132,6 +133,7 @@
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<signal name="keynav-failed" handler="on_list_keynav_failed" swapped="no"/>
+ <signal name="row-activated" handler="on_activate" swapped="no"/>
</object>
</child>
<child type="label_item">
@@ -171,6 +173,7 @@
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<signal name="keynav-failed" handler="on_list_keynav_failed" swapped="no"/>
+ <signal name="row-activated" handler="on_activate" swapped="no"/>
</object>
</child>
<child type="label_item">
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]