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

Commits:

6 changed files:

Changes:

  • gajim/gtk/add_contact.py
    ... ... @@ -36,7 +36,6 @@
    36 36
     from gajim.common.i18n import _
    
    37 37
     from gajim.common.modules.util import as_task
    
    38 38
     
    
    39
    -from .adhoc import AdHocCommand
    
    40 39
     from .assistant import Assistant
    
    41 40
     from .assistant import Page
    
    42 41
     from .assistant import ErrorPage
    
    ... ... @@ -475,7 +474,9 @@ def _on_register_clicked(self, _button: Gtk.Button) -> None:
    475 474
                 address=self._result.jid)
    
    476 475
     
    
    477 476
         def _on_command_clicked(self, _button: Gtk.Button) -> None:
    
    478
    -        AdHocCommand(self._account, self._result.jid)
    
    477
    +        assert self._result is not None
    
    478
    +        open_window(
    
    479
    +            'AdHocCommand', account=self._account, jid=str(self._result.jid))
    
    479 480
     
    
    480 481
     
    
    481 482
     class GroupChat(Page):
    

  • gajim/gtk/adhoc.py
    ... ... @@ -12,6 +12,13 @@
    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
    +
    
    17
    +from typing import cast
    
    18
    +from typing import Any
    
    19
    +from typing import Optional
    
    20
    +from typing import Union
    
    21
    +
    
    15 22
     import logging
    
    16 23
     
    
    17 24
     from gi.repository import Gtk
    
    ... ... @@ -21,6 +28,12 @@
    21 28
     from nbxmpp.modules import dataforms
    
    22 29
     from nbxmpp.errors import StanzaError
    
    23 30
     from nbxmpp.errors import MalformedStanzaError
    
    31
    +from nbxmpp.modules.dataforms import SimpleDataForm
    
    32
    +from nbxmpp.modules.dataforms import MultipleDataForm
    
    33
    +from nbxmpp.simplexml import Node
    
    34
    +from nbxmpp.structs import AdHocCommand
    
    35
    +from nbxmpp.structs import AdHocCommandNote
    
    36
    +from nbxmpp.task import Task
    
    24 37
     
    
    25 38
     from gajim.common import app
    
    26 39
     from gajim.common.i18n import _
    
    ... ... @@ -38,15 +51,15 @@
    38 51
     log = logging.getLogger('gajim.gui.adhoc')
    
    39 52
     
    
    40 53
     
    
    41
    -class AdHocCommand(Assistant):
    
    42
    -    def __init__(self, account, jid=None):
    
    54
    +class AdHocCommands(Assistant):
    
    55
    +    def __init__(self, account: str, jid: Optional[str] = None) -> None:
    
    43 56
             Assistant.__init__(self, width=600, height=500)
    
    57
    +        self.account = account
    
    58
    +        self.jid = jid
    
    44 59
     
    
    45 60
             self._destroyed = False
    
    46 61
     
    
    47 62
             self._client = app.get_client(account)
    
    48
    -        self._account = account
    
    49
    -        self._jid = jid
    
    50 63
     
    
    51 64
             self.add_button('complete', _('Complete'), complete=True,
    
    52 65
                             css_class='suggested-action')
    
    ... ... @@ -78,9 +91,9 @@ def __init__(self, account, jid=None):
    78 91
             self.show_all()
    
    79 92
     
    
    80 93
         @ensure_not_destroyed
    
    81
    -    def _received_command_list(self, task):
    
    94
    +    def _received_command_list(self, task: Task) -> None:
    
    82 95
             try:
    
    83
    -            commands = task.finish()
    
    96
    +            commands = cast(Optional[list[AdHocCommand]], task.finish())
    
    84 97
             except (StanzaError, MalformedStanzaError) as error:
    
    85 98
                 self._set_error(to_user_string(error), False)
    
    86 99
                 return
    
    ... ... @@ -89,13 +102,14 @@ def _received_command_list(self, task):
    89 102
                 self._set_error(_('No commands available'), False)
    
    90 103
                 return
    
    91 104
     
    
    92
    -        self.get_page('commands').add_commands(commands)
    
    105
    +        commands_page = cast(Commands, self.get_page('commands'))
    
    106
    +        commands_page.add_commands(commands)
    
    93 107
             self.show_page('commands')
    
    94 108
     
    
    95 109
         @ensure_not_destroyed
    
    96
    -    def _received_stage(self, task):
    
    110
    +    def _received_stage(self, task: Task) -> None:
    
    97 111
             try:
    
    98
    -            stage = task.finish()
    
    112
    +            stage = cast(AdHocCommand, task.finish())
    
    99 113
             except (StanzaError, MalformedStanzaError) as error:
    
    100 114
                 self._set_error(to_user_string(error), True)
    
    101 115
                 return
    
    ... ... @@ -104,19 +118,23 @@ def _received_stage(self, task):
    104 118
             if stage.is_completed:
    
    105 119
                 page_name = 'completed'
    
    106 120
     
    
    107
    -        page = self.get_page(page_name)
    
    121
    +        page = cast(Union[Stage, Completed], self.get_page(page_name))
    
    108 122
             page.process_stage(stage)
    
    109 123
             self.show_page(page_name)
    
    110 124
     
    
    111
    -    def _set_error(self, text, show_command_button):
    
    112
    -        self.get_page('error').set_show_commands_button(show_command_button)
    
    113
    -        self.get_page('error').set_text(text)
    
    125
    +    def _set_error(self, text: str, show_command_button: bool) -> None:
    
    126
    +        error_page = cast(Error, self.get_page('error'))
    
    127
    +        error_page.set_show_commands_button(show_command_button)
    
    128
    +        error_page.set_text(text)
    
    114 129
             self.show_page('error')
    
    115 130
     
    
    116
    -    def _on_destroy(self, *args):
    
    131
    +    def _on_destroy(self, _widget: Gtk.Widget) -> None:
    
    117 132
             self._destroyed = True
    
    118 133
     
    
    119
    -    def _on_button_clicked(self, _assistant, button_name):
    
    134
    +    def _on_button_clicked(self,
    
    135
    +                           _assistant: AdHocCommands,
    
    136
    +                           button_name: str
    
    137
    +                           ) -> None:
    
    120 138
             if button_name == 'commands':
    
    121 139
                 self.show_page('commands')
    
    122 140
     
    
    ... ... @@ -132,8 +150,9 @@ def _on_button_clicked(self, _assistant, button_name):
    132 150
             else:
    
    133 151
                 raise ValueError('Invalid button name: %s' % button_name)
    
    134 152
     
    
    135
    -    def _on_stage_action(self, action):
    
    136
    -        command, dataform = self.get_page('stage').stage_data
    
    153
    +    def _on_stage_action(self, action: AdHocAction) -> None:
    
    154
    +        stage_page = cast(Stage, self.get_page('stage'))
    
    155
    +        command, dataform = stage_page.stage_data
    
    137 156
             if action == AdHocAction.PREV:
    
    138 157
                 dataform = None
    
    139 158
     
    
    ... ... @@ -144,10 +163,12 @@ def _on_stage_action(self, action):
    144 163
                 callback=self._received_stage)
    
    145 164
     
    
    146 165
             self.show_page('executing')
    
    147
    -        self.get_page('stage').clear()
    
    166
    +        stage_page = cast(Stage, self.get_page('stage'))
    
    167
    +        stage_page.clear()
    
    148 168
     
    
    149
    -    def _on_execute(self, *args):
    
    150
    -        command = self.get_page('commands').get_selected_command()
    
    169
    +    def _on_execute(self, *args: Any) -> None:
    
    170
    +        commands_page = cast(Commands, self.get_page('commands'))
    
    171
    +        command = commands_page.get_selected_command()
    
    151 172
             if command is None:
    
    152 173
                 return
    
    153 174
     
    
    ... ... @@ -158,8 +179,9 @@ def _on_execute(self, *args):
    158 179
     
    
    159 180
             self.show_page('executing')
    
    160 181
     
    
    161
    -    def _on_cancel(self):
    
    162
    -        command, _ = self.get_page('stage').stage_data
    
    182
    +    def _on_cancel(self) -> None:
    
    183
    +        stage_page = cast(Stage, self.get_page('stage'))
    
    184
    +        command, _ = stage_page.stage_data
    
    163 185
             self._client.get_module('AdHocCommands').execute_command(
    
    164 186
                 command, AdHocAction.CANCEL)
    
    165 187
             self.show_page('commands')
    
    ... ... @@ -171,14 +193,14 @@ class Commands(Page):
    171 193
             'execute': (GObject.SignalFlags.RUN_LAST, None, ()),
    
    172 194
         }
    
    173 195
     
    
    174
    -    def __init__(self):
    
    196
    +    def __init__(self) -> None:
    
    175 197
             Page.__init__(self)
    
    176 198
     
    
    177 199
             self.set_valign(Gtk.Align.FILL)
    
    178 200
             self.complete = True
    
    179 201
             self.title = _('Command List')
    
    180 202
     
    
    181
    -        self._commands = {}
    
    203
    +        self._commands: dict[str, AdHocCommand] = {}
    
    182 204
             self._scrolled = Gtk.ScrolledWindow()
    
    183 205
             self._scrolled.get_style_context().add_class('adhoc-scrolled')
    
    184 206
             self._scrolled.set_max_content_height(400)
    
    ... ... @@ -204,33 +226,41 @@ def __init__(self):
    204 226
             self.show_all()
    
    205 227
     
    
    206 228
         @staticmethod
    
    207
    -    def _search_func(model, _column, search_text, iter_):
    
    229
    +    def _search_func(model: Gtk.TreeModel,
    
    230
    +                     _column: int,
    
    231
    +                     search_text: str,
    
    232
    +                     iter_: Gtk.TreeIter
    
    233
    +                     ) -> bool:
    
    208 234
             return search_text.lower() not in model[iter_][0].lower()
    
    209 235
     
    
    210
    -    def _on_row_activate(self, _tree_view, _path, _column):
    
    236
    +    def _on_row_activate(self,
    
    237
    +                         _tree_view: Gtk.TreeView,
    
    238
    +                         _path: Gtk.TreePath,
    
    239
    +                         _column: Gtk.TreeViewColumn
    
    240
    +                         ) -> None:
    
    211 241
             self.emit('execute')
    
    212 242
     
    
    213
    -    def add_commands(self, commands):
    
    243
    +    def add_commands(self, commands: list[AdHocCommand]) -> None:
    
    214 244
             self._store.clear()
    
    215 245
             self._commands = {}
    
    216 246
             for command in commands:
    
    217
    -            key = '%s:%s' % (command.jid, command.node)
    
    247
    +            key = f'{command.jid}:{command.node}'
    
    218 248
                 self._commands[key] = command
    
    219 249
                 self._store.append((command.name, key))
    
    220 250
     
    
    221
    -    def get_selected_command(self):
    
    251
    +    def get_selected_command(self) -> Optional[AdHocCommand]:
    
    222 252
             model, treeiter = self._treeview.get_selection().get_selected()
    
    223 253
             if treeiter is None:
    
    224 254
                 return None
    
    225 255
             key = model[treeiter][1]
    
    226 256
             return self._commands[key]
    
    227 257
     
    
    228
    -    def get_visible_buttons(self):
    
    258
    +    def get_visible_buttons(self) -> list[str]:
    
    229 259
             return ['execute']
    
    230 260
     
    
    231 261
     
    
    232 262
     class Stage(Page):
    
    233
    -    def __init__(self):
    
    263
    +    def __init__(self) -> None:
    
    234 264
             Page.__init__(self)
    
    235 265
     
    
    236 266
             self.set_valign(Gtk.Align.FILL)
    
    ... ... @@ -238,31 +268,35 @@ def __init__(self):
    238 268
             self.title = _('Stage')
    
    239 269
     
    
    240 270
             self._dataform_widget = None
    
    241
    -        self._notes = []
    
    242
    -        self._last_stage_data = None
    
    271
    +        self._notes: list[Gtk.Label] = []
    
    272
    +        self._last_stage_data: Optional[AdHocCommand] = None
    
    243 273
             self.default = None
    
    244 274
             self.show_all()
    
    245 275
     
    
    246 276
         @property
    
    247
    -    def stage_data(self):
    
    277
    +    def stage_data(self) -> tuple[AdHocCommand,
    
    278
    +                                  Union[SimpleDataForm, MultipleDataForm]]:
    
    279
    +        assert self._last_stage_data is not None
    
    280
    +        assert self._dataform_widget is not None
    
    248 281
             return self._last_stage_data, self._dataform_widget.get_submit_form()
    
    249 282
     
    
    250 283
         @property
    
    251
    -    def actions(self):
    
    284
    +    def actions(self) -> Optional[set[AdHocAction]]:
    
    285
    +        assert self._last_stage_data is not None
    
    252 286
             return self._last_stage_data.actions
    
    253 287
     
    
    254
    -    def clear(self):
    
    288
    +    def clear(self) -> None:
    
    255 289
             self._show_form(None)
    
    256 290
             self._show_notes(None)
    
    257 291
             self._last_stage_data = None
    
    258 292
     
    
    259
    -    def process_stage(self, stage_data):
    
    293
    +    def process_stage(self, stage_data: AdHocCommand) -> None:
    
    260 294
             self._last_stage_data = stage_data
    
    261 295
             self._show_notes(stage_data.notes)
    
    262 296
             self._show_form(stage_data.data)
    
    263 297
             self.default = stage_data.default
    
    264 298
     
    
    265
    -    def _show_form(self, form):
    
    299
    +    def _show_form(self, form: Optional[Node]) -> None:
    
    266 300
             if self._dataform_widget is not None:
    
    267 301
                 self.remove(self._dataform_widget)
    
    268 302
                 self._dataform_widget.destroy()
    
    ... ... @@ -276,7 +310,7 @@ def _show_form(self, form):
    276 310
             self._dataform_widget.show_all()
    
    277 311
             self.add(self._dataform_widget)
    
    278 312
     
    
    279
    -    def _show_notes(self, notes):
    
    313
    +    def _show_notes(self, notes: Optional[list[AdHocCommandNote]]):
    
    280 314
             for note in self._notes:
    
    281 315
                 self.remove(note)
    
    282 316
             self._notes = []
    
    ... ... @@ -290,28 +324,28 @@ def _show_notes(self, notes):
    290 324
                 self._notes.append(label)
    
    291 325
                 self.add(label)
    
    292 326
     
    
    293
    -    def _on_is_valid(self, _widget, is_valid):
    
    327
    +    def _on_is_valid(self, _widget: DataFormWidget, is_valid: bool) -> None:
    
    294 328
             self.complete = is_valid
    
    295 329
             self.update_page_complete()
    
    296 330
     
    
    297
    -    def get_visible_buttons(self):
    
    331
    +    def get_visible_buttons(self) -> list[str]:
    
    298 332
             actions = list(map(lambda action: action.value,
    
    299 333
                                self._last_stage_data.actions))
    
    300 334
             return actions
    
    301 335
     
    
    302
    -    def get_default_button(self):
    
    336
    +    def get_default_button(self) -> str:
    
    303 337
             return self._last_stage_data.default.value
    
    304 338
     
    
    305 339
     
    
    306 340
     class Completed(Page):
    
    307
    -    def __init__(self):
    
    341
    +    def __init__(self) -> None:
    
    308 342
             Page.__init__(self)
    
    309 343
     
    
    310 344
             self.set_valign(Gtk.Align.FILL)
    
    311 345
             self.complete = True
    
    312 346
             self.title = _('Completed')
    
    313 347
     
    
    314
    -        self._notes = []
    
    348
    +        self._notes: list[MultiLineLabel] = []
    
    315 349
             self._dataform_widget = None
    
    316 350
     
    
    317 351
             icon = Gtk.Image.new_from_icon_name('object-select-symbolic',
    
    ... ... @@ -331,12 +365,12 @@ def __init__(self):
    331 365
     
    
    332 366
             self.show_all()
    
    333 367
     
    
    334
    -    def process_stage(self, stage_data):
    
    368
    +    def process_stage(self, stage_data: AdHocCommand) -> None:
    
    335 369
             self._show_notes(stage_data.notes)
    
    336 370
             self._show_form(stage_data.data)
    
    337 371
             self._show_icon_text(stage_data.data is None)
    
    338 372
     
    
    339
    -    def _show_icon_text(self, show):
    
    373
    +    def _show_icon_text(self, show: bool) -> None:
    
    340 374
             if show:
    
    341 375
                 self.set_valign(Gtk.Align.CENTER)
    
    342 376
                 self._icon_text.show_all()
    
    ... ... @@ -344,7 +378,7 @@ def _show_icon_text(self, show):
    344 378
                 self.set_valign(Gtk.Align.FILL)
    
    345 379
                 self._icon_text.hide()
    
    346 380
     
    
    347
    -    def _show_form(self, form):
    
    381
    +    def _show_form(self, form: Optional[Node]) -> None:
    
    348 382
             if self._dataform_widget is not None:
    
    349 383
                 self.remove(self._dataform_widget)
    
    350 384
                 self._dataform_widget.destroy()
    
    ... ... @@ -358,7 +392,7 @@ def _show_form(self, form):
    358 392
             self._dataform_widget.show_all()
    
    359 393
             self.add(self._dataform_widget)
    
    360 394
     
    
    361
    -    def _show_notes(self, notes):
    
    395
    +    def _show_notes(self, notes: list[AdHocCommandNote]):
    
    362 396
             for note in self._notes:
    
    363 397
                 self.remove(note)
    
    364 398
             self._notes = []
    
    ... ... @@ -370,35 +404,35 @@ def _show_notes(self, notes):
    370 404
                 self._notes.append(label)
    
    371 405
                 self.add(label)
    
    372 406
     
    
    373
    -    def get_visible_buttons(self):
    
    407
    +    def get_visible_buttons(self) -> list[str]:
    
    374 408
             return ['commands']
    
    375 409
     
    
    376 410
     
    
    377 411
     class Error(ErrorPage):
    
    378
    -    def __init__(self):
    
    412
    +    def __init__(self) -> None:
    
    379 413
             ErrorPage.__init__(self)
    
    380 414
     
    
    381 415
             self._show_commands_button = False
    
    382 416
             self.set_heading(_('An error occurred'))
    
    383 417
     
    
    384
    -    def set_show_commands_button(self, value):
    
    418
    +    def set_show_commands_button(self, value: bool) -> None:
    
    385 419
             self._show_commands_button = value
    
    386 420
     
    
    387
    -    def get_visible_buttons(self):
    
    421
    +    def get_visible_buttons(self) -> list[str]:
    
    388 422
             if self._show_commands_button:
    
    389 423
                 return ['commands']
    
    390
    -        return None
    
    424
    +        return []
    
    391 425
     
    
    392 426
     
    
    393 427
     class Executing(ProgressPage):
    
    394
    -    def __init__(self):
    
    428
    +    def __init__(self) -> None:
    
    395 429
             ProgressPage.__init__(self)
    
    396 430
             self.set_title(_('Executing…'))
    
    397 431
             self.set_text(_('Executing…'))
    
    398 432
     
    
    399 433
     
    
    400 434
     class RequestCommandList(ProgressPage):
    
    401
    -    def __init__(self):
    
    435
    +    def __init__(self) -> None:
    
    402 436
             ProgressPage.__init__(self)
    
    403 437
             self.set_title(_('Requesting Command List'))
    
    404 438
             self.set_text(_('Requesting Command List'))

  • gajim/gtk/const.py
    ... ... @@ -134,6 +134,7 @@ def __str__(self):
    134 134
         'AccountsWindow': 'gajim.gui.accounts',
    
    135 135
         'AccountWizard': 'gajim.gui.account_wizard',
    
    136 136
         'AddContact': 'gajim.gui.add_contact',
    
    137
    +    'AdHocCommands': 'gajim.gui.adhoc',
    
    137 138
         'AdhocMUC': 'gajim.gui.adhoc_muc',
    
    138 139
         'AdvancedConfig': 'gajim.gui.advanced_config',
    
    139 140
         'BlockingList': 'gajim.gui.blocking',
    

  • gajim/gtk/controls/groupchat.py
    ... ... @@ -75,7 +75,6 @@
    75 75
     from gajim.gui.dialogs import ConfirmationDialog
    
    76 76
     from gajim.gui.filechoosers import AvatarChooserDialog
    
    77 77
     from gajim.gui.groupchat_config import GroupchatConfig
    
    78
    -from gajim.gui.adhoc import AdHocCommand
    
    79 78
     from gajim.gui.avatar_selector import AvatarSelector
    
    80 79
     from gajim.gui.dataform import DataFormWidget
    
    81 80
     from gajim.gui.groupchat_info import GroupChatInfoScrolled
    
    ... ... @@ -618,7 +617,7 @@ def _on_execute_command(self,
    618 617
             nick = param.get_string()
    
    619 618
             if nick:
    
    620 619
                 jid += '/' + nick
    
    621
    -        AdHocCommand(self.account, jid)
    
    620
    +        open_window('AdHocCommands', account=self.account, jid=jid)
    
    622 621
     
    
    623 622
         def _on_change_avatar(self, _button: Gtk.Button) -> None:
    
    624 623
             def _on_accept(path: str) -> None:
    

  • gajim/gtk/discovery.py
    ... ... @@ -58,7 +58,6 @@
    58 58
     from gajim.common.i18n import _
    
    59 59
     from gajim.common.const import StyleAttr
    
    60 60
     
    
    61
    -from .adhoc import AdHocCommand
    
    62 61
     from .dialogs import ErrorDialog
    
    63 62
     from .search import Search
    
    64 63
     from .util import icon_exists
    
    ... ... @@ -1332,7 +1331,7 @@ def _on_execute_button_clicked(self, widget=None):
    1332 1331
             if not iter_:
    
    1333 1332
                 return
    
    1334 1333
             service = model[iter_][0]
    
    1335
    -        AdHocCommand(self.account, service)
    
    1334
    +        open_window('AdHocCommands', account=self.account, jid=service)
    
    1336 1335
     
    
    1337 1336
         def _on_register_button_clicked(self, widget=None):
    
    1338 1337
             """
    

  • gajim/gtk/main.py
    ... ... @@ -43,7 +43,6 @@
    43 43
     from gajim.common.ged import EventHelper
    
    44 44
     from gajim.common.modules.bytestream import is_transfer_active
    
    45 45
     
    
    46
    -from .adhoc import AdHocCommand
    
    47 46
     from .account_side_bar import AccountSideBar
    
    48 47
     from .app_side_bar import AppSideBar
    
    49 48
     from .workspace_side_bar import WorkspaceSideBar
    
    ... ... @@ -609,7 +608,7 @@ def contact_info(account: str, jid: str) -> None:
    609 608
         @staticmethod
    
    610 609
         def execute_command(account: str, jid: str) -> None:
    
    611 610
             # TODO: Resource?
    
    612
    -        AdHocCommand(account, jid)
    
    611
    +        open_window('AdHocCommands', account=account, jid=jid)
    
    613 612
     
    
    614 613
         def block_contact(self, account: str, jid: str) -> None:
    
    615 614
             client = app.get_client(account)