diff options
Diffstat (limited to 'main/src/ui/manage_accounts')
-rw-r--r-- | main/src/ui/manage_accounts/account_row.vala | 22 | ||||
-rw-r--r-- | main/src/ui/manage_accounts/add_account_dialog.vala | 62 | ||||
-rw-r--r-- | main/src/ui/manage_accounts/dialog.vala | 230 |
3 files changed, 314 insertions, 0 deletions
diff --git a/main/src/ui/manage_accounts/account_row.vala b/main/src/ui/manage_accounts/account_row.vala new file mode 100644 index 00000000..5e4570f0 --- /dev/null +++ b/main/src/ui/manage_accounts/account_row.vala @@ -0,0 +1,22 @@ +using Gtk; + +using Dino.Entities; + +namespace Dino.Ui.ManageAccounts { + +[GtkTemplate (ui = "/org/dino-im/manage_accounts/account_row.ui")] +public class AccountRow : Gtk.ListBoxRow { + + [GtkChild] public Image image; + [GtkChild] public Label jid_label; + + public Account account; + + public AccountRow(StreamInteractor stream_interactor, Account account) { + this.account = account; + Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(40, 40, image.scale_factor)).draw_account(stream_interactor, account)); + jid_label.set_label(account.bare_jid.to_string()); + } +} + +}
\ No newline at end of file diff --git a/main/src/ui/manage_accounts/add_account_dialog.vala b/main/src/ui/manage_accounts/add_account_dialog.vala new file mode 100644 index 00000000..f6ad40a2 --- /dev/null +++ b/main/src/ui/manage_accounts/add_account_dialog.vala @@ -0,0 +1,62 @@ +using Gee; +using Gtk; + +using Dino.Entities; + +namespace Dino.Ui.ManageAccounts { + +[GtkTemplate (ui = "/org/dino-im/manage_accounts/add_account_dialog.ui")] +public class AddAccountDialog : Gtk.Dialog { + + public signal void added(Account account); + + [GtkChild] private Button cancel_button; + [GtkChild] private Button ok_button; + [GtkChild] private Entry alias_entry; + [GtkChild] private Entry jid_entry; + [GtkChild] private Entry password_entry; + + public AddAccountDialog(StreamInteractor stream_interactor) { + Object(use_header_bar : 1); + this.title = "Add Account"; + + cancel_button.clicked.connect(() => { close(); }); + ok_button.clicked.connect(on_ok_button_clicked); + jid_entry.changed.connect(on_jid_entry_changed); + jid_entry.focus_out_event.connect(on_jid_entry_focus_out_event); + } + + private void on_jid_entry_changed() { + Jid? jid = Jid.parse(jid_entry.text); + if (jid != null && jid.localpart != null && jid.resourcepart == null) { + ok_button.set_sensitive(true); + jid_entry.secondary_icon_name = null; + } else { + ok_button.set_sensitive(false); + } + } + + private bool on_jid_entry_focus_out_event() { + Jid? jid = Jid.parse(jid_entry.text); + if (jid == null || jid.localpart == null || jid.resourcepart != null) { + jid_entry.secondary_icon_name = "dialog-warning-symbolic"; + // TODO why doesn't the tooltip work + jid_entry.set_icon_tooltip_text(EntryIconPosition.SECONDARY, "JID should be of the form \"user@example.com\""); + } else { + jid_entry.secondary_icon_name = null; + } + return false; + } + + private void on_ok_button_clicked() { + Account account = new Account.from_bare_jid(jid_entry.get_text()); + account.resourcepart = "dino"; + account.alias = alias_entry.get_text(); + account.enabled = false; + account.password = password_entry.get_text(); + added(account); + close(); + } +} + +} diff --git a/main/src/ui/manage_accounts/dialog.vala b/main/src/ui/manage_accounts/dialog.vala new file mode 100644 index 00000000..3616c403 --- /dev/null +++ b/main/src/ui/manage_accounts/dialog.vala @@ -0,0 +1,230 @@ +using Gdk; +using Gee; +using Gtk; +using Markup; + +using Dino.Entities; + +namespace Dino.Ui.ManageAccounts { + +[GtkTemplate (ui = "/org/dino-im/manage_accounts/dialog.ui")] +public class Dialog : Gtk.Window { + + public signal void account_enabled(Account account); + public signal void account_disabled(Account account); + + [GtkChild] public Stack main_stack; + [GtkChild] public ListBox account_list; + [GtkChild] public Button no_accounts_add; + [GtkChild] public ToolButton add_button; + [GtkChild] public ToolButton remove_button; + [GtkChild] public Image image; + [GtkChild] public Button image_button; + [GtkChild] public Label jid_label; + [GtkChild] public Switch active_switch; + + [GtkChild] public Stack password_stack; + [GtkChild] public Label password_label; + [GtkChild] public Button password_button; + [GtkChild] public Entry password_entry; + + [GtkChild] public Stack alias_stack; + [GtkChild] public Label alias_label; + [GtkChild] public Button alias_button; + [GtkChild] public Entry alias_entry; + + [GtkChild] public Grid settings_list; + + private ArrayList<Plugins.AccountSettingsWidget> plugin_widgets = new ArrayList<Plugins.AccountSettingsWidget>(); + + private Database db; + private StreamInteractor stream_interactor; + + construct { + account_list.row_selected.connect(account_list_row_selected); + add_button.clicked.connect(add_button_clicked); + no_accounts_add.clicked.connect(add_button_clicked); + remove_button.clicked.connect(remove_button_clicked); + password_entry.key_release_event.connect(on_password_key_release_event); + alias_entry.key_release_event.connect(on_alias_key_release_event); + 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) { + this.db = db; + this.stream_interactor = stream_interactor; + foreach (Account account in db.get_accounts()) { + add_account(account); + } + + AvatarManager.get_instance(stream_interactor).received_avatar.connect((pixbuf, jid, account) => { + Idle.add(() => { + on_received_avatar(pixbuf, jid, account); + return false; + });}); + + if (account_list.get_row_at_index(0) != null) account_list.select_row(account_list.get_row_at_index(0)); + } + + public AccountRow add_account(Account account) { + AccountRow account_item = new AccountRow (stream_interactor, account); + account_list.add(account_item); + main_stack.set_visible_child_name("accounts_exist"); + return account_item; + } + + private void add_button_clicked() { + AddAccountDialog add_account_dialog = new AddAccountDialog(stream_interactor); + add_account_dialog.set_transient_for(this); + add_account_dialog.added.connect((account) => { + db.add_account(account); + AccountRow account_item = add_account(account); + account_list.select_row(account_item); + account_list.queue_draw(); + }); + add_account_dialog.show(); + } + + private void remove_button_clicked() { + AccountRow account_item = account_list.get_selected_row() as AccountRow; + if (account_item != null) { + account_list.remove(account_item); + account_list.queue_draw(); + if (account_item.account.enabled) account_disabled(account_item.account); + db.remove_account(account_item.account); + if (account_list.get_row_at_index(0) != null) { + account_list.select_row(account_list.get_row_at_index(0)); + } else { + main_stack.set_visible_child_name("no_accounts"); + } + } + } + + private void account_list_row_selected(ListBoxRow? row) { + AccountRow? account_item = row as AccountRow; + if (account_item != null) populate_grid_data(account_item.account); + } + + private void populate_grid_data(Account account) { + active_switch.state_set.disconnect(on_active_switch_state_changed); + + Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(50, 50, image.scale_factor)).draw_account(stream_interactor, account)); + active_switch.set_active(account.enabled); + jid_label.label = account.bare_jid.to_string(); + + string filler = ""; + for (int i = 0; i < account.password.length; i++) filler += password_entry.get_invisible_char().to_string(); + password_label.label = filler; + password_stack.set_visible_child_name("label"); + password_entry.text = account.password; + + alias_stack.set_visible_child_name("label"); + alias_label.label = account.alias; + alias_entry.text = account.alias; + + password_button.clicked.connect(() => { set_active_stack(password_stack); }); + alias_button.clicked.connect(() => { set_active_stack(alias_stack); }); + active_switch.state_set.connect(on_active_switch_state_changed); + + foreach(Plugins.AccountSettingsWidget widget in plugin_widgets) { + widget.set_account(account); + } + + child_activated(null); + } + + + private void on_image_button_clicked() { + FileChooserDialog chooser = new FileChooserDialog ( + "Select avatar", this, FileChooserAction.OPEN, + "Cancel", ResponseType.CANCEL, + "Select", ResponseType.ACCEPT); + FileFilter filter = new FileFilter(); + filter.add_mime_type("image/*"); + chooser.set_filter(filter); + if (chooser.run() == Gtk.ResponseType.ACCEPT) { + string uri = chooser.get_filename(); + Account account = (account_list.get_selected_row() as AccountRow).account; + AvatarManager.get_instance(stream_interactor).publish(account, uri); + } + chooser.close(); + } + + private bool on_active_switch_state_changed(bool state) { + Account account = (account_list.get_selected_row() as AccountRow).account; + account.enabled = state; + if (state) { + account_enabled(account); + } else { + account_disabled(account); + } + return false; + } + + private bool on_password_key_release_event(EventKey event) { + Account account = (account_list.get_selected_row() as AccountRow).account; + account.password = password_entry.text; + string filler = ""; + for (int i = 0; i < account.password.length; i++) filler += password_entry.get_invisible_char().to_string(); + password_label.label = filler; + if (event.keyval == Key.Return) { + password_stack.set_visible_child_name("label"); + } + return false; + } + + private bool on_alias_key_release_event(EventKey event) { + Account account = (account_list.get_selected_row() as AccountRow).account; + account.alias = alias_entry.text; + alias_label.label = alias_entry.text; + if (event.keyval == Key.Return) { + alias_stack.set_visible_child_name("label"); + } + return false; + } + + private void on_received_avatar(Pixbuf pixbuf, Jid jid, Account account) { + Account curr_account = (account_list.get_selected_row() as AccountRow).account; + if (curr_account.equals(account) && jid.equals(account.bare_jid)) { + Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(50, 50, image.scale_factor)).draw_account(stream_interactor, account)); + } + } + + 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"); + child_activated(stack); + } +} + +} + |