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

Commits:

5 changed files:

Changes:

  • gajim/gtk/assistant.py
    ... ... @@ -144,8 +144,8 @@ def add_button(self,
    144 144
             self._ui.action_area.pack_end(button, False, False, 0)
    
    145 145
     
    
    146 146
         def add_pages(self, pages: dict[str, Page]):
    
    147
    -        self._pages = pages
    
    148 147
             for name, widget in pages.items():
    
    148
    +            self._pages[name] = widget
    
    149 149
                 widget.connect('update-page-complete', self._update_page_complete)
    
    150 150
                 self._ui.stack.add_named(widget, name)
    
    151 151
     
    

  • gajim/gtk/discovery.py
    ... ... @@ -47,6 +47,7 @@
    47 47
     import nbxmpp
    
    48 48
     from nbxmpp.structs import DiscoIdentity
    
    49 49
     from nbxmpp.namespaces import Namespace
    
    50
    +from nbxmpp.protocol import JID
    
    50 51
     from nbxmpp.errors import StanzaError
    
    51 52
     
    
    52 53
     from gi.repository import GLib
    
    ... ... @@ -1342,7 +1343,7 @@ def _on_register_button_clicked(self, widget=None):
    1342 1343
                 self.window.services_treeview.get_selection().get_selected()
    
    1343 1344
             if not iter_:
    
    1344 1345
                 return
    
    1345
    -        jid = model[iter_][0]
    
    1346
    +        jid = JID.from_string(model[iter_][0])
    
    1346 1347
             if jid:
    
    1347 1348
                 open_window(
    
    1348 1349
                     'ServiceRegistration', account=self.account, address=jid)
    

  • gajim/gtk/roster.py
    ... ... @@ -330,11 +330,10 @@ def _on_contact_info(self,
    330 330
         def _on_modify_gateway(self,
    
    331 331
                                _action: Gio.SimpleAction,
    
    332 332
                                param: GLib.Variant) -> None:
    
    333
    -
    
    334 333
             open_window(
    
    335 334
                 'ServiceRegistration',
    
    336 335
                 account=self._account,
    
    337
    -            address=param.get_string())
    
    336
    +            address=JID.from_string(param.get_string()))
    
    338 337
     
    
    339 338
         def _on_execute_command(self,
    
    340 339
                                 _action: Gio.SimpleAction,
    

  • gajim/gtk/service_registration.py
    ... ... @@ -12,218 +12,192 @@
    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 Any
    
    18
    +from typing import Literal
    
    19
    +from typing import Optional
    
    20
    +from typing import overload
    
    21
    +
    
    15 22
     import logging
    
    16
    -from enum import IntEnum
    
    17 23
     
    
    18 24
     from gi.repository import Gtk
    
    19 25
     
    
    20 26
     from nbxmpp.errors import StanzaError
    
    21 27
     from nbxmpp.errors import MalformedStanzaError
    
    22 28
     from nbxmpp.errors import RegisterStanzaError
    
    29
    +from nbxmpp.protocol import JID
    
    30
    +from nbxmpp.task import Task
    
    23 31
     
    
    24 32
     from gajim.common import app
    
    25 33
     from gajim.common.i18n import _
    
    26 34
     
    
    35
    +from .assistant import Assistant
    
    36
    +from .assistant import ErrorPage
    
    37
    +from .assistant import Page
    
    38
    +from .assistant import ProgressPage
    
    39
    +from .assistant import SuccessPage
    
    27 40
     from .dataform import DataFormWidget
    
    28 41
     
    
    29
    -log = logging.getLogger('gajim.gui.registration')
    
    42
    +log = logging.getLogger('gajim.gui.service_registration')
    
    30 43
     
    
    31 44
     
    
    32
    -class Page(IntEnum):
    
    33
    -    REQUEST = 0
    
    34
    -    FORM = 1
    
    35
    -    SENDING = 2
    
    36
    -    SUCCESS = 3
    
    37
    -    ERROR = 4
    
    45
    +class ServiceRegistration(Assistant):
    
    46
    +    def __init__(self, account: str, address: JID) -> None:
    
    47
    +        Assistant.__init__(self, width= 600, height=400)
    
    48
    +        self.account = account
    
    38 49
     
    
    50
    +        self._client = app.get_client(account)
    
    51
    +        self._service = address
    
    39 52
     
    
    40
    -class ServiceRegistration(Gtk.Assistant):
    
    41
    -    def __init__(self, account, address):
    
    42
    -        Gtk.Assistant.__init__(self)
    
    43
    -        self.account = account
    
    53
    +        self.add_button('register', _('Register'), 'suggested-action')
    
    54
    +        self.add_button('close', _('Close'))
    
    55
    +        self.add_button('back', _('Back'))
    
    44 56
     
    
    45
    -        self._con = app.connections[account]
    
    46
    -        self._agent = address
    
    47
    -        self._data_form_widget = None
    
    57
    +        self.set_button_visible_func(self._visible_func)
    
    48 58
     
    
    49
    -        self.set_application(app.app)
    
    50
    -        self.set_resizable(True)
    
    51
    -        self.set_position(Gtk.WindowPosition.CENTER)
    
    59
    +        self.add_pages({
    
    60
    +            'form': Form(),
    
    61
    +        })
    
    52 62
     
    
    53
    -        self.set_default_size(600, 400)
    
    54
    -        self.get_style_context().add_class('dialog-margin')
    
    63
    +        self.add_default_page('error')
    
    64
    +        self.add_default_page('progress')
    
    65
    +        self.add_default_page('success')
    
    55 66
     
    
    56
    -        self._add_page(RequestPage())
    
    57
    -        self._add_page(FormPage())
    
    58
    -        self._add_page(SendingPage())
    
    59
    -        self._add_page(SuccessfulPage())
    
    60
    -        self._add_page(ErrorPage())
    
    67
    +        self.get_page('error').set_title(_('Registration failed'))
    
    68
    +        self.get_page('error').set_heading(_('Registration failed'))
    
    61 69
     
    
    62
    -        self.connect('prepare', self._on_page_change)
    
    63
    -        self.connect('cancel', self._on_cancel)
    
    64
    -        self.connect('close', self._on_cancel)
    
    70
    +        self.connect('button-clicked', self._on_button_clicked)
    
    65 71
     
    
    66
    -        self._remove_sidebar()
    
    67 72
             self.show_all()
    
    68 73
     
    
    69
    -    def _add_page(self, page):
    
    70
    -        self.append_page(page)
    
    71
    -        self.set_page_type(page, page.type_)
    
    72
    -        self.set_page_title(page, page.title)
    
    73
    -        self.set_page_complete(page, page.complete)
    
    74
    -
    
    75
    -    def _remove_sidebar(self):
    
    76
    -        main_box = self.get_children()[0]
    
    77
    -        sidebar = main_box.get_children()[0]
    
    78
    -        main_box.remove(sidebar)
    
    79
    -
    
    80
    -    def _on_page_change(self, _assistant, _page):
    
    81
    -        if self.get_current_page() == Page.REQUEST:
    
    82
    -            self._con.get_module('Register').request_register_form(
    
    83
    -                self._agent, callback=self._on_register_form)
    
    84
    -        elif self.get_current_page() == Page.SENDING:
    
    74
    +        self._request_form()
    
    75
    +
    
    76
    +    @overload
    
    77
    +    def get_page(self, name: Literal['form']) -> Form: ...
    
    78
    +    @overload
    
    79
    +    def get_page(self, name: Literal['success']) -> SuccessPage: ...
    
    80
    +    @overload
    
    81
    +    def get_page(self, name: Literal['error']) -> ErrorPage: ...
    
    82
    +    @overload
    
    83
    +    def get_page(self, name: Literal['progress']) -> ProgressPage: ...
    
    84
    +
    
    85
    +    def get_page(self, name: str) -> Page:
    
    86
    +        return self._pages[name]
    
    87
    +
    
    88
    +    @staticmethod
    
    89
    +    def _visible_func(_assistant: Assistant, page_name: str) -> list[str]:
    
    90
    +        if page_name == 'form':
    
    91
    +            return ['close', 'register']
    
    92
    +
    
    93
    +        if page_name == 'progress':
    
    94
    +            return []
    
    95
    +
    
    96
    +        if page_name == 'success':
    
    97
    +            return ['close']
    
    98
    +
    
    99
    +        if page_name == 'error':
    
    100
    +            return ['back', 'close']
    
    101
    +        raise ValueError(f'page {page_name} unknown')
    
    102
    +
    
    103
    +    def _on_button_clicked(self, _page: Gtk.Widget, button_name: str) -> None:
    
    104
    +        if button_name == 'register':
    
    85 105
                 self._register()
    
    86
    -            self.commit()
    
    87 106
     
    
    88
    -    def _on_register_form(self, task):
    
    107
    +        if button_name == 'back':
    
    108
    +            self.show_page('form', Gtk.StackTransitionType.SLIDE_RIGHT)
    
    109
    +
    
    110
    +        if button_name == 'close':
    
    111
    +            self.destroy()
    
    112
    +
    
    113
    +    def _request_form(self) -> None:
    
    114
    +        self.get_page('progress').set_title(_('Requesting Register Form'))
    
    115
    +        self.get_page('progress').set_text(
    
    116
    +            _('Requesting register form from server…'))
    
    117
    +        self.show_page('progress')
    
    118
    +
    
    119
    +        self._client.get_module('Register').request_register_form(
    
    120
    +            self._service, callback=self._on_register_form)
    
    121
    +
    
    122
    +    def _on_register_form(self, task: Task) -> None:
    
    89 123
             try:
    
    90 124
                 result = task.finish()
    
    91 125
             except (StanzaError, MalformedStanzaError) as error:
    
    92
    -            self.get_nth_page(Page.ERROR).set_text(error.get_text())
    
    93
    -            self.set_current_page(Page.ERROR)
    
    126
    +            self.get_page('error').set_text(error.get_text())
    
    127
    +            self.show_page('error')
    
    94 128
                 return
    
    95 129
     
    
    96 130
             form = result.form
    
    97 131
             if result.form is None:
    
    98 132
                 form = result.fields_form
    
    99 133
     
    
    100
    -        self._data_form_widget = DataFormWidget(form)
    
    101
    -        self._data_form_widget.connect('is-valid', self._on_is_valid)
    
    102
    -        self._data_form_widget.validate()
    
    103
    -        self.get_nth_page(Page.FORM).set_form(self._data_form_widget)
    
    104
    -        self.set_current_page(Page.FORM)
    
    134
    +        self.get_page('form').add_form(form)
    
    135
    +        self.show_page('form')
    
    105 136
     
    
    106
    -    def _on_is_valid(self, _widget, is_valid):
    
    107
    -        self.set_page_complete(self.get_nth_page(Page.FORM), is_valid)
    
    137
    +    def _register(self) -> None:
    
    138
    +        self.get_page('progress').set_title(_('Registering…'))
    
    139
    +        self.get_page('progress').set_text(_('Registering…'))
    
    140
    +        self.show_page('progress')
    
    108 141
     
    
    109
    -    def _on_cancel(self, _widget):
    
    110
    -        self.destroy()
    
    111
    -
    
    112
    -    def _register(self):
    
    113
    -        form = self._data_form_widget.get_submit_form()
    
    114
    -        self._con.get_module('Register').submit_register_form(
    
    142
    +        form = self.get_page('form').get_submit_form()
    
    143
    +        self._client.get_module('Register').submit_register_form(
    
    115 144
                 form,
    
    116
    -            self._agent,
    
    145
    +            self._service,
    
    117 146
                 callback=self._on_register_result)
    
    118 147
     
    
    119
    -    def _on_register_result(self, task):
    
    148
    +    def _on_register_result(self, task: Task) -> None:
    
    120 149
             try:
    
    121 150
                 task.finish()
    
    122 151
             except (StanzaError,
    
    123 152
                     MalformedStanzaError,
    
    124 153
                     RegisterStanzaError) as error:
    
    125
    -            self.get_nth_page(Page.ERROR).set_text(error.get_text())
    
    126
    -            self.set_current_page(Page.ERROR)
    
    154
    +            self.get_page('error').set_text(error.get_text())
    
    155
    +            self.show_page('error')
    
    127 156
                 return
    
    128 157
     
    
    129
    -        self.set_current_page(Page.SUCCESS)
    
    130
    -
    
    131
    -
    
    132
    -class RequestPage(Gtk.Box):
    
    133
    -
    
    134
    -    type_ = Gtk.AssistantPageType.INTRO
    
    135
    -    title = _('Register')
    
    136
    -    complete = False
    
    137
    -
    
    138
    -    def __init__(self):
    
    139
    -        super().__init__(orientation=Gtk.Orientation.VERTICAL)
    
    140
    -        self.set_spacing(18)
    
    141
    -        spinner = Gtk.Spinner()
    
    142
    -        self.pack_start(spinner, True, True, 0)
    
    143
    -        spinner.start()
    
    158
    +        self.get_page('success').set_title(_('Registration successful'))
    
    159
    +        self.get_page('success').set_text(_('Registration successful'))
    
    160
    +        self.show_page('success')
    
    144 161
     
    
    145 162
     
    
    146
    -class SendingPage(RequestPage):
    
    163
    +class Form(Page):
    
    164
    +    def __init__(self) -> None:
    
    165
    +        Page.__init__(self)
    
    166
    +        self.title = _('Register')
    
    167
    +        self.complete = False
    
    147 168
     
    
    148
    -    type_ = Gtk.AssistantPageType.PROGRESS
    
    149
    -    title = _('Register')
    
    150
    -    complete = False
    
    151
    -
    
    152
    -
    
    153
    -class FormPage(Gtk.Box):
    
    154
    -
    
    155
    -    type_ = Gtk.AssistantPageType.INTRO
    
    156
    -    title = _('Register')
    
    157
    -    complete = True
    
    158
    -
    
    159
    -    def __init__(self):
    
    160
    -        super().__init__(orientation=Gtk.Orientation.VERTICAL)
    
    161
    -        self._form = None
    
    162
    -        self._label = Gtk.Label()
    
    163
    -        self._label.set_no_show_all(True)
    
    164
    -        self._label.get_style_context().add_class('error-color')
    
    165
    -        self.pack_end(self._label, False, False, 0)
    
    166
    -
    
    167
    -    def set_form(self, form, error_text=None):
    
    168
    -        if self._form is not None:
    
    169
    -            self.remove(self._form)
    
    170
    -            self._form.destroy()
    
    171
    -            self._label.hide()
    
    172
    -        self._form = form
    
    173
    -
    
    174
    -        if error_text is not None:
    
    175
    -            self._label.set_text(error_text)
    
    176
    -            self._label.show()
    
    177
    -
    
    178
    -        self.pack_start(form, True, True, 0)
    
    179
    -        self._form.show_all()
    
    180
    -
    
    181
    -
    
    182
    -class SuccessfulPage(Gtk.Box):
    
    183
    -
    
    184
    -    type_ = Gtk.AssistantPageType.SUMMARY
    
    185
    -    title = _('Registration successful')
    
    186
    -    complete = True
    
    187
    -
    
    188
    -    def __init__(self):
    
    189
    -        super().__init__(orientation=Gtk.Orientation.VERTICAL)
    
    190
    -        self.set_spacing(12)
    
    191
    -        self.set_homogeneous(True)
    
    192
    -
    
    193
    -        icon = Gtk.Image.new_from_icon_name('object-select-symbolic',
    
    194
    -                                            Gtk.IconSize.DIALOG)
    
    195
    -        icon.get_style_context().add_class('success-color')
    
    196
    -        icon.set_valign(Gtk.Align.END)
    
    197
    -        label = Gtk.Label(label=_('Registration successful'))
    
    198
    -        label.get_style_context().add_class('bold16')
    
    199
    -        label.set_valign(Gtk.Align.START)
    
    200
    -
    
    201
    -        self.add(icon)
    
    202
    -        self.add(label)
    
    203
    -
    
    204
    -
    
    205
    -class ErrorPage(Gtk.Box):
    
    206
    -
    
    207
    -    type_ = Gtk.AssistantPageType.SUMMARY
    
    208
    -    title = _('Registration failed')
    
    209
    -    complete = True
    
    210
    -
    
    211
    -    def __init__(self):
    
    212
    -        super().__init__(orientation=Gtk.Orientation.VERTICAL)
    
    213
    -        self.set_spacing(12)
    
    214
    -        self.set_homogeneous(True)
    
    169
    +        self._dataform_widget: Optional[DataFormWidget] = None
    
    170
    +        self.show_all()
    
    215 171
     
    
    216
    -        icon = Gtk.Image.new_from_icon_name('dialog-error-symbolic',
    
    217
    -                                            Gtk.IconSize.DIALOG)
    
    218
    -        icon.get_style_context().add_class('error-color')
    
    219
    -        icon.set_valign(Gtk.Align.END)
    
    220
    -        self._label = Gtk.Label()
    
    221
    -        self._label.set_valign(Gtk.Align.START)
    
    222
    -        self._label.set_max_width_chars(50)
    
    223
    -        self._label.set_line_wrap(True)
    
    172
    +    def add_form(self, form: Any) -> None:
    
    173
    +        self.remove_form()
    
    174
    +
    
    175
    +        options = {
    
    176
    +            'form-width': 350,
    
    177
    +            'entry-activates-default': True
    
    178
    +        }
    
    179
    +        self._dataform_widget = DataFormWidget(form, options)
    
    180
    +        self._dataform_widget.set_propagate_natural_height(True)
    
    181
    +        self._dataform_widget.connect('is-valid', self._on_is_valid)
    
    182
    +        self._dataform_widget.validate()
    
    183
    +        self._dataform_widget.show_all()
    
    184
    +        self.add(self._dataform_widget)
    
    185
    +
    
    186
    +    def _on_is_valid(self, _widget: DataFormWidget, is_valid: bool) -> None:
    
    187
    +        self.complete = is_valid
    
    188
    +        self.update_page_complete()
    
    189
    +
    
    190
    +    def get_submit_form(self) -> Any:
    
    191
    +        assert self._dataform_widget is not None
    
    192
    +        return self._dataform_widget.get_submit_form()
    
    193
    +
    
    194
    +    def remove_form(self) -> None:
    
    195
    +        if self._dataform_widget is None:
    
    196
    +            return
    
    224 197
     
    
    225
    -        self.add(icon)
    
    226
    -        self.add(self._label)
    
    198
    +        self.remove(self._dataform_widget)
    
    199
    +        self._dataform_widget.destroy()
    
    200
    +        self._dataform_widget = None
    
    227 201
     
    
    228
    -    def set_text(self, text):
    
    229
    -        self._label.set_text(text)
    202
    +    def get_default_button(self) -> str:
    
    203
    +        return 'register'

  • pyrightconfig.json
    ... ... @@ -100,6 +100,7 @@
    100 100
             "gajim/gtk/resource_selector.py",
    
    101 101
             "gajim/gtk/roster.py",
    
    102 102
             "gajim/gtk/search_view.py",
    
    103
    +        "gajim/gtk/service_registration.py",
    
    103 104
             "gajim/gtk/sidebar_switcher.py",
    
    104 105
             "gajim/gtk/ssl_error_dialog.py",
    
    105 106
             "gajim/gtk/status_icon.py",