From 0ea4ac7e20674e3e6a8d1b3d4b53702dace72907 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sat, 11 Mar 2017 22:48:35 +0100 Subject: Plug-In API: allow adding custom entries to account settings Also make OpenPGP code use this API --- libdino/src/plugin/interfaces.vala | 27 ++++++++++ libdino/src/plugin/registry.vala | 13 +++++ libdino/src/service/pgp_manager.vala | 80 +++++++++++++++++++++++++++++- libdino/src/ui/manage_accounts/dialog.vala | 74 +++++++++++++-------------- 4 files changed, 154 insertions(+), 40 deletions(-) (limited to 'libdino/src') diff --git a/libdino/src/plugin/interfaces.vala b/libdino/src/plugin/interfaces.vala index 19873003..35c93786 100644 --- a/libdino/src/plugin/interfaces.vala +++ b/libdino/src/plugin/interfaces.vala @@ -1,5 +1,15 @@ +using Gtk; + namespace Dino.Plugins { +public enum Priority { + LOWEST, + LOWER, + DEFAULT, + HIGHER, + HIGHEST +} + public interface RootInterface : Object { public abstract void registered(Dino.Application app); @@ -13,4 +23,21 @@ public interface EncryptionListEntry : Object { public abstract bool can_encrypt(Entities.Conversation conversation); } +public abstract class AccountSettingsEntry : Object { + public abstract string id { get; } + public virtual Priority priority { get { return Priority.DEFAULT; } } + public abstract string name { get; } + public virtual int16 label_top_padding { get { return -1; } } + + public abstract AccountSettingsWidget get_widget(); +} + +public interface AccountSettingsWidget : Gtk.Widget { + public abstract void set_account(Entities.Account account); + + public abstract signal void activated(); + + public abstract void deactivate(); +} + } \ No newline at end of file diff --git a/libdino/src/plugin/registry.vala b/libdino/src/plugin/registry.vala index 8c75784e..27cac6f3 100644 --- a/libdino/src/plugin/registry.vala +++ b/libdino/src/plugin/registry.vala @@ -4,6 +4,7 @@ namespace Dino.Plugins { public class Registry { internal ArrayList encryption_list_entries = new ArrayList(); + internal ArrayList account_settings_entries = new ArrayList(); public bool register_encryption_list_entry(EncryptionListEntry entry) { lock(encryption_list_entries) { @@ -15,6 +16,18 @@ public class Registry { return true; } } + + public bool register_account_settings_entry(AccountSettingsEntry entry) { + lock(account_settings_entries) { + foreach(var e in account_settings_entries) { + if (e.id == entry.id) return false; + } + account_settings_entries.add(entry); + // TODO: Order by priority + account_settings_entries.sort((a,b) => b.name.collate(a.name)); + return true; + } + } } } \ No newline at end of file diff --git a/libdino/src/service/pgp_manager.vala b/libdino/src/service/pgp_manager.vala index 76f70b84..a91feac6 100644 --- a/libdino/src/service/pgp_manager.vala +++ b/libdino/src/service/pgp_manager.vala @@ -17,7 +17,85 @@ namespace Dino { public static void start(StreamInteractor stream_interactor, Database db) { PgpManager m = new PgpManager(stream_interactor, db); stream_interactor.add_module(m); - (GLib.Application.get_default() as Application).plugin_registry.register_encryption_list_entry(new EncryptionListEntry(m)); + + Plugins.Registry plugin_registry = (GLib.Application.get_default() as Application).plugin_registry; + plugin_registry.register_encryption_list_entry(new EncryptionListEntry(m)); + plugin_registry.register_account_settings_entry(new AccountSettingsEntry(m)); + } + + private class AccountSettingsEntry : Plugins.AccountSettingsEntry { + private PgpManager pgp_manager; + + public AccountSettingsEntry(PgpManager pgp_manager) { + this.pgp_manager = pgp_manager; + } + + public override string id { get { + return "pgp_key_picker"; + }} + + public override string name { get { + return "OpenPGP"; + }} + + public override Plugins.AccountSettingsWidget get_widget() { + return new AccountSettingsWidget(); + } + } + + [GtkTemplate (ui = "/org/dino-im/manage_accounts/pgp_stack.ui")] + private class AccountSettingsWidget : Gtk.Stack, Plugins.AccountSettingsWidget { + [GtkChild] private Gtk.Label pgp_label; + [GtkChild] private Gtk.Button pgp_button; + [GtkChild] private Gtk.ComboBox pgp_combobox; + + private Gtk.ListStore list_store = new Gtk.ListStore(2, typeof(string), typeof(string?)); + + public AccountSettingsWidget() { + Gtk.CellRendererText renderer = new Gtk.CellRendererText(); + renderer.set_padding(0, 0); + pgp_combobox.pack_start(renderer, true); + pgp_combobox.add_attribute(renderer, "markup", 0); + pgp_button.clicked.connect(() => { activated(); this.set_visible_child_name("entry"); pgp_combobox.popup(); }); + } + + public void deactivate() { + this.set_visible_child_name("label"); + } + + private void key_changed() { + Gtk.TreeIter selected; + pgp_combobox.get_active_iter(out selected); + Value text; + list_store.get_value(selected, 0, out text); + pgp_label.set_markup((string) text); + deactivate(); + } + + public void set_account(Account account) { + populate_pgp_combobox(account); + } + + private void populate_pgp_combobox(Account account) { + pgp_combobox.changed.disconnect(key_changed); + + Gtk.TreeIter iter; + pgp_combobox.set_model(list_store); + + list_store.clear(); + list_store.append(out iter); + pgp_label.set_markup("Disabled\nSelect key"); + list_store.set(iter, 0, "Disabled\nSelect key", 1, null); + Gee.List list = GPGHelper.get_keylist(null, true); + foreach (GPG.Key key in list) { + list_store.append(out iter); + list_store.set(iter, 0, @"$(Markup.escape_text(key.uids[0].uid))\n0x$(Markup.escape_text(key.fpr[0:16]))"); + list_store.set(iter, 1, key.fpr); + } + + pgp_combobox.set_active(0); + pgp_combobox.changed.connect(key_changed); + } } private class EncryptionListEntry : Plugins.EncryptionListEntry, Object { diff --git a/libdino/src/ui/manage_accounts/dialog.vala b/libdino/src/ui/manage_accounts/dialog.vala index 879c6aee..3616c403 100644 --- a/libdino/src/ui/manage_accounts/dialog.vala +++ b/libdino/src/ui/manage_accounts/dialog.vala @@ -1,4 +1,5 @@ using Gdk; +using Gee; using Gtk; using Markup; @@ -32,20 +33,14 @@ public class Dialog : Gtk.Window { [GtkChild] public Button alias_button; [GtkChild] public Entry alias_entry; - [GtkChild] public Stack pgp_stack; - [GtkChild] public Label pgp_label; - [GtkChild] public Button pgp_button; - [GtkChild] public ComboBox pgp_combobox; + [GtkChild] public Grid settings_list; + private ArrayList plugin_widgets = new ArrayList(); private Database db; private StreamInteractor stream_interactor; construct { - CellRendererText renderer = new Gtk.CellRendererText(); - pgp_combobox.pack_start(renderer, true); - pgp_combobox.add_attribute(renderer, "markup", 0); - account_list.row_selected.connect(account_list_row_selected); add_button.clicked.connect(add_button_clicked); no_accounts_add.clicked.connect(add_button_clicked); @@ -55,6 +50,25 @@ public class Dialog : Gtk.Window { image_button.clicked.connect(on_image_button_clicked); main_stack.set_visible_child_name("no_accounts"); + + int row_index = 4; + int16 default_top_padding = new Gtk.Button().get_style_context().get_padding(Gtk.StateFlags.NORMAL).top + 1; + Application app = GLib.Application.get_default() as Application; + foreach (var e in app.plugin_registry.account_settings_entries) { + Plugins.AccountSettingsWidget widget = e.get_widget(); + plugin_widgets.add(widget); + widget.visible = true; + widget.activated.connect(child_activated); + Label label = new Label(e.name); + label.get_style_context().add_class("dim-label"); + label.set_padding(0, e.label_top_padding == -1 ? default_top_padding : e.label_top_padding); + label.yalign = 0; + label.xalign = 1; + label.visible = true; + settings_list.attach(label, 0, row_index); + settings_list.attach(widget, 1, row_index, 2); + row_index++; + } } public Dialog(StreamInteractor stream_interactor, Database db) { @@ -131,38 +145,13 @@ public class Dialog : Gtk.Window { password_button.clicked.connect(() => { set_active_stack(password_stack); }); alias_button.clicked.connect(() => { set_active_stack(alias_stack); }); - pgp_button.clicked.connect(() => { set_active_stack(pgp_stack); pgp_combobox.popup(); }); active_switch.state_set.connect(on_active_switch_state_changed); - populate_pgp_combobox(account); - } - - private void populate_pgp_combobox(Account account) { - - Gtk.ListStore list_store = new Gtk.ListStore(2, typeof(string), typeof(string?)); - Gtk.TreeIter iter; - - pgp_combobox.set_model(list_store); - - list_store.append(out iter); - list_store.set(iter, 0, "Disabled", 1, null); - Gee.List list = GPGHelper.get_keylist(null, true); - foreach (GPG.Key key in list) { - list_store.append(out iter); - list_store.set(iter, 0, @"$(escape_text(key.uids[0].uid))\n0x$(escape_text(key.fpr[0:16]))"); - list_store.set(iter, 1, key.fpr); + foreach(Plugins.AccountSettingsWidget widget in plugin_widgets) { + widget.set_account(account); } - pgp_combobox.set_active(0); - - pgp_combobox.changed.connect(() => { - TreeIter selected; - pgp_combobox.get_active_iter(out selected); - Value text; - list_store.get_value(selected, 0, out text); - pgp_label.set_markup((string) text); - pgp_stack.set_visible_child_name("label"); - }); + child_activated(null); } @@ -222,11 +211,18 @@ public class Dialog : Gtk.Window { } } + private void child_activated(Gtk.Widget? widget) { + if (widget != password_stack) password_stack.set_visible_child_name("label"); + if (widget != alias_stack) alias_stack.set_visible_child_name("label"); + + foreach(var w in plugin_widgets) { + if (widget != (Gtk.Widget)w) w.deactivate(); + } + } + private void set_active_stack(Stack stack) { stack.set_visible_child_name("entry"); - if (stack != password_stack) password_stack.set_visible_child_name("label"); - if (stack != alias_stack) alias_stack.set_visible_child_name("label"); - if (stack != pgp_stack) pgp_stack.set_visible_child_name("label"); + child_activated(stack); } } -- cgit v1.2.3-70-g09d2