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.
This commit is contained in:
parent
b37d146a2d
commit
3c06c0969e
8 changed files with 192 additions and 14 deletions
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,11 @@ 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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue