diff --git a/libdino/CMakeLists.txt b/libdino/CMakeLists.txt index 6fc31050..e638b3c8 100644 --- a/libdino/CMakeLists.txt +++ b/libdino/CMakeLists.txt @@ -39,6 +39,7 @@ set(RESOURCE_LIST manage_accounts/account_row.ui manage_accounts/add_account_dialog.ui manage_accounts/dialog.ui + manage_accounts/pgp_stack.ui menu_add.ui menu_app.ui menu_conversation.ui diff --git a/libdino/data/manage_accounts/dialog.ui b/libdino/data/manage_accounts/dialog.ui index d44cae71..e431bfff 100644 --- a/libdino/data/manage_accounts/dialog.ui +++ b/libdino/data/manage_accounts/dialog.ui @@ -77,10 +77,10 @@ - + True 10 - 10 + 5 True @@ -133,12 +133,14 @@ True + end + center 2 0 1 - 1 + 2 @@ -247,58 +249,6 @@ 1 - - - OpenPGP - 1 - True - - - - 0 - 4 - 1 - 1 - - - - - True - - - none - True - - - 0 - True - - - - - label - - - - - True - 200 - True - - - entry - - - - - 1 - 4 - 2 - 1 - - diff --git a/libdino/data/manage_accounts/pgp_stack.ui b/libdino/data/manage_accounts/pgp_stack.ui new file mode 100644 index 00000000..4df9f0b8 --- /dev/null +++ b/libdino/data/manage_accounts/pgp_stack.ui @@ -0,0 +1,31 @@ + + + + \ No newline at end of file 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); } }