Philipp Hörist pushed to branch master at gajim / gajim

Commits:

3 changed files:

Changes:

  • gajim/data/gui/account_wizard.ui
    1 1
     <?xml version="1.0" encoding="UTF-8"?>
    
    2
    -<!-- Generated with glade 3.22.2 -->
    
    2
    +<!-- Generated with glade 3.22.1 -->
    
    3 3
     <interface>
    
    4 4
       <requires lib="gtk+" version="3.20"/>
    
    5 5
       <object class="GtkGrid" id="advanced_grid">
    
    ... ... @@ -313,7 +313,6 @@
    313 313
           <object class="GtkButton" id="sign_up_button">
    
    314 314
             <property name="label" translatable="yes">_Sign Up</property>
    
    315 315
             <property name="visible">True</property>
    
    316
    -        <property name="sensitive">False</property>
    
    317 316
             <property name="can_focus">True</property>
    
    318 317
             <property name="receives_default">True</property>
    
    319 318
             <property name="tooltip_text" translatable="yes">Sign up for a new account on a server of your choice</property>
    
    ... ... @@ -332,6 +331,58 @@
    332 331
         <property name="popup_completion">False</property>
    
    333 332
         <property name="popup_single_match">False</property>
    
    334 333
       </object>
    
    334
    +  <object class="GtkBox" id="redirect_box">
    
    335
    +    <property name="visible">True</property>
    
    336
    +    <property name="can_focus">False</property>
    
    337
    +    <property name="orientation">vertical</property>
    
    338
    +    <property name="spacing">18</property>
    
    339
    +    <child>
    
    340
    +      <object class="GtkImage">
    
    341
    +        <property name="visible">True</property>
    
    342
    +        <property name="can_focus">False</property>
    
    343
    +        <property name="halign">center</property>
    
    344
    +        <property name="icon_name">applications-internet-symbolic</property>
    
    345
    +        <property name="icon_size">6</property>
    
    346
    +      </object>
    
    347
    +      <packing>
    
    348
    +        <property name="expand">False</property>
    
    349
    +        <property name="fill">True</property>
    
    350
    +        <property name="position">0</property>
    
    351
    +      </packing>
    
    352
    +    </child>
    
    353
    +    <child>
    
    354
    +      <object class="GtkLabel" id="instructions">
    
    355
    +        <property name="visible">True</property>
    
    356
    +        <property name="can_focus">False</property>
    
    357
    +        <property name="halign">center</property>
    
    358
    +        <property name="wrap">True</property>
    
    359
    +        <property name="max_width_chars">42</property>
    
    360
    +      </object>
    
    361
    +      <packing>
    
    362
    +        <property name="expand">False</property>
    
    363
    +        <property name="fill">True</property>
    
    364
    +        <property name="position">1</property>
    
    365
    +      </packing>
    
    366
    +    </child>
    
    367
    +    <child>
    
    368
    +      <object class="GtkButton" id="link_button">
    
    369
    +        <property name="label" translatable="yes">Visit Website</property>
    
    370
    +        <property name="visible">True</property>
    
    371
    +        <property name="can_focus">True</property>
    
    372
    +        <property name="receives_default">True</property>
    
    373
    +        <property name="halign">center</property>
    
    374
    +        <property name="use_underline">True</property>
    
    375
    +        <style>
    
    376
    +          <class name="suggested-action"/>
    
    377
    +        </style>
    
    378
    +      </object>
    
    379
    +      <packing>
    
    380
    +        <property name="expand">False</property>
    
    381
    +        <property name="fill">True</property>
    
    382
    +        <property name="position">2</property>
    
    383
    +      </packing>
    
    384
    +    </child>
    
    385
    +  </object>
    
    335 386
       <object class="GtkBox" id="security_warning_box">
    
    336 387
         <property name="visible">True</property>
    
    337 388
         <property name="can_focus">False</property>
    
    ... ... @@ -650,6 +701,7 @@ Creating an account on one server allows you to communicate with contacts from o
    650 701
           <object class="GtkCheckButton" id="sign_up_anonymously">
    
    651 702
             <property name="label" translatable="yes">Sign up Anonymously</property>
    
    652 703
             <property name="visible">True</property>
    
    704
    +        <property name="sensitive">False</property>
    
    653 705
             <property name="can_focus">True</property>
    
    654 706
             <property name="receives_default">False</property>
    
    655 707
             <property name="tooltip_text" translatable="yes">Note: Anonymous accounts are not possible on all servers</property>
    

  • gajim/gtk/account_wizard.py
    ... ... @@ -26,6 +26,7 @@ from nbxmpp.const import Mode
    26 26
     from nbxmpp.const import StreamError
    
    27 27
     from nbxmpp.const import ConnectionProtocol
    
    28 28
     from nbxmpp.const import ConnectionType
    
    29
    +from nbxmpp.util import is_error_result
    
    29 30
     
    
    30 31
     from gajim.common import app
    
    31 32
     from gajim.common import configpaths
    
    ... ... @@ -48,7 +49,7 @@ log = logging.getLogger('gajim.gtk.account_wizard')
    48 49
     
    
    49 50
     class AccountWizard(Assistant):
    
    50 51
         def __init__(self):
    
    51
    -        Assistant.__init__(self)
    
    52
    +        Assistant.__init__(self, height=500)
    
    52 53
     
    
    53 54
             self._destroyed = False
    
    54 55
     
    
    ... ... @@ -61,9 +62,10 @@ class AccountWizard(Assistant):
    61 62
     
    
    62 63
             self.add_pages({'login': Login(self._on_button_clicked),
    
    63 64
                             'signup': Signup(),
    
    64
    -                        'form': Form(),
    
    65 65
                             'advanced': AdvancedSettings(),
    
    66 66
                             'security-warning': SecurityWarning(),
    
    67
    +                        'form': Form(),
    
    68
    +                        'redirect': Redirect(),
    
    67 69
                             'success': Success(),
    
    68 70
                             })
    
    69 71
     
    
    ... ... @@ -94,7 +96,7 @@ class AccountWizard(Assistant):
    94 96
             if page_name in ('login', 'progress'):
    
    95 97
                 return None
    
    96 98
     
    
    97
    -        if page_name == 'error':
    
    99
    +        if page_name in ('error', 'redirect'):
    
    98 100
                 return ['back']
    
    99 101
     
    
    100 102
             if page_name == 'success':
    
    ... ... @@ -159,17 +161,26 @@ class AccountWizard(Assistant):
    159 161
                     self.show_page('login', Gtk.StackTransitionType.SLIDE_RIGHT)
    
    160 162
     
    
    161 163
                 elif page in ('advanced', 'error', 'security-warning'):
    
    162
    -                self.show_page(self._method,
    
    163
    -                               Gtk.StackTransitionType.SLIDE_RIGHT)
    
    164
    +                if (page == 'error' and
    
    165
    +                        self._method == 'signup' and
    
    166
    +                        self.get_page('form').has_form):
    
    167
    +                    self.show_page('form', Gtk.StackTransitionType.SLIDE_RIGHT)
    
    168
    +                else:
    
    169
    +                    self.show_page(self._method,
    
    170
    +                                   Gtk.StackTransitionType.SLIDE_RIGHT)
    
    164 171
     
    
    165 172
                 elif page == 'form':
    
    166
    -                # TODO: Disconnect
    
    167
    -                self.get_page('form').remove_form()
    
    168 173
                     self.show_page('signup', Gtk.StackTransitionType.SLIDE_RIGHT)
    
    174
    +                self.get_page('form').remove_form()
    
    175
    +                self._disconnect()
    
    176
    +
    
    177
    +            elif page == 'redirect':
    
    178
    +                self.show_page('login', Gtk.StackTransitionType.SLIDE_RIGHT)
    
    169 179
     
    
    170 180
         def _on_page_changed(self, _assistant, page_name):
    
    171 181
             if page_name == 'signup':
    
    172 182
                 self._method = page_name
    
    183
    +            self.get_page('signup').focus()
    
    173 184
                 self.set_default_button('signup')
    
    174 185
     
    
    175 186
             elif page_name == 'login':
    
    ... ... @@ -185,15 +196,15 @@ class AccountWizard(Assistant):
    185 196
             elif page_name == 'success':
    
    186 197
                 self.set_default_button('connect')
    
    187 198
     
    
    188
    -        elif page_name == 'error':
    
    199
    +        elif page_name in ('error', 'redirect'):
    
    189 200
                 self.set_default_button('back')
    
    190 201
     
    
    202
    +        elif page_name == 'form':
    
    203
    +            self.set_default_button('signup')
    
    204
    +
    
    191 205
         def update_proxy_list(self):
    
    192 206
             self.get_page('advanced').update_proxy_list()
    
    193 207
     
    
    194
    -    def _on_destroy(self, *args):
    
    195
    -        self._destroyed = True
    
    196
    -
    
    197 208
         def _get_base_client(self,
    
    198 209
                              domain,
    
    199 210
                              username,
    
    ... ... @@ -201,10 +212,10 @@ class AccountWizard(Assistant):
    201 212
                              advanced,
    
    202 213
                              ignore_all_errors):
    
    203 214
     
    
    204
    -        client = Client()
    
    215
    +        client = Client(log_context='Account Wizard')
    
    205 216
             client.set_domain(domain)
    
    206 217
             client.set_username(username)
    
    207
    -        client.set_mode(Mode.LOGIN_TEST)
    
    218
    +        client.set_mode(mode)
    
    208 219
             client.set_ignore_tls_errors(ignore_all_errors)
    
    209 220
             client.set_accepted_certificates(
    
    210 221
                 app.cert_store.get_certificates())
    
    ... ... @@ -223,10 +234,17 @@ class AccountWizard(Assistant):
    223 234
             client.subscribe('connection-failed', self._on_connection_failed)
    
    224 235
             return client
    
    225 236
     
    
    237
    +    def _disconnect(self):
    
    238
    +        if self._client is None:
    
    239
    +            return
    
    240
    +        self._client.remove_subscriptions()
    
    241
    +        self._client.disconnect()
    
    242
    +        self._client = None
    
    243
    +
    
    226 244
         def _test_credentials(self, ignore_all_errors=False):
    
    227 245
             self._show_progress_page(_('Connecting...'),
    
    228 246
                                      _('Connecting to server...'))
    
    229
    -        address, password = self.get_page('login').get_data()
    
    247
    +        address, password = self.get_page('login').get_credentials()
    
    230 248
             jid = JID(address)
    
    231 249
             advanced = self.get_page('login').is_advanced()
    
    232 250
     
    
    ... ... @@ -291,6 +309,10 @@ class AccountWizard(Assistant):
    291 309
                                           _('Signup not allowed'),
    
    292 310
                                           _('This server does not allow signup.'))
    
    293 311
     
    
    312
    +        elif domain == StreamError.STREAM:
    
    313
    +            self._show_error_page(_('Error'), _('Error'), error)
    
    314
    +
    
    315
    +        self.get_page('form').remove_form()
    
    294 316
             self._client.destroy()
    
    295 317
             self._client = None
    
    296 318
     
    
    ... ... @@ -322,27 +344,84 @@ class AccountWizard(Assistant):
    322 344
             return domain
    
    323 345
     
    
    324 346
         def _on_register_form(self, result):
    
    325
    -        if result.form is None:
    
    326
    -            # Invalid form
    
    347
    +        if is_error_result(result):
    
    348
    +            self._show_error_page(_('Error'),
    
    349
    +                                  _('Error'),
    
    350
    +                                  result.get_text())
    
    351
    +            self._disconnect()
    
    327 352
                 return
    
    328 353
     
    
    329 354
             if result.bob_data is not None:
    
    330 355
                 algo_hash = result.bob_data.cid.split('@')[0]
    
    331 356
                 app.bob_cache[algo_hash] = result.bob_data.data
    
    332
    -        self.get_page('form').add_form(result.form)
    
    357
    +
    
    358
    +        form = result.form
    
    359
    +        if result.form is None:
    
    360
    +            form = result.fields_form
    
    361
    +
    
    362
    +        if form is not None:
    
    363
    +            self.get_page('form').add_form(form)
    
    364
    +
    
    365
    +        elif result.oob_url is not None:
    
    366
    +            self.get_page('redirect').set_redirect(result.oob_url,
    
    367
    +                                                   result.instructions)
    
    368
    +            self.show_page('redirect', Gtk.StackTransitionType.SLIDE_LEFT)
    
    369
    +            self._disconnect()
    
    370
    +            return
    
    371
    +
    
    333 372
             self.show_page('form', Gtk.StackTransitionType.SLIDE_LEFT)
    
    334 373
     
    
    335 374
         def _submit_form(self):
    
    336
    -        pass
    
    337
    -        # if self.is_form:
    
    338
    -        #     form = self.get_page('form').get_data_form()
    
    339
    -        # else:
    
    340
    -        #     form = self.get_page('form').get_submit_form()
    
    341
    -        # app.connections[self.account].send_new_account_infos(
    
    342
    -        #     form, self.is_form)
    
    343
    -        # self.get_page('progress').set_text(_('Account is being created'))
    
    344
    -        # self.show_page('progress', Gtk.StackTransitionType.SLIDE_LEFT)
    
    345
    -        # self.get_page('form').remove_form()
    
    375
    +        self.get_page('progress').set_text(_('Account is being created'))
    
    376
    +        self.show_page('progress', Gtk.StackTransitionType.SLIDE_LEFT)
    
    377
    +
    
    378
    +        form = self.get_page('form').get_submit_form()
    
    379
    +        self._client.get_module('Register').submit_register_form(
    
    380
    +            form, callback=self._on_register_result)
    
    381
    +
    
    382
    +    def _on_register_result(self, result):
    
    383
    +        if is_error_result(result):
    
    384
    +            self._on_register_error(result)
    
    385
    +            return
    
    386
    +
    
    387
    +        username, password = self.get_page('form').get_credentials()
    
    388
    +        account = self._generate_account_name(self._client.domain)
    
    389
    +        app.interface.create_account(account,
    
    390
    +                                     username,
    
    391
    +                                     self._client.domain,
    
    392
    +                                     password)
    
    393
    +
    
    394
    +        self.get_page('success').set_account(account)
    
    395
    +        self.show_page('success', Gtk.StackTransitionType.SLIDE_LEFT)
    
    396
    +        self.get_page('form').remove_form()
    
    397
    +        self._disconnect()
    
    398
    +
    
    399
    +    def _on_register_error(self, result):
    
    400
    +        self._show_error_page(_('Error'),
    
    401
    +                              _('Error'),
    
    402
    +                              result.get_text())
    
    403
    +
    
    404
    +        register_data = result.get_date()
    
    405
    +        if register_data is None:
    
    406
    +            # IQ error did not have the payload included
    
    407
    +            self.get_page('form').remove_form()
    
    408
    +            self._disconnect()
    
    409
    +            return
    
    410
    +
    
    411
    +        form = register_data.form
    
    412
    +        if register_data.form is None:
    
    413
    +            form = register_data.fields_form
    
    414
    +
    
    415
    +        if form is not None:
    
    416
    +            self.get_page('form').add_form(form)
    
    417
    +
    
    418
    +        else:
    
    419
    +            self.get_page('form').remove_form()
    
    420
    +            self._disconnect()
    
    421
    +
    
    422
    +    def _on_destroy(self, *args):
    
    423
    +        self._disconnect()
    
    424
    +        self._destroyed = True
    
    346 425
     
    
    347 426
     
    
    348 427
     class Login(Page):
    
    ... ... @@ -445,7 +524,7 @@ class Login(Page):
    445 524
         def is_advanced(self):
    
    446 525
             return self._ui.login_advanced_checkbutton.get_active()
    
    447 526
     
    
    448
    -    def get_data(self):
    
    527
    +    def get_credentials(self):
    
    449 528
             data = (self._ui.log_in_address_entry.get_text(),
    
    450 529
                     self._ui.log_in_password_entry.get_text())
    
    451 530
             return data
    
    ... ... @@ -479,6 +558,9 @@ class Signup(Page):
    479 558
     
    
    480 559
             self.show_all()
    
    481 560
     
    
    561
    +    def focus(self):
    
    562
    +        self._ui.server_comboboxtext_sign_up_entry.grab_focus()
    
    563
    +
    
    482 564
         def _create_server_completion(self):
    
    483 565
             # Parse servers.json
    
    484 566
             server_file_path = os.path.join(
    
    ... ... @@ -663,6 +745,10 @@ class Form(Page):
    663 745
     
    
    664 746
             self.show_all()
    
    665 747
     
    
    748
    +    @property
    
    749
    +    def has_form(self):
    
    750
    +        return self._current_form is not None
    
    751
    +
    
    666 752
         def _on_is_valid(self, _widget, is_valid):
    
    667 753
             self.complete = is_valid
    
    668 754
             self.get_toplevel().update_page_complete()
    
    ... ... @@ -670,20 +756,49 @@ class Form(Page):
    670 756
         def add_form(self, form):
    
    671 757
             self.remove_form()
    
    672 758
     
    
    673
    -        options = {'hide-fallback-fields': True}
    
    759
    +        options = {'hide-fallback-fields': True,
    
    760
    +                   'entry-activates-default': True}
    
    674 761
             self._current_form = DataFormWidget(form, options)
    
    675 762
             self._current_form.connect('is-valid', self._on_is_valid)
    
    676 763
             self._current_form.validate()
    
    677 764
             self.pack_start(self._current_form, True, True, 0)
    
    678 765
             self._current_form.show_all()
    
    679 766
     
    
    767
    +    def get_credentials(self):
    
    768
    +        return (self._current_form.get_form()['username'].value,
    
    769
    +                self._current_form.get_form()['password'].value)
    
    770
    +
    
    680 771
         def get_submit_form(self):
    
    681 772
             return self._current_form.get_submit_form()
    
    682 773
     
    
    683 774
         def remove_form(self):
    
    684
    -        if self._current_form is not None:
    
    685
    -            self.remove(self._current_form)
    
    686
    -            self._current_form.destroy()
    
    775
    +        if self._current_form is None:
    
    776
    +            return
    
    777
    +
    
    778
    +        self.remove(self._current_form)
    
    779
    +        self._current_form.destroy()
    
    780
    +        self._current_form = None
    
    781
    +
    
    782
    +
    
    783
    +class Redirect(Page):
    
    784
    +    def __init__(self):
    
    785
    +        Page.__init__(self)
    
    786
    +        self.title = _('Redirect')
    
    787
    +        self._link = None
    
    788
    +
    
    789
    +        self._ui = get_builder('account_wizard.ui')
    
    790
    +        self.pack_start(self._ui.redirect_box, True, True, 0)
    
    791
    +        self._ui.link_button.connect('clicked', self._on_link_button)
    
    792
    +        self.show_all()
    
    793
    +
    
    794
    +    def set_redirect(self, link, instructions):
    
    795
    +        if instructions is None:
    
    796
    +            instructions = _('Register on the Website')
    
    797
    +        self._ui.instructions.set_text(instructions)
    
    798
    +        self._link = link
    
    799
    +
    
    800
    +    def _on_link_button(self, _button):
    
    801
    +        open_uri(self._link)
    
    687 802
     
    
    688 803
     
    
    689 804
     class Success(Page):
    

  • gajim/gtk/dataform.py
    ... ... @@ -62,6 +62,9 @@ class DataFormWidget(Gtk.ScrolledWindow):
    62 62
         def validate(self):
    
    63 63
             return self._form_grid.validate(True)
    
    64 64
     
    
    65
    +    def get_form(self):
    
    66
    +        return self._form_node
    
    67
    +
    
    65 68
         def get_submit_form(self):
    
    66 69
             self._form_node.type_ = 'submit'
    
    67 70
             return self._form_node
    
    ... ... @@ -257,7 +260,9 @@ class Field:
    257 260
                 form_grid.attach_next_to(self._warning_box,
    
    258 261
                                          self._widget,
    
    259 262
                                          Gtk.PositionType.RIGHT, 1, 1)
    
    260
    -            self._set_warning(False, '')
    
    263
    +
    
    264
    +            is_valid, error = self._field.is_valid()
    
    265
    +            self._set_warning(is_valid, error)
    
    261 266
     
    
    262 267
         def _set_warning(self, is_valid, error):
    
    263 268
             if not self._field.required and not is_valid and not error: