diff options
21 files changed, 197 insertions, 273 deletions
diff --git a/libdino/src/entity/conversation.vala b/libdino/src/entity/conversation.vala index d4f2f7a7..40bff1c2 100644 --- a/libdino/src/entity/conversation.vala +++ b/libdino/src/entity/conversation.vala @@ -26,7 +26,7 @@ public class Conversation : Object { } public Encryption encryption { get; set; default = Encryption.NONE; } public Type type_ { get; set; } - public Message read_up_to { get; set; } + public Message? read_up_to { get; set; } public enum NotifySetting { DEFAULT, ON, OFF, HIGHLIGHT } public NotifySetting notify_setting { get; set; default = NotifySetting.DEFAULT; } @@ -157,4 +157,4 @@ public class Conversation : Object { } } -}
\ No newline at end of file +} diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala index ae8d5412..333c599b 100644 --- a/libdino/src/service/database.vala +++ b/libdino/src/service/database.vala @@ -122,12 +122,12 @@ public class Database : Qlite.Database { public class RosterTable : Table { public Column<int> account_id = new Column.Integer("account_id"); public Column<string> jid = new Column.Text("jid"); - public Column<string> name = new Column.Text("name"); + public Column<string> handle = new Column.Text("name"); public Column<string> subscription = new Column.Text("subscription"); internal RosterTable(Database db) { base(db, "roster"); - init({account_id, jid, name, subscription}); + init({account_id, jid, handle, subscription}); unique({account_id, jid}, "IGNORE"); } } @@ -333,4 +333,4 @@ public class Database : Qlite.Database { } } -}
\ No newline at end of file +} diff --git a/libdino/src/service/muc_manager.vala b/libdino/src/service/muc_manager.vala index c6f37116..7761373f 100644 --- a/libdino/src/service/muc_manager.vala +++ b/libdino/src/service/muc_manager.vala @@ -134,6 +134,11 @@ public class MucManager : StreamInteractionModule, Object { } } + public string? get_room_name(Account account, Jid jid) { + Core.XmppStream? stream = stream_interactor.get_stream(account); + return stream != null ? stream.get_flag(Xep.Muc.Flag.IDENTITY).get_room_name(jid.to_string()) : null; + } + public string? get_groupchat_subject(Jid jid, Account account) { Core.XmppStream? stream = stream_interactor.get_stream(account); if (stream != null) { diff --git a/libdino/src/service/roster_manager.vala b/libdino/src/service/roster_manager.vala index e17c24e3..51a64625 100644 --- a/libdino/src/service/roster_manager.vala +++ b/libdino/src/service/roster_manager.vala @@ -49,6 +49,11 @@ public class RosterManager : StreamInteractionModule, Object { if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).add_jid(stream, jid.bare_jid.to_string(), handle); } + public void set_jid_handle(Account account, Jid jid, string? handle) { + Core.XmppStream? stream = stream_interactor.get_stream(account); + if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).set_jid_handle(stream, jid.bare_jid.to_string(), handle); + } + private void on_account_added(Account account) { stream_interactor.module_manager.get_module(account, Roster.Module.IDENTITY).received_roster.connect( (stream, roster) => { foreach (Roster.Item roster_item in roster) { @@ -81,7 +86,7 @@ public class RosterStoreImpl : Roster.Storage, Object { foreach (Qlite.Row row in db.roster.select().with(db.roster.account_id, "=", account.id)) { Roster.Item item = new Roster.Item(); item.jid = row[db.roster.jid]; - item.name = row[db.roster.name]; + item.name = row[db.roster.handle]; item.subscription = row[db.roster.subscription]; items[item.jid] = item; } @@ -115,7 +120,7 @@ public class RosterStoreImpl : Roster.Storage, Object { db.roster.insert().or("REPLACE") .value(db.roster.account_id, account.id) .value(db.roster.jid, item.jid) - .value(db.roster.name, item.name) + .value(db.roster.handle, item.name) .value(db.roster.subscription, item.subscription) .perform(); } @@ -128,4 +133,4 @@ public class RosterStoreImpl : Roster.Storage, Object { } } -}
\ No newline at end of file +} diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 1d0364c4..60bfd517 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -150,4 +150,4 @@ install(FILES data/icons/dino-tick-symbolic.svg DESTINATION ${ICON_INSTALL_DIR}/hicolor/scalable/status -)
\ No newline at end of file +) diff --git a/main/data/add_conversation/select_jid_fragment.ui b/main/data/add_conversation/select_jid_fragment.ui index 6384edb0..76744ad0 100644 --- a/main/data/add_conversation/select_jid_fragment.ui +++ b/main/data/add_conversation/select_jid_fragment.ui @@ -69,19 +69,6 @@ </object> </child> <child> - <object class="GtkButton" id="edit_button"> - <property name="sensitive">False</property> - <property name="visible">True</property> - <child> - <object class="GtkImage"> - <property name="icon-name">document-edit-symbolic</property> - <property name="icon-size">1</property> - <property name="visible">True</property> - </object> - </child> - </object> - </child> - <child> <object class="GtkButton" id="remove_button"> <property name="sensitive">False</property> <property name="visible">True</property> @@ -105,4 +92,4 @@ </object> </child> </template> -</interface>
\ No newline at end of file +</interface> diff --git a/main/data/contact_details_dialog.ui b/main/data/contact_details_dialog.ui index 5b074650..217a8b32 100644 --- a/main/data/contact_details_dialog.ui +++ b/main/data/contact_details_dialog.ui @@ -30,7 +30,7 @@ <property name="margin-bottom">12</property> <property name="margin-right">100</property> <property name="margin-left">100</property> - <property name="column-spacing">15</property> + <property name="column-spacing">10</property> <property name="visible">True</property> <child> <object class="GtkImage" id="avatar"> @@ -46,6 +46,19 @@ </packing> </child> <child> + <object class="DinoUiUtilEntryLabelHybrid" id="name_hybrid"> + <property name="xalign">0</property> + <property name="expand">True</property> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> <object class="GtkLabel" id="name_label"> <property name="xalign">0</property> <property name="expand">True</property> diff --git a/main/data/manage_accounts/dialog.ui b/main/data/manage_accounts/dialog.ui index 616d0503..2ad3a6bc 100644 --- a/main/data/manage_accounts/dialog.ui +++ b/main/data/manage_accounts/dialog.ui @@ -64,13 +64,13 @@ <property name="toolbar-style">icons</property> <property name="visible">True</property> <child> - <object class="GtkToolButton" id="add_button"> + <object class="GtkToolButton" id="add_account_button"> <property name="icon-name">list-add-symbolic</property> <property name="visible">True</property> </object> </child> <child> - <object class="GtkToolButton" id="remove_button"> + <object class="GtkToolButton" id="remove_account_button"> <property name="icon-name">list-remove-symbolic</property> <property name="visible">True</property> </object> @@ -178,35 +178,11 @@ </packing> </child> <child> - <object class="GtkStack" id="password_stack"> + <object class="DinoUiUtilEntryLabelHybrid" id="password_hybrid"> + <property name="xalign">0</property> + <property name="width_request">200</property> + <property name="visibility">False</property> <property name="visible">True</property> - <child> - <object class="GtkButton" id="password_button"> - <property name="relief">none</property> - <property name="visible">True</property> - <child> - <object class="GtkLabel" id="password_label"> - <property name="xalign">0</property> - <property name="visible">True</property> - </object> - </child> - </object> - <packing> - <property name="name">label</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="password_entry"> - <property name="hexpand">True</property> - <property name="input_purpose">password</property> - <property name="width_request">200</property> - <property name="visible">True</property> - <property name="visibility">False</property> - </object> - <packing> - <property name="name">entry</property> - </packing> - </child> </object> <packing> <property name="left_attach">1</property> @@ -232,33 +208,10 @@ </packing> </child> <child> - <object class="GtkStack" id="alias_stack"> + <object class="DinoUiUtilEntryLabelHybrid" id="alias_hybrid"> + <property name="xalign">0</property> + <property name="width_request">200</property> <property name="visible">True</property> - <child> - <object class="GtkButton" id="alias_button"> - <property name="relief">none</property> - <property name="visible">True</property> - <child> - <object class="GtkLabel" id="alias_label"> - <property name="xalign">0</property> - <property name="visible">True</property> - </object> - </child> - </object> - <packing> - <property name="name">label</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="alias_entry"> - <property name="hexpand">True</property> - <property name="width_request">200</property> - <property name="visible">True</property> - </object> - <packing> - <property name="name">entry</property> - </packing> - </child> </object> <packing> <property name="left_attach">1</property> diff --git a/main/src/main.vala b/main/src/main.vala index e0d54d18..ce633e30 100644 --- a/main/src/main.vala +++ b/main/src/main.vala @@ -48,4 +48,4 @@ void main(string[] args) { } } -}
\ No newline at end of file +} diff --git a/main/src/ui/add_conversation/chat/dialog.vala b/main/src/ui/add_conversation/chat/dialog.vala index ee535f09..4b618bc5 100644 --- a/main/src/ui/add_conversation/chat/dialog.vala +++ b/main/src/ui/add_conversation/chat/dialog.vala @@ -60,9 +60,6 @@ public class Dialog : Gtk.Dialog { add_contact_dialog.set_transient_for(this); add_contact_dialog.present(); }); - select_jid_fragment.edit_jid.connect(() => { - - }); select_jid_fragment.remove_jid.connect((row) => { ListRow list_row = roster_list.get_selected_row() as ListRow; stream_interactor.get_module(RosterManager.IDENTITY).remove_jid(list_row.account, list_row.jid); @@ -74,4 +71,4 @@ public class Dialog : Gtk.Dialog { } } -}
\ No newline at end of file +} diff --git a/main/src/ui/add_conversation/conference/dialog.vala b/main/src/ui/add_conversation/conference/dialog.vala index 9674cef2..10d6e535 100644 --- a/main/src/ui/add_conversation/conference/dialog.vala +++ b/main/src/ui/add_conversation/conference/dialog.vala @@ -94,12 +94,6 @@ public class Dialog : Gtk.Dialog { dialog.set_transient_for(this); dialog.present(); }); - select_fragment.edit_jid.connect((row) => { - ConferenceListRow conference_row = row as ConferenceListRow; - AddGroupchatDialog dialog = new AddGroupchatDialog.for_conference(stream_interactor, conference_row.account, conference_row.bookmark); - dialog.set_transient_for(this); - dialog.present(); - }); select_fragment.remove_jid.connect((row) => { ConferenceListRow conference_row = row as ConferenceListRow; stream_interactor.get_module(MucManager.IDENTITY).remove_bookmark(conference_row.account, conference_row.bookmark); @@ -165,4 +159,4 @@ public class Dialog : Gtk.Dialog { } } -}
\ No newline at end of file +} diff --git a/main/src/ui/add_conversation/select_jid_fragment.vala b/main/src/ui/add_conversation/select_jid_fragment.vala index 71314235..9e0c4067 100644 --- a/main/src/ui/add_conversation/select_jid_fragment.vala +++ b/main/src/ui/add_conversation/select_jid_fragment.vala @@ -9,7 +9,6 @@ namespace Dino.Ui.AddConversation { public class SelectJidFragment : Gtk.Box { public signal void add_jid(); - public signal void edit_jid(ListRow row); public signal void remove_jid(ListRow row); public bool done { get { @@ -20,7 +19,6 @@ public class SelectJidFragment : Gtk.Box { [GtkChild] private Entry entry; [GtkChild] private Box box; [GtkChild] private Button add_button; - [GtkChild] private Button edit_button; [GtkChild] private Button remove_button; private StreamInteractor stream_interactor; @@ -45,7 +43,6 @@ public class SelectJidFragment : Gtk.Box { entry.changed.connect(on_entry_changed); add_button.clicked.connect(() => { add_jid(); }); remove_button.clicked.connect(() => { remove_jid(filterable_list.get_selected_row() as ListRow); }); - edit_button.clicked.connect(() => { edit_jid(filterable_list.get_selected_row() as ListRow); }); } private void on_entry_changed() { @@ -71,7 +68,6 @@ public class SelectJidFragment : Gtk.Box { private void check_buttons_active() { ListBoxRow? row = filterable_list.get_selected_row(); bool active = row != null && !row.get_type().is_a(typeof(AddListRow)); - edit_button.sensitive = active; remove_button.sensitive = active; } @@ -115,4 +111,4 @@ public abstract class FilterableList : Gtk.ListBox { public abstract int sort(ListBoxRow row1, ListBoxRow row2); } -}
\ No newline at end of file +} diff --git a/main/src/ui/contact_details/dialog.vala b/main/src/ui/contact_details/dialog.vala index 7e2f6100..a5b8ea38 100644 --- a/main/src/ui/contact_details/dialog.vala +++ b/main/src/ui/contact_details/dialog.vala @@ -1,6 +1,7 @@ using Gee; using Gtk; using Markup; +using Pango; using Dino.Entities; @@ -10,6 +11,7 @@ namespace Dino.Ui.ContactDetails { public class Dialog : Gtk.Dialog { [GtkChild] public Image avatar; + [GtkChild] public Util.EntryLabelHybrid name_hybrid; [GtkChild] public Label name_label; [GtkChild] public Label jid_label; [GtkChild] public Label account_label; @@ -22,6 +24,11 @@ public class Dialog : Gtk.Dialog { private HashMap<string, ListBox> categories = new HashMap<string, ListBox>(); private Util.LabelHybridGroup hybrid_group = new Util.LabelHybridGroup(); + construct { + name_hybrid.label.attributes = new AttrList(); + name_hybrid.label.attributes.insert(attr_weight_new(Weight.BOLD)); + } + public Dialog(StreamInteractor stream_interactor, Conversation conversation) { Object(use_header_bar : 1); this.stream_interactor = stream_interactor; @@ -29,11 +36,7 @@ public class Dialog : Gtk.Dialog { title = conversation.type_ == Conversation.Type.GROUPCHAT ? _("Conference Details") : _("Contact Details"); (get_header_bar() as HeaderBar).set_subtitle(Util.get_conversation_display_name(stream_interactor, conversation)); - - name_label.label = Util.get_conversation_display_name(stream_interactor, conversation); - jid_label.label = conversation.counterpart.to_string(); - account_label.label = "via " + conversation.account.bare_jid.to_string(); - Util.image_set_from_scaled_pixbuf(avatar, (new AvatarGenerator(50, 50, avatar.scale_factor)).draw_conversation(stream_interactor, conversation)); + setup_top(); contact_details.add.connect(add_entry); @@ -50,7 +53,26 @@ public class Dialog : Gtk.Dialog { }); } - public void add_entry(string category, string label, string? description, Widget w) { + private void setup_top() { + if (conversation.type_ == Conversation.Type.CHAT) { + name_label.visible = false; + jid_label.set_padding(new Button().get_style_context().get_padding(StateFlags.NORMAL).left + 1, 0); + name_hybrid.text = Util.get_conversation_display_name(stream_interactor, conversation); + destroy.connect(() => { + if (name_hybrid.text != Util.get_conversation_display_name(stream_interactor, conversation)) { + stream_interactor.get_module(RosterManager.IDENTITY).set_jid_handle(conversation.account, conversation.counterpart, name_hybrid.text); + } + }); + } else { + name_hybrid.visible = false; + name_label.label = Util.get_conversation_display_name(stream_interactor, conversation); + } + jid_label.label = conversation.counterpart.to_string(); + account_label.label = "via " + conversation.account.bare_jid.to_string(); + Util.image_set_from_scaled_pixbuf(avatar, (new AvatarGenerator(50, 50, avatar.scale_factor)).draw_conversation(stream_interactor, conversation)); + } + + private void add_entry(string category, string label, string? description, Widget w) { add_category(category); ListBoxRow list_row = new ListBoxRow() { activatable=false, visible=true }; @@ -71,11 +93,11 @@ public class Dialog : Gtk.Dialog { Widget widget = w; if (widget.get_type().is_a(typeof(Entry))) { - Util.EntryLabelHybrid hybrid = new Util.EntryLabelHybrid(widget as Entry) { xalign=1, visible=true }; + Util.EntryLabelHybrid hybrid = new Util.EntryLabelHybrid.wrap(widget as Entry) { xalign=1, visible=true }; hybrid_group.add(hybrid); widget = hybrid; } else if (widget.get_type().is_a(typeof(ComboBoxText))) { - Util.ComboBoxTextLabelHybrid hybrid = new Util.ComboBoxTextLabelHybrid(widget as ComboBoxText) { xalign=1, visible=true }; + Util.ComboBoxTextLabelHybrid hybrid = new Util.ComboBoxTextLabelHybrid.wrap(widget as ComboBoxText) { xalign=1, visible=true }; hybrid_group.add(hybrid); widget = hybrid; } @@ -95,7 +117,7 @@ public class Dialog : Gtk.Dialog { }); } - public void add_category(string category) { + private void add_category(string category) { if (!categories.has_key(category)) { ListBox list_box = new ListBox() { selection_mode=SelectionMode.NONE, visible=true }; categories[category] = list_box; diff --git a/main/src/ui/manage_accounts/dialog.vala b/main/src/ui/manage_accounts/dialog.vala index 6a474e67..c4324b75 100644 --- a/main/src/ui/manage_accounts/dialog.vala +++ b/main/src/ui/manage_accounts/dialog.vala @@ -16,24 +16,15 @@ public class Dialog : Gtk.Dialog { [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 ToolButton add_account_button; + [GtkChild] public ToolButton remove_account_button; [GtkChild] public Image image; [GtkChild] public Button image_button; [GtkChild] public Label jid_label; [GtkChild] public Label state_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 Util.EntryLabelHybrid password_hybrid; + [GtkChild] public Util.EntryLabelHybrid alias_hybrid; [GtkChild] public Grid settings_list; private ArrayList<Plugins.AccountSettingsWidget> plugin_widgets = new ArrayList<Plugins.AccountSettingsWidget>(); @@ -45,12 +36,19 @@ public class Dialog : Gtk.Dialog { construct { Util.force_error_color(state_label, ".is_error"); account_list.row_selected.connect(on_account_list_row_selected); - add_button.clicked.connect(on_add_button_clicked); - no_accounts_add.clicked.connect(on_add_button_clicked); - remove_button.clicked.connect(on_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); + add_account_button.clicked.connect(show_add_account_dialog); + no_accounts_add.clicked.connect(show_add_account_dialog); + remove_account_button.clicked.connect(() => { + AccountRow? account_row = account_list.get_selected_row() as AccountRow; + if (selected_account != null) remove_account(account_row); + }); + image_button.clicked.connect(show_select_avatar); + alias_hybrid.entry.key_release_event.connect(() => { selected_account.alias = alias_hybrid.text; return false; }); + password_hybrid.entry.key_release_event.connect(() => { selected_account.password = password_hybrid.text; return false; }); + + Util.LabelHybridGroup label_hybrid_group = new Util.LabelHybridGroup(); + label_hybrid_group.add(alias_hybrid); + label_hybrid_group.add(password_hybrid); main_stack.set_visible_child_name("no_accounts"); @@ -61,13 +59,11 @@ public class Dialog : Gtk.Dialog { 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 label = new Label(e.name) { xalign=1, yalign=0, visible=true }; 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++; @@ -111,7 +107,7 @@ public class Dialog : Gtk.Dialog { return account_item; } - private void on_add_button_clicked() { + private void show_add_account_dialog() { AddAccountDialog add_account_dialog = new AddAccountDialog(stream_interactor); add_account_dialog.set_transient_for(this); add_account_dialog.added.connect((account) => { @@ -123,18 +119,15 @@ public class Dialog : Gtk.Dialog { add_account_dialog.present(); } - private void on_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); - account_item.account.remove(); - 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 remove_account(AccountRow account_item) { + account_list.remove(account_item); + account_list.queue_draw(); + if (account_item.account.enabled) account_disabled(account_item.account); + account_item.account.remove(); + 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"); } } @@ -146,59 +139,34 @@ public class Dialog : Gtk.Dialog { } } - private void on_image_button_clicked() { + private void show_select_avatar() { FileChooserDialog chooser = new FileChooserDialog ( - _("Select avatar"), this, FileChooserAction.OPEN, - _("Cancel"), ResponseType.CANCEL, - _("Select"), ResponseType.ACCEPT); + _("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; - stream_interactor.get_module(AvatarManager.IDENTITY).publish(account, uri); + stream_interactor.get_module(AvatarManager.IDENTITY).publish(selected_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; + selected_account.enabled = state; if (state) { - if (account.enabled) account_disabled(account); - account_enabled(account); + if (selected_account.enabled) account_disabled(selected_account); + account_enabled(selected_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"); + account_disabled(selected_account); } 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)) { + if (selected_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)); } } @@ -210,27 +178,17 @@ public class Dialog : Gtk.Dialog { 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; + alias_hybrid.text = account.alias; + password_hybrid.entry.input_purpose = InputPurpose.PASSWORD; + password_hybrid.text = account.password; update_status_label(account); - 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 update_status_label(Account account) { @@ -259,20 +217,6 @@ public class Dialog : Gtk.Dialog { } } - 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); - } - private string get_connection_error_description(ConnectionManager.ConnectionError error) { switch (error.source) { case ConnectionManager.ConnectionError.Source.SASL: @@ -287,4 +231,3 @@ public class Dialog : Gtk.Dialog { } } - diff --git a/main/src/ui/util/helper.vala b/main/src/ui/util/helper.vala index c65acfc9..d493def2 100644 --- a/main/src/ui/util/helper.vala +++ b/main/src/ui/util/helper.vala @@ -118,4 +118,4 @@ public static bool is_24h_format() { return settings_format == "24h" || p_format == " "; } -}
\ No newline at end of file +} diff --git a/main/src/ui/util/label_hybrid.vala b/main/src/ui/util/label_hybrid.vala index 4486f25b..a16bccf7 100644 --- a/main/src/ui/util/label_hybrid.vala +++ b/main/src/ui/util/label_hybrid.vala @@ -8,7 +8,7 @@ public class LabelHybrid : Stack { public Label label = new Label("") { visible=true }; protected Button button = new Button() { relief=ReliefStyle.NONE, visible=true }; - public void init(Widget widget) { + internal virtual void init(Widget widget) { button.add(label); add_named(button, "label"); add_named(widget, "widget"); @@ -33,7 +33,13 @@ public class EntryLabelHybrid : LabelHybrid { get { return entry.text; } set { entry.text = value; - label.label = value; + if (visibility) { + label.label = value; + } else { + string filler = ""; + for (int i = 0; i < value.length; i++) filler += entry.get_invisible_char().to_string(); + label.label = filler; + } } } @@ -50,11 +56,26 @@ public class EntryLabelHybrid : LabelHybrid { } } - private Entry entry; + private Entry? entry_; + public Entry entry { + get { + if (entry_ == null) { + entry_ = new Entry() { visible=true }; + init(entry_); + } + return entry_; + } + set { entry_ = value; } + } + + public EntryLabelHybrid.wrap(Entry e) { + init(e); + } - public EntryLabelHybrid(Entry? e = null) { - entry = e ?? new Entry() { visible=true }; - init(entry); + internal override void init(Widget widget) { + Entry? e = widget as Entry; if (e == null) return; + entry = e; + base.init(entry); update_label(); entry.key_release_event.connect((event) => { @@ -84,11 +105,29 @@ public class ComboBoxTextLabelHybrid : LabelHybrid { set { label.xalign = value; } } - private ComboBoxText combobox; + private ComboBoxText combobox_; + public ComboBoxText combobox { + get { + if (combobox_ == null) { + combobox_ = new ComboBoxText() { visible=true }; + init(combobox_); + } + return combobox_; + } + set { combobox_ = combobox; } + } - public ComboBoxTextLabelHybrid(ComboBoxText? cb = null) { - combobox = cb ?? new ComboBoxText() { visible=true }; - init(combobox); + public ComboBoxTextLabelHybrid.wrap(ComboBoxText cb) { + combobox_ = cb; + init(cb); + } + + public void append(string id, string text) { combobox.append(id, text); } + public string get_active_text() { return combobox.get_active_text(); } + + internal override void init(Widget widget) { + ComboBoxText? combobox = widget as ComboBoxText; if (combobox == null) return; + base.init(combobox); update_label(); combobox.changed.connect(() => { @@ -100,9 +139,6 @@ public class ComboBoxTextLabelHybrid : LabelHybrid { }); } - public void append(string id, string text) { combobox.append(id, text); } - public string get_active_text() { return combobox.get_active_text(); } - private void update_label() { label.label = combobox.get_active_text(); } @@ -126,4 +162,4 @@ public class LabelHybridGroup { } } -}
\ No newline at end of file +} diff --git a/plugins/openpgp/src/account_settings_widget.vala b/plugins/openpgp/src/account_settings_widget.vala index 77121352..9c21f967 100644 --- a/plugins/openpgp/src/account_settings_widget.vala +++ b/plugins/openpgp/src/account_settings_widget.vala @@ -143,4 +143,4 @@ private class AccountSettingsWidget : Stack, Plugins.AccountSettingsWidget { } } -}
\ No newline at end of file +} diff --git a/xmpp-vala/src/module/roster/module.vala b/xmpp-vala/src/module/roster/module.vala index e0d8aeb3..4c1028fb 100644 --- a/xmpp-vala/src/module/roster/module.vala +++ b/xmpp-vala/src/module/roster/module.vala @@ -38,13 +38,11 @@ public class Module : XmppStreamModule, Iq.Handler { * @param handle Handle to be set. If null, any handle will be removed. */ public void set_jid_handle(XmppStream stream, string jid, string? handle) { - Item roster_item = new Item(); - roster_item.jid = jid; - if (handle != null) { - roster_item.name = handle; - } + Flag flag = stream.get_flag(Flag.IDENTITY); + Item item = flag.get_item(jid) ?? new Item() { jid=jid }; + item.name = handle != null ? handle : ""; - roster_set(stream, roster_item); + roster_set(stream, item); } public void on_iq_set(XmppStream stream, Iq.Stanza iq) { diff --git a/xmpp-vala/src/module/util.vala b/xmpp-vala/src/module/util.vala index a0621225..365170b0 100644 --- a/xmpp-vala/src/module/util.vala +++ b/xmpp-vala/src/module/util.vala @@ -20,44 +20,4 @@ namespace Xmpp { uint32 b5_2 = Random.next_int(); return "%08x-%04x-%04x-%04x-%04x%08x".printf(b1, b2, b3, b4, b5_1, b5_2); } - - public class Tuple<A,B> : Object { - public A a { get; private set; } - public B b { get; private set; } - - public Tuple(A a, B b) { - this.a = a; - this.b = b; - } - - public static Tuple<A,B> create<A,B>(A a, B b) { - return new Tuple<A,B>(a,b); - } - } - - public class Triple<A,B,C> : Tuple<A,B> { - public C c { get; private set; } - - public Triple(A a, B b, C c) { - base(a, b); - this.c = c; - } - - public static new Triple<A,B,C> create<A,B,C>(A a, B b, C c) { - return new Triple<A,B,C>(a, b, c); - } - } - - public class Quadruple<A,B,C,D> : Triple<A,B,C> { - public D d { get; private set; } - - public Quadruple(A a, B b, C c, D d) { - base (a, b, c); - this.d = d; - } - - public static new Quadruple<A,B,C,D> create<A,B,C,D>(A a, B b, C c, D d) { - return new Quadruple<A,B,C,D>(a, b, c, d); - } - } -}
\ No newline at end of file +} diff --git a/xmpp-vala/src/module/xep/0045_muc/flag.vala b/xmpp-vala/src/module/xep/0045_muc/flag.vala index cf729bf9..00383407 100644 --- a/xmpp-vala/src/module/xep/0045_muc/flag.vala +++ b/xmpp-vala/src/module/xep/0045_muc/flag.vala @@ -8,6 +8,7 @@ public class Flag : XmppStreamFlag { public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "muc"); private HashMap<string, Gee.List<Feature>> room_features = new HashMap<string, Gee.List<Feature>>(); + private HashMap<string, string> room_names = new HashMap<string, string>(); private HashMap<string, string> enter_ids = new HashMap<string, string>(); private HashMap<string, string> own_nicks = new HashMap<string, string>(); @@ -18,6 +19,8 @@ public class Flag : XmppStreamFlag { private HashMap<string, HashMap<string, Affiliation>> affiliations = new HashMap<string, HashMap<string, Affiliation>>(); private HashMap<string, Role> occupant_role = new HashMap<string, Role>(); + public string? get_room_name(string jid) { return room_names.has_key(jid) ? room_names[jid] : null; } + public bool has_room_feature(string jid, Feature feature) { return room_features.has_key(jid) && room_features[jid].contains(feature); } @@ -59,6 +62,10 @@ public class Flag : XmppStreamFlag { public string? get_muc_subject(string bare_jid) { return subjects[bare_jid]; } + internal void set_room_name(string jid, string name) { + room_names[jid] = name; + } + internal void set_room_features(string jid, Gee.List<Feature> features) { room_features[jid] = features; } @@ -121,4 +128,4 @@ public class Flag : XmppStreamFlag { internal override string get_id() { return IDENTITY.id; } } -}
\ No newline at end of file +} diff --git a/xmpp-vala/src/module/xep/0045_muc/module.vala b/xmpp-vala/src/module/xep/0045_muc/module.vala index 82a7d7a6..951ec7d1 100644 --- a/xmpp-vala/src/module/xep/0045_muc/module.vala +++ b/xmpp-vala/src/module/xep/0045_muc/module.vala @@ -10,6 +10,7 @@ private const string NS_URI_OWNER = NS_URI + "#owner"; private const string NS_URI_USER = NS_URI + "#user"; public enum MucEnterError { + NONE, PASSWORD_REQUIRED, BANNED, ROOM_DOESNT_EXIST, @@ -64,7 +65,7 @@ public class Module : XmppStreamModule { public signal void room_configuration_changed(XmppStream stream, string jid, StatusCode code); public signal void room_entered(XmppStream stream, string jid, string nick); - public signal void room_enter_error(XmppStream stream, string jid, MucEnterError error); + public signal void room_enter_error(XmppStream stream, string jid, MucEnterError? error); // TODO "?" shoudln't be necessary (vala bug), remove someday public signal void self_removed_from_room(XmppStream stream, string jid, StatusCode code); public signal void removed_from_room(XmppStream stream, string jid, StatusCode? code); @@ -213,7 +214,7 @@ public class Module : XmppStreamModule { string bare_jid = get_bare_jid(presence.from); ErrorStanza? error_stanza = presence.get_error(); if (flag.get_enter_id(bare_jid) == presence.id) { - MucEnterError? error = null; + MucEnterError error = MucEnterError.NONE; switch (error_stanza.condition) { case ErrorStanza.CONDITION_NOT_AUTHORIZED: if (ErrorStanza.TYPE_AUTH == error_stanza.type_) error = MucEnterError.PASSWORD_REQUIRED; @@ -240,7 +241,7 @@ public class Module : XmppStreamModule { if (ErrorStanza.TYPE_CANCEL == error_stanza.type_) error = MucEnterError.USE_RESERVED_ROOMNICK; break; } - if (error != null) room_enter_error(stream, bare_jid, error); + if (error != MucEnterError.NONE) room_enter_error(stream, bare_jid, error); flag.finish_muc_enter(bare_jid); } } @@ -312,6 +313,13 @@ public class Module : XmppStreamModule { Gee.List<Feature> features = new ArrayList<Feature>(); if (query_result != null) { + + foreach (ServiceDiscovery.Identity identity in query_result.identities) { + if (identity.category == "conference") { + stream.get_flag(Flag.IDENTITY).set_room_name(jid, identity.name); + } + } + foreach (string feature in query_result.features) { Feature? parsed = null; switch (feature) { |