Daniel Brötzmann pushed to branch new-chat-menu at gajim / gajim
Commits: c28bf8bf by Philipp Hörist at 2023-04-05T20:36:49+02:00 ci: Debian: Raise nbxmpp-nightly version
- - - - - 3bb3865b by wurstsalat at 2023-04-07T23:59:35+02:00 change: Move chat menu to chat banner
- - - - - 40b6b3d0 by wurstsalat at 2023-04-07T23:59:35+02:00 change: GroupChatRoster: Include invite button and add search bar
- - - - - e94865b3 by wurstsalat at 2023-04-07T23:59:35+02:00 imprv: ChatBanner: Add share button
- - - - - 080b0b3e by wurstsalat at 2023-04-07T23:59:35+02:00 imprv: ChatBanner: Add Contact Info button
- - - - - c4f0095b by wurstsalat at 2023-04-07T23:59:35+02:00 imprv: ChatBanner: Unify button style
- - - - - b20d6246 by wurstsalat at 2023-04-07T23:59:35+02:00 imprv: ChatBanner: Add search button
- - - - - 7325ada8 by wurstsalat at 2023-04-07T23:59:35+02:00 imprv: ChatBanner: Add group chat description
- - - - - 6c93ddd3 by wurstsalat at 2023-04-07T23:59:35+02:00 imprv: Control: Use Gtk.Paned for group chat roster
Fixes #10362
- - - - -
12 changed files:
- debian/control - gajim/data/gui/chat_banner.ui - gajim/data/gui/chat_control.ui - gajim/data/gui/groupchat_roster.ui - gajim/data/gui/message_actions_box.ui - gajim/data/style/gajim.css - gajim/gtk/builder.pyi - gajim/gtk/chat_banner.py - gajim/gtk/control.py - gajim/gtk/groupchat_roster.py - gajim/gtk/menus.py - gajim/gtk/message_actions_box.py
Changes:
===================================== debian/control ===================================== @@ -12,7 +12,7 @@ Build-Depends: python3-css-parser, python3-gi, python3-gi-cairo, - python3-nbxmpp-nightly (>=20230206), + python3-nbxmpp-nightly (>=20230405), python3-setuptools, python3-packaging, python3-cryptography (>=3.4.8), @@ -34,7 +34,7 @@ Depends: python3 (>= 3.10), python3-gi (>= 3.42.0), python3-gi-cairo (>= 1.14.0~), - python3-nbxmpp-nightly (>=20230123), + python3-nbxmpp-nightly (>=20230405), gir1.2-pango-1.0 (>= 1.50.0), gir1.2-gtk-3.0 (>= 3.24.30), gir1.2-gtksource-4,
===================================== gajim/data/gui/chat_banner.ui ===================================== @@ -2,6 +2,70 @@ <!-- Generated with glade 3.40.0 --> <interface> <requires lib="gtk+" version="3.24"/> + <object class="GtkPopover" id="share_popover"> + <property name="can-focus">False</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkLabel" id="jid_label"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="justify">center</property> + <property name="wrap">True</property> + <property name="wrap-mode">word-char</property> + <property name="max-width-chars">30</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="tooltip-text" translatable="yes">Copy to clipboard</property> + <property name="valign">center</property> + <signal name="clicked" handler="_on_copy_jid_clicked" swapped="no"/> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">edit-copy-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <style> + <class name="padding-12"/> + </style> + </object> + </child> + </object> <object class="GtkBox" id="banner_box"> <property name="visible">True</property> <property name="can-focus">False</property> @@ -23,51 +87,39 @@ <property name="can-focus">False</property> <property name="spacing">12</property> <child> - <object class="GtkBox"> + <object class="GtkSeparator"> <property name="visible">True</property> <property name="can-focus">False</property> + <property name="margin-top">12</property> + <property name="margin-bottom">12</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkMenuButton" id="chat_menu_button"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> <property name="valign">center</property> - <property name="orientation">vertical</property> - <property name="spacing">3</property> + <property name="margin-end">6</property> <child> - <object class="GtkLabel" id="name_label"> + <object class="GtkImage"> <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="selectable">True</property> - <property name="halign">start</property> - <property name="hexpand">True</property> - <property name="ellipsize">end</property> - <property name="single-line-mode">True</property> - <property name="xalign">0</property> - <style> - <class name="large-header"/> - </style> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkImage" id="phone_image"> <property name="can-focus">False</property> - <property name="no-show-all">True</property> - <property name="tooltip-text" translatable="yes">The last message was written on a mobile client</property> - <property name="halign">start</property> - <property name="margin-end">4</property> - <property name="icon-name">phone-apple-iphone-symbolic</property> + <property name="icon-name">view-more-symbolic</property> </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> + <property name="pack-type">end</property> <property name="position">0</property> </packing> </child> @@ -78,7 +130,6 @@ <property name="no-show-all">True</property> <property name="tooltip-text" translatable="yes">Toggle participants list</property> <property name="valign">center</property> - <property name="relief">none</property> <signal name="clicked" handler="_on_toggle_roster_clicked" swapped="no"/> <child> <object class="GtkBox"> @@ -109,20 +160,163 @@ <property name="position">1</property> </packing> </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkButton" id="contact_info_button"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="tooltip-text" translatable="yes">Contact Details and Settings</property> + <property name="valign">center</property> + <property name="action-name">win.show-contact-info</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">user-info-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="tooltip-text" translatable="yes">Search…</property> + <property name="valign">center</property> + <property name="action-name">win.search-history</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">system-search-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">4</property> + </packing> + </child> + <child> + <object class="GtkMenuButton" id="share_menu_button"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="tooltip-text" translatable="yes">Share Contact…</property> + <property name="valign">center</property> + <property name="popover">share_popover</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">emblem-shared-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">5</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="valign">center</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel" id="name_label"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="halign">start</property> + <property name="hexpand">True</property> + <property name="selectable">True</property> + <property name="ellipsize">end</property> + <property name="single-line-mode">True</property> + <property name="xalign">0</property> <style> - <class name="dim-label"/> + <class name="large-header"/> </style> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkImage" id="phone_image"> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> + <property name="tooltip-text" translatable="yes">The last message was written on a mobile client</property> + <property name="halign">start</property> + <property name="margin-end">4</property> + <property name="icon-name">phone-apple-iphone-symbolic</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="description_label"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="ellipsize">end</property> + <property name="single-line-mode">True</property> + <property name="max-width-chars">30</property> + <property name="xalign">0</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> - <style> - <class name="flat"/> - </style> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="pack-type">end</property> - <property name="position">0</property> + <property name="position">6</property> </packing> </child> <child> @@ -141,7 +335,7 @@ <property name="expand">False</property> <property name="fill">True</property> <property name="pack-type">end</property> - <property name="position">1</property> + <property name="position">6</property> </packing> </child> <child> @@ -192,7 +386,7 @@ <property name="expand">False</property> <property name="fill">True</property> <property name="pack-type">end</property> - <property name="position">3</property> + <property name="position">7</property> </packing> </child> </object>
===================================== gajim/data/gui/chat_control.ui ===================================== @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.38.2 --> +<!-- Generated with glade 3.40.0 --> <interface> <requires lib="gtk+" version="3.24"/> <object class="GtkBox" id="control_box"> <property name="can-focus">True</property> <child> - <object class="GtkBox" id="conv_view_box"> + <object class="GtkPaned" id="conv_view_paned"> + <property name="visible">True</property> <property name="can-focus">True</property> - <property name="spacing">3</property> <child> <object class="GtkOverlay" id="conv_view_overlay"> <property name="visible">True</property> @@ -18,16 +18,18 @@ </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> + <property name="resize">True</property> + <property name="shrink">True</property> </packing> </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> - <property name="position">0</property> + <property name="position">1</property> </packing> </child> </object>
===================================== gajim/data/gui/groupchat_roster.ui ===================================== @@ -2,74 +2,167 @@ <!-- Generated with glade 3.40.0 --> <interface> <requires lib="gtk+" version="3.20"/> - <object class="GtkTreeStore" id="participant_store"> - <columns> - <!-- column-name Avatar --> - <column type="CairoGObjectSurface"/> - <!-- column-name Text --> - <column type="gchararray"/> - <!-- column-name IsContact --> - <column type="gboolean"/> - <!-- column-name GroupOrNickname --> - <column type="gchararray"/> - </columns> - </object> - <object class="GtkScrolledWindow" id="scrolled"> + <object class="GtkBox" id="box"> <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="hscrollbar-policy">never</property> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> <child> - <object class="GtkTreeView" id="roster_treeview"> + <object class="GtkBox"> <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="headers-visible">False</property> - <property name="expander-column">expander</property> - <property name="search-column">1</property> - <signal name="button-press-event" handler="_on_roster_button_press_event" swapped="no"/> - <signal name="focus-out-event" handler="_on_focus_out" swapped="no"/> - <signal name="query-tooltip" handler="_query_tooltip" swapped="no"/> - <signal name="row-activated" handler="_on_roster_row_activated" swapped="no"/> - <child internal-child="selection"> - <object class="GtkTreeSelection"/> + <property name="can-focus">False</property> + <property name="margin-start">6</property> + <property name="margin-end">6</property> + <property name="margin-top">12</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child> + <object class="GtkButton"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="halign">center</property> + <property name="action-name">win.muc-invite</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">contact-new-symbolic</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes">Invite someone…</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> <child> - <object class="GtkTreeViewColumn" id="contact_column"> - <property name="sizing">fixed</property> - <property name="fixed-width">210</property> - <property name="title">avatar</property> - <property name="expand">True</property> + <object class="GtkSearchEntry" id="search_entry"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="primary-icon-name">edit-find-symbolic</property> + <property name="primary-icon-activatable">False</property> + <property name="primary-icon-sensitive">False</property> + <property name="placeholder-text" translatable="yes">Search Participants…</property> + <signal name="changed" handler="_on_search_changed" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolled"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hscrollbar-policy">never</property> + <child> + <object class="GtkTreeView" id="roster_treeview"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="headers-visible">False</property> + <property name="expander-column">expander</property> + <property name="enable-search">False</property> + <signal name="button-press-event" handler="_on_roster_button_press_event" swapped="no"/> + <signal name="focus-out-event" handler="_on_focus_out" swapped="no"/> + <signal name="query-tooltip" handler="_query_tooltip" swapped="no"/> + <signal name="row-activated" handler="_on_roster_row_activated" swapped="no"/> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> <child> - <object class="GtkCellRendererPixbuf" id="avatar_renderer"> - <property name="width">40</property> - <property name="ypad">3</property> - <property name="xalign">0</property> + <object class="GtkTreeViewColumn" id="contact_column"> + <property name="sizing">fixed</property> + <property name="fixed-width">210</property> + <property name="title">avatar</property> + <property name="expand">True</property> + <child> + <object class="GtkCellRendererPixbuf" id="avatar_renderer"> + <property name="width">40</property> + <property name="ypad">3</property> + <property name="xalign">0</property> + </object> + <attributes> + <attribute name="visible">2</attribute> + <attribute name="surface">0</attribute> + </attributes> + </child> + <child> + <object class="GtkCellRendererText" id="text_renderer"> + <property name="ellipsize">end</property> + </object> + <attributes> + <attribute name="markup">1</attribute> + </attributes> + </child> </object> - <attributes> - <attribute name="visible">2</attribute> - <attribute name="surface">0</attribute> - </attributes> </child> <child> - <object class="GtkCellRendererText" id="text_renderer"> - <property name="ellipsize">end</property> + <object class="GtkTreeViewColumn" id="expander"> + <property name="visible">False</property> + <property name="sizing">fixed</property> + <property name="title">expander</property> </object> - <attributes> - <attribute name="markup">1</attribute> - </attributes> </child> </object> </child> - <child> - <object class="GtkTreeViewColumn" id="expander"> - <property name="visible">False</property> - <property name="sizing">fixed</property> - <property name="title">expander</property> - </object> - </child> </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> </child> <style> <class name="groupchat-roster"/> </style> </object> + <object class="GtkTreeStore" id="participant_store"> + <columns> + <!-- column-name Avatar --> + <column type="CairoGObjectSurface"/> + <!-- column-name Text --> + <column type="gchararray"/> + <!-- column-name IsContact --> + <column type="gboolean"/> + <!-- column-name GroupOrNickname --> + <column type="gchararray"/> + </columns> + </object> </interface>
===================================== gajim/data/gui/message_actions_box.ui ===================================== @@ -9,55 +9,7 @@ <property name="hexpand">True</property> <property name="spacing">2</property> <child> - <object class="GtkButton" id="quick_invite_button"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">True</property> - <property name="tooltip-text" translatable="yes">Invite Contacts…</property> - <property name="action-name">win.invite</property> - <property name="relief">none</property> - <child> - <object class="GtkImage"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="icon-name">list-add-symbolic</property> - </object> - </child> - <style> - <class name="message-actions-box-button"/> - <class name="flat"/> - </style> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack-type">end</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkMenuButton" id="settings_menu"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">True</property> - <property name="relief">none</property> - <child> - <object class="GtkImage"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="icon-name">open-menu-symbolic</property> - </object> - </child> - <style> - <class name="message-actions-box-button"/> - </style> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack-type">end</property> - <property name="position">0</property> - </packing> + <placeholder/> </child> <child> <object class="GtkButton" id="encryption_details_button"> @@ -216,20 +168,17 @@ <property name="position">7</property> </packing> </child> - <child> - <placeholder/> - </child> <child> <object class="GtkScrolledWindow" id="input_scrolled"> <property name="visible">True</property> <property name="can-focus">True</property> <property name="margin-start">3</property> <property name="margin-end">3</property> + <property name="hscrollbar-policy">external</property> <property name="shadow-type">in</property> <property name="overlay-scrolling">False</property> <property name="max-content-height">100</property> <property name="propagate-natural-height">True</property> - <property name="hscrollbar-policy">GTK_POLICY_EXTERNAL</property> <child> <placeholder/> </child>
===================================== gajim/data/style/gajim.css ===================================== @@ -968,10 +968,6 @@ .start-chat-row:not(.activatable) label { color: @insensitive_fg_color; } .start-chat-row:focus { outline: none; }
/* GroupChatRoster */ -.groupchat-roster { - border-left: 1px solid; - border-color: @borders; -} .groupchat-roster treeview { padding-left: 4px; }
/* GroupchatConfig */
===================================== gajim/gtk/builder.pyi ===================================== @@ -186,12 +186,18 @@ class CertificateBuilder(Builder):
class ChatBannerBuilder(Builder): + share_popover: Gtk.Popover + jid_label: Gtk.Label banner_box: Gtk.Box avatar_image: Gtk.Image - name_label: Gtk.Label - phone_image: Gtk.Image + chat_menu_button: Gtk.MenuButton toggle_roster_button: Gtk.Button toggle_roster_image: Gtk.Image + contact_info_button: Gtk.Button + share_menu_button: Gtk.MenuButton + name_label: Gtk.Label + phone_image: Gtk.Image + description_label: Gtk.Label additional_items_box: Gtk.Box visitor_box: Gtk.Box visitor_menu_button: Gtk.MenuButton @@ -200,7 +206,7 @@ class ChatBannerBuilder(Builder):
class ChatControlBuilder(Builder): control_box: Gtk.Box - conv_view_box: Gtk.Box + conv_view_paned: Gtk.Paned conv_view_overlay: Gtk.Overlay
@@ -485,13 +491,15 @@ class GroupchatOutcastBuilder(Builder):
class GroupchatRosterBuilder(Builder): - participant_store: Gtk.TreeStore + box: Gtk.Box + search_entry: Gtk.SearchEntry scrolled: Gtk.ScrolledWindow roster_treeview: Gtk.TreeView contact_column: Gtk.TreeViewColumn avatar_renderer: Gtk.CellRendererPixbuf text_renderer: Gtk.CellRendererText expander: Gtk.TreeViewColumn + participant_store: Gtk.TreeStore
class GroupchatRosterTooltipBuilder(Builder): @@ -572,8 +580,6 @@ class ManageSoundsBuilder(Builder):
class MessageActionsBoxBuilder(Builder): box: Gtk.Box - quick_invite_button: Gtk.Button - settings_menu: Gtk.MenuButton encryption_details_button: Gtk.Button encryption_details_image: Gtk.Image encryption_menu_button: Gtk.MenuButton
===================================== gajim/gtk/chat_banner.py ===================================== @@ -18,6 +18,7 @@ from typing import Optional
import cairo +from gi.repository import Gdk from gi.repository import GLib from gi.repository import Gtk
@@ -38,6 +39,10 @@
from gajim.gtk.builder import get_builder from gajim.gtk.groupchat_voice_requests_button import VoiceRequestsButton +from gajim.gtk.menus import get_groupchat_menu +from gajim.gtk.menus import get_private_chat_menu +from gajim.gtk.menus import get_self_contact_menu +from gajim.gtk.menus import get_singlechat_menu from gajim.gtk.util import AccountBadge
@@ -93,12 +98,15 @@ def switch_contact(self, contact: types.ChatContactT) -> None:
self._voice_requests_button.switch_contact(self._contact)
+ self._set_chat_menu(contact) self._update_phone_image() self._update_roster_button() self._update_avatar() self._update_visitor_button() self._update_name_label() + self._update_description_label() self._update_account_badge() + self._update_share_box()
def _connect_signals(self) -> None: assert self._contact is not None @@ -212,6 +220,7 @@ def _on_muc_disco_update(self, event: MucDiscoUpdate) -> None: return
self._update_name_label() + self._update_description_label()
def _on_account_changed(self, event: AccountEnabled) -> None: self._update_account_badge() @@ -232,6 +241,17 @@ def _on_message_received(self, event: MessageReceived) -> None:
self._update_phone_image()
+ def _set_chat_menu(self, contact: types.ChatContactT) -> None: + if isinstance(contact, GroupchatContact): + menu = get_groupchat_menu(contact) + elif isinstance(contact, GroupchatParticipant): + menu = get_private_chat_menu(contact) + elif contact.is_self: + menu = get_self_contact_menu(contact) + else: + menu = get_singlechat_menu(contact) + self._ui.chat_menu_button.set_menu_model(menu) + def _update_phone_image(self) -> None: self._ui.phone_image.set_visible( self._contact in self._last_message_from_phone) @@ -283,6 +303,17 @@ def _update_name_label(self) -> None:
self._ui.name_label.set_tooltip_text(tooltip_text)
+ def _update_description_label(self) -> None: + assert self._contact is not None + text = '' + if self._contact.is_groupchat: + disco_info = app.storage.cache.get_last_disco_info( + self._contact.jid) + if disco_info is not None: + text = disco_info.muc_description or '' + self._ui.description_label.set_text(text) + self._ui.description_label.set_visible(bool(text)) + def _update_account_badge(self) -> None: if self._contact is None: self._account_badge.set_visible(False) @@ -294,6 +325,20 @@ def _update_account_badge(self) -> None:
self._account_badge.set_visible(visible)
+ def _update_share_box(self) -> None: + assert self._contact is not None + self._ui.share_menu_button.set_sensitive(True) + self._ui.jid_label.set_text(str(self._contact.jid)) + + def _on_copy_jid_clicked(self, _button: Gtk.Button) -> None: + assert self._contact is not None + text = f'xmpp:{self._contact.jid}' + if self._contact.is_groupchat: + text = f'{text}?join' + clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + clipboard.set_text(text, -1) + self._ui.share_popover.popdown() + def _on_request_voice_clicked(self, _button: Gtk.Button) -> None: self._ui.visitor_popover.popdown() app.window.activate_action('muc-request-voice', None)
===================================== gajim/gtk/control.py ===================================== @@ -90,8 +90,7 @@ def __init__(self) -> None: self._ui.conv_view_overlay.add_overlay(self._jump_to_end_button)
self._roster = GroupchatRoster() - - self._ui.conv_view_box.add(self._roster) + self._ui.conv_view_paned.pack2(self._roster, False, False)
# Used with encryption plugins self.sendmessage = False
===================================== gajim/gtk/groupchat_roster.py ===================================== @@ -84,7 +84,7 @@ def __init__(self) -> None: self._tooltip = GCTooltip()
self._ui = get_builder('groupchat_roster.ui') - self.add(self._ui.scrolled) + self.add(self._ui.box)
self._contact_refs: dict[str, Gtk.TreeRowReference] = {} self._group_refs: dict[str, Gtk.TreeRowReference] = {} @@ -93,7 +93,10 @@ def __init__(self) -> None: self._store.set_sort_func(Column.TEXT, self._tree_compare_iters)
self._roster = self._ui.roster_treeview - self._roster.set_search_equal_func(self._search_func) + + self._filter_string = '' + self._modelfilter = self._store.filter_new() + self._modelfilter.set_visible_func(self._visible_func) self._roster.set_has_tooltip(True)
self._ui.contact_column.set_fixed_width( @@ -201,14 +204,24 @@ def _query_tooltip(self, tooltip.set_custom(widget) return value
- @staticmethod - def _search_func(model: Gtk.TreeModel, - _column: int, - search_text: str, - iter_: Gtk.TreeIter - ) -> bool: + def _on_search_changed(self, widget: Gtk.SearchEntry) -> None: + self._filter_string = widget.get_text().lower() + self._modelfilter.refilter() + self._roster.expand_all() + + def _visible_func(self, + model: Gtk.TreeModelFilter, + iter_: Gtk.TreeIter, + *_data: Any + ) -> bool:
- return search_text.lower() not in model[iter_][1].lower() + if not self._filter_string: + return True + + if not model[iter_][Column.IS_CONTACT]: + return True + + return self._filter_string in model[iter_][Column.TEXT].lower()
def _get_group_iter(self, group_name: str) -> Optional[Gtk.TreeIter]: try: @@ -512,7 +525,9 @@ def _load_roster(self) -> None: self._add_contact(participant)
self.enable_sort(True) - self._roster.set_model(self._store) + self._roster.set_model(self._modelfilter) + + self._ui.search_entry.set_text('') self._roster.expand_all()
def _unload_roster(self) -> None:
===================================== gajim/gtk/menus.py ===================================== @@ -75,7 +75,6 @@ def get_self_contact_menu(contact: types.BareContact) -> GajimMenu:
params = RemoveHistoryActionParams(account=account, jid=jid) menu.add_item(_('Remove History…'), 'app.remove-history', params) - menu.add_item(_('Search…'), 'win.search-history', None) return menu
@@ -83,7 +82,6 @@ def get_singlechat_menu(contact: types.BareContact) -> GajimMenu: account = contact.account
menu = GajimMenu() - menu.add_item(_('Details'), 'win.show-contact-info') menu.add_item(_('Block Contact…'), f'app.{account}-block-contact', str(contact.jid)) @@ -94,8 +92,6 @@ def get_singlechat_menu(contact: types.BareContact) -> GajimMenu: menu.add_item(_('Start Voice Call…'), 'win.start-voice-call') menu.add_item(_('Start Video Call…'), 'win.start-video-call')
- menu.add_item(_('Search…'), 'win.search-history', None) - if can_add_to_roster(contact): params = AccountJidParam(account=account, jid=contact.jid) menu.add_item(_('Add to Contact List…'), 'win.add-to-roster', params) @@ -108,9 +104,7 @@ def get_private_chat_menu(contact: types.GroupchatParticipant) -> GajimMenu:
value = GLib.Variant('as', [''])
- menu.add_item(_('Details'), 'win.show-contact-info') menu.add_item(_('Upload File…'), 'win.send-file-httpupload', value) - menu.add_item(_('Search…'), 'win.search-history')
if can_add_to_roster(contact): params = AccountJidParam(account=contact.account, jid=contact.jid) @@ -131,11 +125,9 @@ def get_send_file_submenu() -> GajimMenu:
def get_groupchat_menu(contact: GroupchatContact) -> GajimMenu: menuitems: MenuItemListT = [ - (_('Details'), 'win.show-contact-info', None), (_('Change Nickname…'), 'win.muc-change-nickname', None), (_('Request Voice'), 'win.muc-request-voice', None), (_('Execute Command…'), 'win.muc-execute-command', ''), - (_('Search…'), 'win.search-history', None) ]
return GajimMenu.from_list(menuitems)
===================================== gajim/gtk/message_actions_box.py ===================================== @@ -44,10 +44,6 @@ from gajim.gtk.dialogs import ErrorDialog from gajim.gtk.menus import get_encryption_menu from gajim.gtk.menus import get_format_menu -from gajim.gtk.menus import get_groupchat_menu -from gajim.gtk.menus import get_private_chat_menu -from gajim.gtk.menus import get_self_contact_menu -from gajim.gtk.menus import get_singlechat_menu from gajim.gtk.message_input import MessageInputTextView from gajim.gtk.security_label_selector import SecurityLabelSelector
@@ -93,8 +89,6 @@ def __init__(self) -> None: self._ui.formattings_button.set_menu_model(get_format_menu()) self._ui.encryption_menu_button.set_menu_model(get_encryption_menu())
- self._ui.quick_invite_button.set_action_name('win.muc-invite') - self.show_all() self._ui.connect_signals(self)
@@ -181,23 +175,17 @@ def switch_contact(self, contact: ChatContactT) -> None: self._contact = contact
if isinstance(self._contact, GroupchatContact): - self._ui.quick_invite_button.show() self._contact.multi_connect({ 'state-changed': self._on_muc_state_changed, 'user-role-changed': self._on_muc_state_changed, }) elif isinstance(self._contact, GroupchatParticipant): - self._ui.quick_invite_button.hide() self._contact.multi_connect({ 'user-joined': self._on_user_state_changed, 'user-left': self._on_user_state_changed, 'room-joined': self._on_user_state_changed, 'room-left': self._on_user_state_changed, }) - else: - self._ui.quick_invite_button.hide() - - self._set_settings_menu(contact)
self._update_encryption_button() self._update_encryption_details_button() @@ -374,17 +362,6 @@ def _on_encryption_details_clicked(self, _button: Gtk.Button) -> None: app.plugin_manager.extension_point( f'encryption_dialog{encryption}', app.window.get_control())
- def _set_settings_menu(self, contact: ChatContactT) -> None: - if isinstance(contact, GroupchatContact): - menu = get_groupchat_menu(contact) - elif isinstance(contact, GroupchatParticipant): - menu = get_private_chat_menu(contact) - elif contact.is_self: - menu = get_self_contact_menu(contact) - else: - menu = get_singlechat_menu(contact) - self._ui.settings_menu.set_menu_model(menu) - def _on_format(self, name: str) -> None: name = name.removeprefix('input-') self.msg_textview.apply_formatting(name)
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/65cb6ba3bacab5ad6082210b1ddaa01d...