Daniel Brötzmann pushed to branch master at gajim / gajim
Commits: b9b0dff6 by wurstsalat at 2022-01-25T23:09:41+01:00 ServerInfo: Simplify code
- - - - - bdaf009f by wurstsalat at 2022-01-25T23:09:41+01:00 GroupchatDetails: Add page icon for affiliation
- - - - -
4 changed files:
- gajim/data/gui/groupchat_details.ui - gajim/data/gui/server_info.ui - gajim/gtk/builder.pyi - gajim/gtk/server_info.py
Changes:
===================================== gajim/data/gui/groupchat_details.ui ===================================== @@ -143,6 +143,7 @@ <packing> <property name="name">affiliations</property> <property name="title" translatable="yes">Affiliations</property> + <property name="icon-name">system-users-symbolic</property> <property name="position">2</property> </packing> </child>
===================================== gajim/data/gui/server_info.ui ===================================== @@ -1,21 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.22.1 --> +<!-- Generated with glade 3.38.2 --> <interface> <requires lib="gtk+" version="3.22"/> <object class="GtkNotebook" id="server_info_notebook"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="can-focus">True</property> <child> + <!-- n-columns=3 n-rows=5 --> <object class="GtkGrid" id="server"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">center</property> - <property name="row_spacing">6</property> - <property name="column_spacing">12</property> + <property name="row-spacing">6</property> + <property name="column-spacing">12</property> <child> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="label" translatable="yes">Hostname</property> <style> @@ -23,29 +24,29 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> + <property name="left-attach">0</property> + <property name="top-attach">0</property> </packing> </child> <child> <object class="GtkLabel" id="server_hostname"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="selectable">True</property> <property name="ellipsize">end</property> - <property name="single_line_mode">True</property> + <property name="single-line-mode">True</property> <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> + <property name="left-attach">1</property> + <property name="top-attach">0</property> </packing> </child> <child> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="label" translatable="yes">Server Software</property> <style> @@ -53,29 +54,29 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> + <property name="left-attach">0</property> + <property name="top-attach">1</property> </packing> </child> <child> <object class="GtkLabel" id="server_software"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="selectable">True</property> <property name="ellipsize">end</property> - <property name="single_line_mode">True</property> + <property name="single-line-mode">True</property> <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> + <property name="left-attach">1</property> + <property name="top-attach">1</property> </packing> </child> <child> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="label" translatable="yes">Server Uptime</property> <style> @@ -83,57 +84,72 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> + <property name="left-attach">0</property> + <property name="top-attach">2</property> </packing> </child> <child> <object class="GtkLabel" id="server_uptime"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="selectable">True</property> <property name="ellipsize">end</property> - <property name="single_line_mode">True</property> + <property name="single-line-mode">True</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> + <property name="left-attach">1</property> + <property name="top-attach">2</property> </packing> </child> <child> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_top">12</property> + <property name="can-focus">False</property> + <property name="margin-top">12</property> <property name="label" translatable="yes">Contact Addresses</property> <style> <class name="bold16"/> </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> + <property name="left-attach">0</property> + <property name="top-attach">3</property> <property name="width">2</property> </packing> </child> <child> <object class="GtkLabel" id="no_addresses_label"> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> <property name="label" translatable="yes">No contact addresses published for this server.</property> <property name="wrap">True</property> - <property name="max_width_chars">50</property> + <property name="max-width-chars">50</property> <style> <class name="dim-label"/> </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">4</property> + <property name="left-attach">0</property> + <property name="top-attach">4</property> <property name="width">2</property> </packing> </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> <style> <class name="margin-18"/> </style> @@ -142,37 +158,38 @@ <child type="tab"> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="label" translatable="yes">Server</property> </object> <packing> - <property name="tab_fill">False</property> + <property name="tab-fill">False</property> </packing> </child> <child> + <!-- n-columns=3 n-rows=9 --> <object class="GtkGrid"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">12</property> - <property name="column_homogeneous">True</property> + <property name="can-focus">False</property> + <property name="row-spacing">6</property> + <property name="column-spacing">12</property> + <property name="column-homogeneous">True</property> <child> <object class="GtkLabel" id="connection_type"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> - <property name="single_line_mode">True</property> + <property name="single-line-mode">True</property> <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">4</property> + <property name="left-attach">1</property> + <property name="top-attach">4</property> </packing> </child> <child> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="label" translatable="yes">Proxy Type</property> <style> @@ -180,44 +197,44 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">5</property> + <property name="left-attach">0</property> + <property name="top-attach">5</property> </packing> </child> <child> <object class="GtkLabel" id="proxy_type"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="label" translatable="yes">No proxy used</property> <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">5</property> + <property name="left-attach">1</property> + <property name="top-attach">5</property> </packing> </child> <child> <object class="GtkButton" id="cert_button"> <property name="label" translatable="yes">View _Certificate</property> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> <property name="halign">center</property> - <property name="margin_top">12</property> - <property name="use_underline">True</property> + <property name="margin-top">12</property> + <property name="use-underline">True</property> <signal name="clicked" handler="_on_cert_button_clicked" swapped="no"/> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">8</property> + <property name="left-attach">0</property> + <property name="top-attach">8</property> <property name="width">2</property> </packing> </child> <child> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="label" translatable="yes">Proxy Host</property> <style> @@ -225,27 +242,27 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">6</property> + <property name="left-attach">0</property> + <property name="top-attach">6</property> </packing> </child> <child> <object class="GtkLabel" id="proxy_host"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="label">-</property> <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">6</property> + <property name="left-attach">1</property> + <property name="top-attach">6</property> </packing> </child> <child> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="label" translatable="yes">Type</property> <style> @@ -253,14 +270,14 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">4</property> + <property name="left-attach">0</property> + <property name="top-attach">4</property> </packing> </child> <child> <object class="GtkLabel" id="domain_label"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="label">Domain</property> <style> @@ -268,14 +285,14 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> + <property name="left-attach">0</property> + <property name="top-attach">0</property> </packing> </child> <child> <object class="GtkLabel" id="dns_label"> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> <property name="halign">end</property> <property name="label">DNS</property> <style> @@ -283,14 +300,14 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> + <property name="left-attach">0</property> + <property name="top-attach">1</property> </packing> </child> <child> <object class="GtkLabel" id="ip_port_label"> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> <property name="halign">end</property> <property name="label">IP / Port</property> <style> @@ -298,14 +315,14 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> + <property name="left-attach">0</property> + <property name="top-attach">2</property> </packing> </child> <child> <object class="GtkLabel" id="websocket_label"> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> <property name="halign">end</property> <property name="label">WebSocket URL</property> <style> @@ -313,56 +330,56 @@ </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> + <property name="left-attach">0</property> + <property name="top-attach">3</property> </packing> </child> <child> <object class="GtkLabel" id="domain"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> + <property name="left-attach">1</property> + <property name="top-attach">0</property> </packing> </child> <child> <object class="GtkLabel" id="dns"> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> <property name="halign">start</property> <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> + <property name="left-attach">1</property> + <property name="top-attach">1</property> </packing> </child> <child> <object class="GtkLabel" id="ip_port"> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> <property name="halign">start</property> <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> + <property name="left-attach">1</property> + <property name="top-attach">2</property> </packing> </child> <child> <object class="GtkLabel" id="websocket"> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> <property name="halign">start</property> <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">3</property> + <property name="left-attach">1</property> + <property name="top-attach">3</property> </packing> </child> <child> @@ -371,6 +388,33 @@ <child> <placeholder/> </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> <style> <class name="margin-18"/> </style> @@ -382,29 +426,40 @@ <child type="tab"> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="label" translatable="yes">Connection</property> </object> <packing> <property name="position">1</property> - <property name="tab_fill">False</property> + <property name="tab-fill">False</property> </packing> </child> <child> <object class="GtkBox" id="features"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="border_width">18</property> + <property name="can-focus">False</property> + <property name="border-width">18</property> <property name="orientation">vertical</property> <property name="spacing">12</property> <child> - <object class="GtkScrolledWindow" id="features_scrolled"> + <object class="GtkScrolledWindow"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">never</property> - <property name="max_content_height">500</property> + <property name="can-focus">True</property> + <property name="hscrollbar-policy">never</property> + <property name="max-content-height">500</property> <child> - <placeholder/> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkListBox" id="features_listbox"> + <property name="name">ServerInfo</property> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="selection-mode">none</property> + </object> + </child> + </object> </child> </object> <packing> @@ -416,16 +471,16 @@ <child> <object class="GtkButton" id="clipboard_button"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="tooltip_text" translatable="yes">Copy info to clipboard</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="tooltip-text" translatable="yes">Copy info to clipboard</property> <property name="halign">end</property> <signal name="clicked" handler="_on_clipboard_button_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> + <property name="can-focus">False</property> + <property name="icon-name">edit-copy-symbolic</property> </object> </child> </object> @@ -443,12 +498,12 @@ <child type="tab"> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="label" translatable="yes">Features</property> </object> <packing> <property name="position">2</property> - <property name="tab_fill">False</property> + <property name="tab-fill">False</property> </packing> </child> </object>
===================================== gajim/gtk/builder.pyi ===================================== @@ -819,7 +819,7 @@ class ServerInfoBuilder(Builder): ip_port: Gtk.Label websocket: Gtk.Label features: Gtk.Box - features_scrolled: Gtk.ScrolledWindow + features_listbox: Gtk.ListBox clipboard_button: Gtk.Button
===================================== gajim/gtk/server_info.py ===================================== @@ -12,19 +12,30 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see http://www.gnu.org/licenses/.
+from typing import cast +from typing import Any +from typing import NamedTuple +from typing import Optional + import logging -from collections import namedtuple from datetime import timedelta
-from nbxmpp.errors import StanzaError -from nbxmpp.errors import MalformedStanzaError -from nbxmpp.namespaces import Namespace +from gi.repository import GLib from gi.repository import Gtk from gi.repository import Gdk from gi.repository import Pango
+from nbxmpp.errors import StanzaError +from nbxmpp.errors import MalformedStanzaError +from nbxmpp.modules.dataforms import SimpleDataForm +from nbxmpp.namespaces import Namespace +from nbxmpp.structs import LastActivityData +from nbxmpp.structs import SoftwareVersionResult +from nbxmpp.task import Task + from gajim.common import app from gajim.common import ged +from gajim.common.events import ServerDiscoReceived from gajim.common.helpers import open_uri from gajim.common.i18n import _
@@ -35,25 +46,37 @@ log = logging.getLogger('gajim.gui.server_info')
+class Feature(NamedTuple): + name: str + available: bool + additional: Optional[str] = None + + class ServerInfo(Gtk.ApplicationWindow, EventHelper): - def __init__(self, account): + def __init__(self, account: str) -> None: Gtk.ApplicationWindow.__init__(self) EventHelper.__init__(self) self.set_name('ServerInfo') self.set_application(app.app) self.set_position(Gtk.WindowPosition.CENTER) - self.set_default_size(400, 600) + self.set_default_size(500, 600) self.set_show_menubar(False) self.set_title(_('Server Info')) self.set_type_hint(Gdk.WindowTypeHint.DIALOG)
self.account = account + self._client = app.get_client(account) self._destroyed = False
+ if app.settings.get('use_kib_mib'): + self._units = GLib.FormatSizeFlags.IEC_UNITS + else: + self._units = GLib.FormatSizeFlags.DEFAULT + self._ui = get_builder('server_info.ui') self.add(self._ui.server_info_notebook)
- self.connect('destroy', self.on_destroy) + self.connect('destroy', self._on_destroy) self.connect('key-press-event', self._on_key_press) self._ui.connect_signals(self)
@@ -61,39 +84,37 @@ def __init__(self, account): ('server-disco-received', ged.GUI1, self._server_disco_received), ])
- self.version = '' - self.hostname = app.get_hostname_from_account(account) - self._ui.server_hostname.set_text(self.hostname) - con = app.connections[account] - con.get_module('SoftwareVersion').request_software_version( - self.hostname, callback=self._software_version_received) + self._version = '' + self._hostname = app.get_hostname_from_account(account) + self._ui.server_hostname.set_text(self._hostname) + self._client.get_module('SoftwareVersion').request_software_version( + self._hostname, callback=self._software_version_received)
- con.get_module('LastActivity').request_last_activity( - self.hostname, callback=self._on_last_activity) + self._client.get_module('LastActivity').request_last_activity( + self._hostname, callback=self._on_last_activity)
- server_info = con.get_module('Discovery').server_info + server_info = self._client.get_module('Discovery').server_info self._add_contact_addresses(server_info.dataforms)
- self.cert = con.certificate + self._cert = self._client.certificate self._add_connection_info()
- self.feature_listbox = Gtk.ListBox() - self.feature_listbox.set_name('ServerInfo') - self.feature_listbox.set_selection_mode(Gtk.SelectionMode.NONE) - self._ui.features_scrolled.add(self.feature_listbox) - for feature in self.get_features(): - self.add_feature(feature) - self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + for feature in self._get_features(): + self._add_feature(feature) + self._clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
self.show_all()
- def _on_key_press(self, _widget, event): + def _on_destroy(self, *args: Any) -> None: + self._destroyed = True + + def _on_key_press(self, _widget: Gtk.Widget, event: Gdk.EventKey) -> None: if event.keyval == Gdk.KEY_Escape: self.destroy()
- def _add_connection_info(self): + def _add_connection_info(self) -> None: # Connection type - nbxmpp_client = app.connections[self.account].connection + nbxmpp_client = self._client.connection address = nbxmpp_client.current_address
self._ui.connection_type.set_text(address.type.value) @@ -107,7 +128,7 @@ def _add_connection_info(self): self._ui.proxy_type.set_text(proxy.type) self._ui.proxy_host.set_text(proxy.host)
- self._ui.cert_button.set_sensitive(self.cert) + self._ui.cert_button.set_sensitive(self._cert)
self._ui.domain.set_text(address.domain)
@@ -126,13 +147,13 @@ def _add_connection_info(self): self._ui.websocket.set_visible(visible) self._ui.websocket.set_text(address.uri or '')
- def _on_cert_button_clicked(self, _button): + def _on_cert_button_clicked(self, _button: Gtk.Button) -> None: open_window('CertificateDialog', account=self.account, transient_for=self, - cert=self.cert) + cert=self._cert)
- def _add_contact_addresses(self, dataforms): + def _add_contact_addresses(self, dataforms: list[SimpleDataForm]) -> None: fields = { 'admin-addresses': _('Admin'), 'status-addresses': _('Status'), @@ -159,8 +180,10 @@ def _add_contact_addresses(self, dataforms): row_count += 1
@staticmethod - def _get_addresses(fields, dataforms): - addresses = {} + def _get_addresses(fields: dict[str, str], + dataforms: list[SimpleDataForm] + ) -> Optional[dict[str, list[str]]]: + addresses: dict[str, list[str]] = {} for form in dataforms: field = form.vars.get('FORM_TYPE') if field.value != 'http://jabber.org/network/serverinfo': @@ -182,16 +205,19 @@ def _get_addresses(fields, dataforms): return None
@staticmethod - def _get_address_type_label(text): + def _get_address_type_label(text: str) -> Gtk.Label: label = Gtk.Label(label=text) label.set_halign(Gtk.Align.END) label.set_valign(Gtk.Align.START) label.get_style_context().add_class('dim-label') return label
- def _get_address_label(self, address, last=False): + def _get_address_label(self, + address: str, + last: bool = False + ) -> Gtk.Label: label = Gtk.Label() - label.set_markup('<a href="%s">%s</a>' % (address, address)) + label.set_markup(f'<a href="{address}">{address}</a>') label.set_ellipsize(Pango.EllipsizeMode.END) label.set_xalign(0) label.set_halign(Gtk.Align.START) @@ -201,13 +227,13 @@ def _get_address_label(self, address, last=False): label.set_margin_bottom(6) return label
- def _on_activate_link(self, label, *args): + def _on_activate_link(self, label: Gtk.Label, *args: Any) -> int: open_uri(label.get_text(), account=self.account) return Gdk.EVENT_STOP
- def _on_last_activity(self, task): + def _on_last_activity(self, task: Task) -> None: try: - result = task.finish() + result = cast(LastActivityData, task.finish()) except (StanzaError, MalformedStanzaError) as error: log.warning(error) return @@ -217,141 +243,137 @@ def _on_last_activity(self, task): if result.seconds >= 3600: hours = delta.seconds // 3600 uptime = _('%(days)s days, %(hours)s hours') % { - 'days': delta.days, 'hours': hours} + 'days': delta.days, + 'hours': hours} self._ui.server_uptime.set_text(uptime)
- def _software_version_received(self, task): + def _software_version_received(self, task: Task) -> None: try: - result = task.finish() + result = cast(SoftwareVersionResult, task.finish()) except StanzaError: - self.version = _('Unknown') + self._version = _('Unknown') else: - self.version = '%s %s' % (result.name, result.version) + self._version = f'{result.name} {result.version}'
- self._ui.server_software.set_text(self.version) + self._ui.server_software.set_text(self._version)
- @staticmethod - def update(func, listbox): - for index, item in enumerate(func()): - row = listbox.get_row_at_index(index) - row.get_child().update(item) - row.set_tooltip_text(row.get_child().tooltip) - - def _server_disco_received(self, _event): - self.update(self.get_features, self.feature_listbox) + def _server_disco_received(self, _event: ServerDiscoReceived) -> None: + features = self._get_features() + for index, item in enumerate(features): + row = cast( + FeatureItem, self._ui.features_listbox.get_row_at_index(index)) + row.update(item)
- def add_feature(self, feature): + def _add_feature(self, feature: Feature) -> None: item = FeatureItem(feature) - self.feature_listbox.add(item) - item.get_parent().set_tooltip_text(item.tooltip or '') - - def get_features(self): - con = app.connections[self.account] - Feature = namedtuple('Feature', - ['name', 'available', 'tooltip', 'enabled']) - Feature.__new__.__defaults__ = (None, None) # type: ignore - - # HTTP File Upload - http_upload_info = con.get_module('HTTPUpload').httpupload_namespace - if con.get_module('HTTPUpload').available: - max_file_size = con.get_module('HTTPUpload').max_file_size - if max_file_size is not None: - max_file_size = max_file_size / (1024 * 1024) - http_upload_info = http_upload_info + ' (max. %s MiB)' % \ - max_file_size + self._ui.features_listbox.add(item) + + def _get_features(self) -> list[Feature]: + http_upload_module = self._client.get_module('HTTPUpload') + http_upload_info = http_upload_module.httpupload_namespace + if http_upload_module.available: + max_size = http_upload_module.max_file_size + if max_size is not None: + max_size = GLib.format_size_full(max_size, self._units) + http_upload_info = f'{http_upload_info} (max. {max_size})'
return [ Feature('XEP-0045: Multi-User Chat', - con.get_module('MUC').supported), + self._client.get_module('MUC').supported), Feature('XEP-0054: vcard-temp', - con.get_module('VCardTemp').supported), + self._client.get_module('VCardTemp').supported), Feature('XEP-0077: In-Band Registration', - con.get_module('Register').supported), + self._client.get_module('Register').supported), Feature('XEP-0163: Personal Eventing Protocol', - con.get_module('PEP').supported), + self._client.get_module('PEP').supported), Feature('XEP-0163: #publish-options', - con.get_module('PubSub').publish_options), + self._client.get_module('PubSub').publish_options), Feature('XEP-0191: Blocking Command', - con.get_module('Blocking').supported, + self._client.get_module('Blocking').supported, Namespace.BLOCKING), Feature('XEP-0198: Stream Management', - con.features.has_sm, Namespace.STREAM_MGMT), + self._client.features.has_sm, + Namespace.STREAM_MGMT), Feature('XEP-0258: Security Labels in XMPP', - con.get_module('SecLabels').supported, + self._client.get_module('SecLabels').supported, Namespace.SECLABEL), Feature('XEP-0280: Message Carbons', - con.get_module('Carbons').supported, + self._client.get_module('Carbons').supported, Namespace.CARBONS), Feature('XEP-0313: Message Archive Management', - con.get_module('MAM').available), + self._client.get_module('MAM').available), Feature('XEP-0363: HTTP File Upload', - con.get_module('HTTPUpload').available, + self._client.get_module('HTTPUpload').available, http_upload_info), Feature('XEP-0398: Avatar Conversion', - con.get_module('VCardAvatars').avatar_conversion_available), + self._client.get_module('VCardAvatars').avatar_conversion_available), Feature('XEP-0411: Bookmarks Conversion', - con.get_module('Bookmarks').conversion), + self._client.get_module('Bookmarks').conversion), Feature('XEP-0402: Bookmarks Compat', - con.get_module('Bookmarks').compat), + self._client.get_module('Bookmarks').compat), Feature('XEP-0402: Bookmarks Compat PEP', - con.get_module('Bookmarks').compat_pep) + self._client.get_module('Bookmarks').compat_pep) ]
- def _on_clipboard_button_clicked(self, _widget): - server_software = 'Server Software: %s\n' % self.version + def _on_clipboard_button_clicked(self, _widget: Gtk.Button) -> None: + server_software = _('Server Software: %s\n') % self._version server_features = ''
- for feature in self.get_features(): + for feature in self._get_features(): if feature.available: - available = 'Yes' - else: - available = 'No' - if feature.tooltip is not None: - tooltip = '(%s)' % feature.tooltip + available = _('Available') else: - tooltip = '' - server_features += '%s: %s %s\n' % ( - feature.name, available, tooltip) + available = _('Not available') + additional = '' + if feature.additional is not None: + additional = f'({feature.additional})' + server_features += f'{feature.name}: {available} {additional}\n'
clipboard_text = server_software + server_features - self.clipboard.set_text(clipboard_text, -1) + self._clipboard.set_text(clipboard_text, -1)
- def on_destroy(self, *args): - self._destroyed = True
+class FeatureItem(Gtk.ListBoxRow): + def __init__(self, feature: Feature) -> None: + Gtk.ListBoxRow.__init__(self) + self._feature = feature + + grid = Gtk.Grid(row_spacing=3, column_spacing=12) + + self._icon = Gtk.Image() + self._feature_label = Gtk.Label() + self._additional_label = Gtk.Label() + self._additional_label.set_halign(Gtk.Align.START) + self._additional_label.set_no_show_all(True) + self._additional_label.get_style_context().add_class('dim-label') + + grid.attach(self._icon, 0, 0, 1, 1) + grid.attach(self._feature_label, 1, 0, 1, 1) + grid.attach(self._additional_label, 1, 1, 1, 1) + + self._set_feature() + + self.add(grid) + self.show_all() + + def _set_feature(self) -> None: + self._feature_label.set_text(self._feature.name) + if self._feature.additional is not None: + self._additional_label.set_text(self._feature.additional) + self._additional_label.show() + + self._icon.get_style_context().remove_class('error-color') + self._icon.get_style_context().remove_class('success-color')
-class FeatureItem(Gtk.Grid): - def __init__(self, feature): - super().__init__() - self.tooltip = feature.tooltip - self.set_column_spacing(6) - - self.icon = Gtk.Image() - self.feature_label = Gtk.Label(label=feature.name) - self.set_feature(feature.available, feature.enabled) - - self.add(self.icon) - self.add(self.feature_label) - - def set_feature(self, available, enabled): - self.icon.get_style_context().remove_class('error-color') - self.icon.get_style_context().remove_class('warning-color') - self.icon.get_style_context().remove_class('success-color') - - if not available: - self.icon.set_from_icon_name('window-close-symbolic', - Gtk.IconSize.MENU) - self.icon.get_style_context().add_class('error-color') - elif enabled is False: - self.icon.set_from_icon_name('dialog-warning-symbolic', - Gtk.IconSize.MENU) - self.tooltip += _('\nDisabled in preferences') - self.icon.get_style_context().add_class('warning-color') + if self._feature.available: + self._icon.set_from_icon_name( + 'emblem-ok-symbolic', Gtk.IconSize.MENU) + self._icon.get_style_context().add_class('success-color') else: - self.icon.set_from_icon_name('emblem-ok-symbolic', - Gtk.IconSize.MENU) - self.icon.get_style_context().add_class('success-color') + self._icon.set_from_icon_name( + 'window-close-symbolic', Gtk.IconSize.MENU) + self._icon.get_style_context().add_class('error-color')
- def update(self, feature): - self.tooltip = feature.tooltip - self.set_feature(feature.available, feature.enabled) + def update(self, feature: Feature) -> None: + self._feature = feature + self._set_feature()
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/45585811f2f1eaf77bd5f07946387087...