Daniel Brötzmann pushed to branch master at gajim / gajim

Commits:

4 changed files:

Changes:

  • gajim/common/helpers.py
    ... ... @@ -373,7 +373,10 @@ def get_uf_chatstate(chatstate: str) -> str:
    373 373
             return _('has closed the chat window or tab')
    
    374 374
         return ''
    
    375 375
     
    
    376
    -def exec_command(command, use_shell=False, posix=True):
    
    376
    +def exec_command(command: str,
    
    377
    +                 use_shell: bool = False,
    
    378
    +                 posix: bool = True
    
    379
    +                 ) -> None:
    
    377 380
         """
    
    378 381
         execute a command. if use_shell is True, we run the command as is it was
    
    379 382
         typed in a console. So it may be dangerous if you are not sure about what
    
    ... ... @@ -455,7 +458,7 @@ def _cut_if_long(string_):
    455 458
         return reduced_text
    
    456 459
     
    
    457 460
     
    
    458
    -def get_contact_dict_for_account(account):
    
    461
    +def get_contact_dict_for_account(account: str) -> Dict[str, types.BareContact]:
    
    459 462
         """
    
    460 463
         Creates a dict of jid -> contact with all contacts of account
    
    461 464
         Can be used for completion lists
    
    ... ... @@ -533,7 +536,7 @@ def strip_soundfile_path(file_, dirs=None, abs_=True):
    533 536
                 return name
    
    534 537
         return file_
    
    535 538
     
    
    536
    -def play_sound_file(path_to_soundfile: str, loop: bool = False):
    
    539
    +def play_sound_file(path_to_soundfile: str, loop: bool = False) -> None:
    
    537 540
         path_to_soundfile = check_soundfile_path(path_to_soundfile)
    
    538 541
         if path_to_soundfile is None:
    
    539 542
             return
    
    ... ... @@ -647,7 +650,7 @@ def get_os_info() -> str:
    647 650
         return info
    
    648 651
     
    
    649 652
     
    
    650
    -def message_needs_highlight(text, nickname, own_jid):
    
    653
    +def message_needs_highlight(text: str, nickname: str, own_jid: str) -> bool:
    
    651 654
         """
    
    652 655
         Check text to see whether any of the words in (muc_highlight_words and
    
    653 656
         nick) appear
    
    ... ... @@ -697,7 +700,7 @@ def allow_sound_notification(account: str, sound_event: str) -> bool:
    697 700
         return False
    
    698 701
     
    
    699 702
     
    
    700
    -def get_optional_features(account):
    
    703
    +def get_optional_features(account: str) -> List[Namespace]:
    
    701 704
         features = []
    
    702 705
     
    
    703 706
         if app.settings.get_account_setting(account, 'request_user_data'):
    
    ... ... @@ -720,7 +723,7 @@ def get_optional_features(account):
    720 723
         app.plugin_manager.extension_point('update_caps', account, features)
    
    721 724
         return features
    
    722 725
     
    
    723
    -def jid_is_blocked(account, jid):
    
    726
    +def jid_is_blocked(account: str, jid: str) -> bool:
    
    724 727
         con = app.connections[account]
    
    725 728
         return jid in con.get_module('Blocking').blocked
    
    726 729
     
    
    ... ... @@ -773,7 +776,7 @@ def version_condition(current_version, required_version):
    773 776
             return False
    
    774 777
         return True
    
    775 778
     
    
    776
    -def get_available_emoticon_themes():
    
    779
    +def get_available_emoticon_themes() -> List[str]:
    
    777 780
         files = []
    
    778 781
         for folder in configpaths.get('EMOTICONS').iterdir():
    
    779 782
             if not folder.is_dir():
    
    ... ... @@ -811,7 +814,7 @@ def load_json(path: Path,
    811 814
         return json_dict.get(key, default)
    
    812 815
     
    
    813 816
     
    
    814
    -def ignore_contact(account, jid):
    
    817
    +def ignore_contact(account: str, jid: JID) -> bool:
    
    815 818
         client = app.get_client(account)
    
    816 819
         contact = client.get_module('Contacts').get_contact(jid)
    
    817 820
     
    
    ... ... @@ -1097,7 +1100,7 @@ def geo_provider_from_location(lat: str, lon: str) -> str:
    1097 1100
         return f'https://www.openstreetmap.org/?mlat={lat}&mlon={lon}&zoom=16'
    
    1098 1101
     
    
    1099 1102
     
    
    1100
    -def get_resource(account):
    
    1103
    +def get_resource(account: str) -> Optional[str]:
    
    1101 1104
         resource = app.settings.get_account_setting(account, 'resource')
    
    1102 1105
         if not resource:
    
    1103 1106
             return None
    
    ... ... @@ -1129,7 +1132,7 @@ def get_default_muc_config() -> Dict[str, Union[bool, str]]:
    1129 1132
         }
    
    1130 1133
     
    
    1131 1134
     
    
    1132
    -def validate_jid(jid, type_=None):
    
    1135
    +def validate_jid(jid: Union[str, JID], type_: Optional[str] = None) -> JID:
    
    1133 1136
         try:
    
    1134 1137
             jid = JID.from_string(str(jid))
    
    1135 1138
         except InvalidJid as error:
    

  • gajim/gtk/conversation/rows/call.py
    ... ... @@ -24,7 +24,6 @@
    24 24
     from gajim.common.const import KindConstant
    
    25 25
     from gajim.common.i18n import _
    
    26 26
     from gajim.common.jingle_session import JingleSession
    
    27
    -from gajim.common import sound
    
    28 27
     
    
    29 28
     from .widgets import SimpleLabel
    
    30 29
     from .base import BaseRow
    
    ... ... @@ -96,7 +95,6 @@ def _on_accept(self, button):
    96 95
                 self.get_parent().accept_call(self._session)
    
    97 96
     
    
    98 97
         def _on_decline(self, _button):
    
    99
    -        sound.stop() # dialing/ringing
    
    100 98
             if self._event is not None:
    
    101 99
                 session = self._client.get_module('Jingle').get_jingle_session(
    
    102 100
                     self._event.fjid, self._event.sid)
    

  • gajim/gtk/groupchat_roster.py
    ... ... @@ -12,18 +12,26 @@
    12 12
     # You should have received a copy of the GNU General Public License
    
    13 13
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    14 14
     
    
    15
    +from __future__ import annotations
    
    16
    +from typing import Any
    
    17
    +from typing import cast
    
    15 18
     from typing import Optional
    
    19
    +from typing import Tuple
    
    16 20
     
    
    17 21
     import locale
    
    18 22
     from enum import IntEnum
    
    19 23
     
    
    24
    +from gi.repository import Gdk
    
    20 25
     from gi.repository import Gtk
    
    21 26
     from gi.repository import GLib
    
    22 27
     from gi.repository import GObject
    
    23 28
     from nbxmpp.const import Affiliation
    
    29
    +from nbxmpp.const import Role
    
    30
    +from nbxmpp.structs import MessageProperties
    
    24 31
     
    
    25 32
     from gajim.common import app
    
    26 33
     from gajim.common import ged
    
    34
    +from gajim.common import types
    
    27 35
     from gajim.common.helpers import get_uf_role
    
    28 36
     from gajim.common.helpers import get_uf_affiliation
    
    29 37
     from gajim.common.helpers import jid_is_blocked
    
    ... ... @@ -33,6 +41,7 @@
    33 41
     from gajim.gui_menu_builder import get_groupchat_roster_menu
    
    34 42
     from .tooltips import GCTooltip
    
    35 43
     from .builder import get_builder
    
    44
    +from .types import GroupchatControlType
    
    36 45
     from .util import EventHelper
    
    37 46
     
    
    38 47
     
    
    ... ... @@ -62,7 +71,11 @@ class GroupchatRoster(Gtk.ScrolledWindow, EventHelper):
    62 71
                 (str, )) # arguments
    
    63 72
         }
    
    64 73
     
    
    65
    -    def __init__(self, account, room_jid, control):
    
    74
    +    def __init__(self,
    
    75
    +                 account: str,
    
    76
    +                 room_jid: str,
    
    77
    +                 control: GroupchatControlType
    
    78
    +                 ) -> None:
    
    66 79
             Gtk.ScrolledWindow.__init__(self)
    
    67 80
             EventHelper.__init__(self)
    
    68 81
             self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
    
    ... ... @@ -74,14 +87,18 @@ def __init__(self, account, room_jid, control):
    74 87
             self._show_roles = True
    
    75 88
             self._tooltip = GCTooltip()
    
    76 89
             self._group_chat_contact = control.contact
    
    77
    -        self._group_chat_contact.connect('user-avatar-update',
    
    78
    -                                         self._on_user_avatar_update)
    
    90
    +        self._group_chat_contact.connect(
    
    91
    +            'user-avatar-update', self._on_user_avatar_update)
    
    79 92
             self._group_chat_contact.connect('user-joined', self._on_user_joined)
    
    80 93
             self._group_chat_contact.connect('user-left', self._on_user_left)
    
    81
    -        self._group_chat_contact.connect('user-affiliation-changed', self._update_contact)
    
    82
    -        self._group_chat_contact.connect('user-role-changed', self._update_contact)
    
    83
    -        self._group_chat_contact.connect('user-status-show-changed', self._on_user_status_show_changed)
    
    84
    -        self._group_chat_contact.connect('user-nickname-changed', self._on_user_nickname_changed)
    
    94
    +        self._group_chat_contact.connect(
    
    95
    +            'user-affiliation-changed', self._update_contact)
    
    96
    +        self._group_chat_contact.connect(
    
    97
    +            'user-role-changed', self._update_contact)
    
    98
    +        self._group_chat_contact.connect(
    
    99
    +            'user-status-show-changed', self._on_user_status_show_changed)
    
    100
    +        self._group_chat_contact.connect(
    
    101
    +            'user-nickname-changed', self._on_user_nickname_changed)
    
    85 102
             # self._group_chat_contact.connect('muc-user-presence-update',
    
    86 103
             #                                  self._on_muc_user_presence_update)
    
    87 104
     
    
    ... ... @@ -90,14 +107,14 @@ def __init__(self, account, room_jid, control):
    90 107
             self.add(self._ui.roster_treeview)
    
    91 108
     
    
    92 109
             # Holds the Gtk.TreeRowReference for each contact
    
    93
    -        self._contact_refs = {}
    
    110
    +        self._contact_refs: dict[str, Gtk.TreeRowReference] = {}
    
    94 111
             # Holds the Gtk.TreeRowReference for each group
    
    95
    -        self._group_refs = {}
    
    112
    +        self._group_refs: dict[str, Gtk.TreeRowReference] = {}
    
    96 113
     
    
    97
    -        self._store = self._ui.participant_store
    
    114
    +        self._store = cast(Gtk.TreeStore, self._ui.participant_store)
    
    98 115
             self._store.set_sort_func(Column.TEXT, self._tree_compare_iters)
    
    99 116
     
    
    100
    -        self._roster = self._ui.roster_treeview
    
    117
    +        self._roster = cast(Gtk.TreeView, self._ui.roster_treeview)
    
    101 118
             self._roster.set_search_equal_func(self._search_func)
    
    102 119
             self._roster.set_has_tooltip(True)
    
    103 120
             self._roster.connect('query-tooltip', self._query_tooltip)
    
    ... ... @@ -115,16 +132,22 @@ def __init__(self, account, room_jid, control):
    115 132
             ])
    
    116 133
     
    
    117 134
         @staticmethod
    
    118
    -    def _on_focus_out(treeview, _param):
    
    135
    +    def _on_focus_out(treeview: Gtk.TreeView, _param: Gdk.EventFocus) -> None:
    
    119 136
             treeview.get_selection().unselect_all()
    
    120 137
     
    
    121
    -    def set_model(self):
    
    138
    +    def set_model(self) -> None:
    
    122 139
             self._roster.set_model(self._store)
    
    123 140
     
    
    124
    -    def set_show_roles(self, enabled):
    
    141
    +    def set_show_roles(self, enabled: bool) -> None:
    
    125 142
             self._show_roles = enabled
    
    126 143
     
    
    127
    -    def _query_tooltip(self, widget, x_pos, y_pos, _keyboard_mode, tooltip):
    
    144
    +    def _query_tooltip(self,
    
    145
    +                       widget: Gtk.Widget,
    
    146
    +                       x_pos: int,
    
    147
    +                       y_pos: int,
    
    148
    +                       _keyboard_mode: bool,
    
    149
    +                       tooltip: Gtk.Tooltip
    
    150
    +                       ) -> bool:
    
    128 151
             try:
    
    129 152
                 row = self._roster.get_path_at_pos(x_pos, y_pos)[0]
    
    130 153
             except TypeError:
    
    ... ... @@ -154,7 +177,11 @@ def _query_tooltip(self, widget, x_pos, y_pos, _keyboard_mode, tooltip):
    154 177
             return value
    
    155 178
     
    
    156 179
         @staticmethod
    
    157
    -    def _search_func(model, _column, search_text, iter_):
    
    180
    +    def _search_func(model: Gtk.TreeModel,
    
    181
    +                     _column: int,
    
    182
    +                     search_text: str,
    
    183
    +                     iter_: Gtk.TreeIter
    
    184
    +                     ) -> bool:
    
    158 185
             return search_text.lower() not in model[iter_][1].lower()
    
    159 186
     
    
    160 187
         def _get_group_iter(self, group_name: str) -> Optional[Gtk.TreeIter]:
    
    ... ... @@ -179,10 +206,15 @@ def _get_contact_iter(self, nick: str) -> Optional[Gtk.TreeIter]:
    179 206
                 return None
    
    180 207
             return self._store.get_iter(path)
    
    181 208
     
    
    182
    -    def _on_user_joined(self, _contact, _signal_name, user_contact, *args):
    
    209
    +    def _on_user_joined(self,
    
    210
    +                        _contact: types.GroupchatContact,
    
    211
    +                        _signal_name: str,
    
    212
    +                        user_contact: types.GroupchatParticipant,
    
    213
    +                        *args: Any
    
    214
    +                        ) -> None:
    
    183 215
             self._add_contact(user_contact)
    
    184 216
     
    
    185
    -    def _add_contact(self, contact):
    
    217
    +    def _add_contact(self, contact: types.GroupchatParticipant) -> None:
    
    186 218
             group_name, group_text = self._get_group_from_contact(contact)
    
    187 219
             nick = contact.name
    
    188 220
     
    
    ... ... @@ -212,24 +244,44 @@ def _add_contact(self, contact):
    212 244
                     self._roster.get_model() is not None):
    
    213 245
                 self._roster.expand_row(role_path, False)
    
    214 246
     
    
    215
    -    def _on_user_left(self, _contact, _signal_name, user_contact, *args):
    
    247
    +    def _on_user_left(self,
    
    248
    +                      _contact: types.GroupchatContact,
    
    249
    +                      _signal_name: str,
    
    250
    +                      user_contact: types.GroupchatParticipant,
    
    251
    +                      *args: Any
    
    252
    +                      ) -> None:
    
    216 253
             self._remove_contact(user_contact)
    
    217 254
             self.draw_groups()
    
    218 255
     
    
    219
    -    def _update_contact(self, _contact, _signal_name, user_contact, *args):
    
    256
    +    def _update_contact(self,
    
    257
    +                        _contact: types.GroupchatContact,
    
    258
    +                        _signal_name: str,
    
    259
    +                        user_contact: types.GroupchatParticipant,
    
    260
    +                        *args: Any
    
    261
    +                        ) -> None:
    
    220 262
             self._remove_contact(user_contact)
    
    221 263
             self._add_contact(user_contact)
    
    222 264
     
    
    223
    -    def _on_user_nickname_changed(self, contact, _signal_name, user_contact, properties):
    
    265
    +    def _on_user_nickname_changed(self,
    
    266
    +                                  contact: types.GroupchatContact,
    
    267
    +                                  _signal_name: str,
    
    268
    +                                  user_contact: types.GroupchatParticipant,
    
    269
    +                                  properties: MessageProperties
    
    270
    +                                  ) -> None:
    
    224 271
             self._remove_contact(user_contact)
    
    225 272
     
    
    226 273
             user_contact = contact.get_resource(properties.muc_user.nick)
    
    227 274
             self._add_contact(user_contact)
    
    228 275
     
    
    229
    -    def _on_user_status_show_changed(self, _contact, _signal_name, user_contact, *args):
    
    276
    +    def _on_user_status_show_changed(self,
    
    277
    +                                     _contact: types.GroupchatContact,
    
    278
    +                                     _signal_name: str,
    
    279
    +                                     user_contact: types.GroupchatParticipant,
    
    280
    +                                     *args: Any
    
    281
    +                                     ) -> None:
    
    230 282
             self.draw_contact(user_contact.name)
    
    231 283
     
    
    232
    -    def _remove_contact(self, contact):
    
    284
    +    def _remove_contact(self, contact: types.GroupchatParticipant) -> None:
    
    233 285
             nick = contact.name
    
    234 286
             iter_ = self._get_contact_iter(nick)
    
    235 287
             if not iter_:
    
    ... ... @@ -247,33 +299,43 @@ def _remove_contact(self, contact):
    247 299
                 self._store.remove(group_iter)
    
    248 300
     
    
    249 301
         @staticmethod
    
    250
    -    def _get_group_from_contact(contact):
    
    302
    +    def _get_group_from_contact(contact: types.GroupchatParticipant
    
    303
    +                                ) -> Tuple[str, str]:
    
    251 304
             if contact.affiliation in (Affiliation.OWNER, Affiliation.ADMIN):
    
    252 305
                 return contact.affiliation.value, get_uf_affiliation(
    
    253 306
                     contact.affiliation, plural=True)
    
    254 307
             return contact.role.value, get_uf_role(contact.role, plural=True)
    
    255 308
     
    
    256 309
         @staticmethod
    
    257
    -    def _text_cell_data_func(_column, renderer, model, iter_, _user_data):
    
    310
    +    def _text_cell_data_func(_column: Gtk.TreeViewColumn,
    
    311
    +                             renderer: Gtk.CellRenderer,
    
    312
    +                             model: Gtk.TreeModel,
    
    313
    +                             iter_: Gtk.TreeIter,
    
    314
    +                             _user_data: Optional[object]
    
    315
    +                             ) -> None:
    
    258 316
             has_parent = bool(model.iter_parent(iter_))
    
    259 317
             style = 'contact' if has_parent else 'group'
    
    260 318
     
    
    261
    -        bgcolor = app.css_config.get_value('.gajim-%s-row' % style,
    
    319
    +        bgcolor = app.css_config.get_value(f'.gajim-{style}-row',
    
    262 320
                                                StyleAttr.BACKGROUND)
    
    263 321
             renderer.set_property('cell-background', bgcolor)
    
    264 322
     
    
    265
    -        color = app.css_config.get_value('.gajim-%s-row' % style,
    
    323
    +        color = app.css_config.get_value(f'.gajim-{style}-row',
    
    266 324
                                              StyleAttr.COLOR)
    
    267 325
             renderer.set_property('foreground', color)
    
    268 326
     
    
    269
    -        desc = app.css_config.get_font('.gajim-%s-row' % style)
    
    327
    +        desc = app.css_config.get_font(f'.gajim-{style}-row')
    
    270 328
             renderer.set_property('font-desc', desc)
    
    271 329
     
    
    272 330
             if not has_parent:
    
    273 331
                 renderer.set_property('weight', 600)
    
    274 332
                 renderer.set_property('ypad', 6)
    
    275 333
     
    
    276
    -    def _on_roster_row_activated(self, _treeview, path, _column):
    
    334
    +    def _on_roster_row_activated(self,
    
    335
    +                                 _treeview: Gtk.TreeView,
    
    336
    +                                 path: Gtk.TreePath,
    
    337
    +                                 _column: Gtk.TreeViewColumn
    
    338
    +                                 ) -> None:
    
    277 339
             iter_ = self._store.get_iter(path)
    
    278 340
             if self._store.iter_parent(iter_) is None:
    
    279 341
                 # This is a group row
    
    ... ... @@ -283,7 +345,10 @@ def _on_roster_row_activated(self, _treeview, path, _column):
    283 345
                 return
    
    284 346
             self.emit('row-activated', nick)
    
    285 347
     
    
    286
    -    def _on_roster_button_press_event(self, treeview, event):
    
    348
    +    def _on_roster_button_press_event(self,
    
    349
    +                                      treeview: Gtk.TreeView,
    
    350
    +                                      event: Gdk.EventButton
    
    351
    +                                      ) -> None:
    
    287 352
             if event.button not in (2, 3):
    
    288 353
                 return
    
    289 354
     
    
    ... ... @@ -307,7 +372,7 @@ def _on_roster_button_press_event(self, treeview, event):
    307 372
             if event.button == 2:  # middle click
    
    308 373
                 self.emit('row-activated', nick)
    
    309 374
     
    
    310
    -    def _show_contact_menu(self, nick):
    
    375
    +    def _show_contact_menu(self, nick: str) -> None:
    
    311 376
             self_contact = self._group_chat_contact.get_self()
    
    312 377
             contact = self._group_chat_contact.get_resource(nick)
    
    313 378
             menu = get_groupchat_roster_menu(self._account,
    
    ... ... @@ -324,11 +389,15 @@ def destroy(menu, _pspec):
    324 389
             menu.connect('notify::visible', destroy)
    
    325 390
             menu.popup_at_pointer()
    
    326 391
     
    
    327
    -    def _tree_compare_iters(self, model, iter1, iter2, _user_data):
    
    392
    +    def _tree_compare_iters(self,
    
    393
    +                            model: Gtk.TreeModel,
    
    394
    +                            iter1: Gtk.TreeIter,
    
    395
    +                            iter2: Gtk.TreeIter,
    
    396
    +                            _user_data: Optional[object]
    
    397
    +                            ) -> int:
    
    328 398
             """
    
    329 399
             Compare two iterators to sort them
    
    330 400
             """
    
    331
    -
    
    332 401
             is_contact = model.iter_parent(iter1)
    
    333 402
             if is_contact:
    
    334 403
                 # Sort contacts with pending events to top
    
    ... ... @@ -356,28 +425,28 @@ def _tree_compare_iters(self, model, iter1, iter2, _user_data):
    356 425
             group2_index = AffiliationRoleSortOrder[group2]
    
    357 426
             return -1 if group1_index < group2_index else 1
    
    358 427
     
    
    359
    -    def enable_sort(self, enable):
    
    428
    +    def enable_sort(self, enable: bool) -> None:
    
    360 429
             column = Gtk.TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID
    
    361 430
             if enable:
    
    362 431
                 column = Column.TEXT
    
    363 432
     
    
    364 433
             self._store.set_sort_column_id(column, Gtk.SortType.ASCENDING)
    
    365 434
     
    
    366
    -    def invalidate_sort(self):
    
    435
    +    def invalidate_sort(self) -> None:
    
    367 436
             self.enable_sort(False)
    
    368 437
             self.enable_sort(True)
    
    369 438
     
    
    370
    -    def initial_draw(self):
    
    439
    +    def initial_draw(self) -> None:
    
    371 440
             self.enable_sort(True)
    
    372 441
             self.set_model()
    
    373 442
             self._roster.expand_all()
    
    374 443
     
    
    375
    -    def redraw(self):
    
    444
    +    def redraw(self) -> None:
    
    376 445
             self._roster.set_model(None)
    
    377 446
             self._roster.set_model(self._store)
    
    378 447
             self._roster.expand_all()
    
    379 448
     
    
    380
    -    def draw_contact(self, nick):
    
    449
    +    def draw_contact(self, nick: str) -> None:
    
    381 450
             iter_ = self._get_contact_iter(nick)
    
    382 451
             if not iter_:
    
    383 452
                 return
    
    ... ... @@ -391,9 +460,9 @@ def draw_contact(self, nick):
    391 460
             name = GLib.markup_escape_text(contact.name)
    
    392 461
     
    
    393 462
             # Strike name if blocked
    
    394
    -        fjid = self.room_jid + '/' + nick
    
    463
    +        fjid = f'{self.room_jid}/{nick}'
    
    395 464
             if jid_is_blocked(self._account, fjid):
    
    396
    -            name = '<span strikethrough="true">%s</span>' % name
    
    465
    +            name = f'<span strikethrough="true">{name}</span>'
    
    397 466
     
    
    398 467
             # add status msg, if not empty, under contact name
    
    399 468
             status = contact.status
    
    ... ... @@ -404,16 +473,16 @@ def draw_contact(self, nick):
    404 473
                 # Display only first line
    
    405 474
                 status = status.split('\n', 1)[0]
    
    406 475
                 # escape markup entities and make them small italic and fg color
    
    407
    -            name += ('\n<span size="small" style="italic" alpha="70%">'
    
    408
    -                     '{}</span>'.format(GLib.markup_escape_text(status)))
    
    476
    +            name += (f'\n<span size="small" style="italic" alpha="70%">'
    
    477
    +                     f'{GLib.markup_escape_text(status)}</span>')
    
    409 478
     
    
    410 479
             self._store[iter_][Column.TEXT] = name
    
    411 480
     
    
    412
    -    def draw_contacts(self):
    
    481
    +    def draw_contacts(self) -> None:
    
    413 482
             for nick in self._contact_refs:
    
    414 483
                 self.draw_contact(nick)
    
    415 484
     
    
    416
    -    def draw_group(self, group):
    
    485
    +    def draw_group(self, group: str) -> None:
    
    417 486
             group_iter = self._get_group_iter(group)
    
    418 487
             if not group_iter:
    
    419 488
                 return
    
    ... ... @@ -426,15 +495,15 @@ def draw_group(self, group):
    426 495
             total_users = self._get_total_user_count()
    
    427 496
             group_users = self._store.iter_n_children(group_iter)
    
    428 497
     
    
    429
    -        group_text += ' (%s/%s)' % (group_users, total_users)
    
    498
    +        group_text += f' ({group_users}/{total_users})'
    
    430 499
     
    
    431 500
             self._store[group_iter][Column.TEXT] = group_text
    
    432 501
     
    
    433
    -    def draw_groups(self):
    
    502
    +    def draw_groups(self) -> None:
    
    434 503
             for group in self._group_refs:
    
    435 504
                 self.draw_group(group)
    
    436 505
     
    
    437
    -    def draw_avatar(self, contact):
    
    506
    +    def draw_avatar(self, contact: types.GroupchatParticipant) -> None:
    
    438 507
             iter_ = self._get_contact_iter(contact.name)
    
    439 508
             if iter_ is None:
    
    440 509
                 return
    
    ... ... @@ -446,13 +515,13 @@ def draw_avatar(self, contact):
    446 515
         def _on_user_avatar_update(self, _contact, _signal_name, user_contact):
    
    447 516
             self.draw_avatar(user_contact)
    
    448 517
     
    
    449
    -    def _get_total_user_count(self):
    
    518
    +    def _get_total_user_count(self) -> int:
    
    450 519
             count = 0
    
    451 520
             for group_row in self._store:
    
    452 521
                 count += self._store.iter_n_children(group_row.iter)
    
    453 522
             return count
    
    454 523
     
    
    455
    -    def get_role(self, nick):
    
    524
    +    def get_role(self, nick: str) -> Role:
    
    456 525
             contact = self._group_chat_contact.get_resource(nick)
    
    457 526
             return contact.role
    
    458 527
     
    
    ... ... @@ -462,12 +531,12 @@ def _on_theme_update(self, _event):
    462 531
         def process_avatar_update(self, event):
    
    463 532
             self.draw_avatar(event.contact)
    
    464 533
     
    
    465
    -    def clear(self):
    
    534
    +    def clear(self) -> None:
    
    466 535
             self._contact_refs = {}
    
    467 536
             self._group_refs = {}
    
    468 537
             self._store.clear()
    
    469 538
     
    
    470
    -    def _on_destroy(self, _roster):
    
    539
    +    def _on_destroy(self, _roster: Any) -> None:
    
    471 540
             self._group_chat_contact.disconnect(self)
    
    472 541
     
    
    473 542
             self._contact_refs = {}
    

  • gajim/gtk/types.py
    ... ... @@ -55,3 +55,5 @@
    55 55
         'PrivateChatControl',
    
    56 56
         'GroupchatControl'
    
    57 57
     ]
    
    58
    +
    
    59
    +GroupchatControlType = Union['GroupchatControl']