[Git][gajim/gajim][master] 2 commits: Move features dialog into gtk folder
Philipp Hörist
gitlab at dev.gajim.org
Mon Jul 30 00:24:10 CEST 2018
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
b3f1416c by Philipp Hörist at 2018-07-29T21:58:38Z
Move features dialog into gtk folder
- - - - -
a7d9701c by Philipp Hörist at 2018-07-29T22:20:38Z
Move AccountCreationWizard into gtk folder
- - - - -
7 changed files:
- gajim/app_actions.py
- gajim/config.py
- gajim/data/gui/features_window.ui
- gajim/gtk/__init__.py
- + gajim/gtk/account_wizard.py
- gajim/features_window.py → gajim/gtk/features.py
- gajim/roster_window.py
Changes:
=====================================
gajim/app_actions.py
=====================================
--- a/gajim/app_actions.py
+++ b/gajim/app_actions.py
@@ -21,7 +21,6 @@ from gajim.common.app import interface
from gajim.common.exceptions import GajimGeneralException
from gajim import config
from gajim import dialogs
-from gajim import features_window
from gajim import shortcuts_window
from gajim import accounts_window
import gajim.plugins.gui
@@ -38,6 +37,8 @@ from gajim.gtk import XMLConsoleWindow
from gajim.gtk import AboutDialog
from gajim.gtk import PrivacyListsWindow
from gajim.gtk import ManageBookmarksWindow
+from gajim.gtk import FeaturesDialog
+from gajim.gtk import AccountCreationWizard
# General Actions
@@ -176,7 +177,7 @@ def on_add_account(action, param):
app.interface.instances['account_creation_wizard'].window.present()
else:
app.interface.instances['account_creation_wizard'] = \
- config.AccountCreationWizardWindow()
+ AccountCreationWizard()
def on_import_contacts(action, param):
@@ -283,7 +284,7 @@ def on_keyboard_shortcuts(action, param):
def on_features(action, param):
- features_window.FeaturesWindow()
+ FeaturesDialog()
def on_about(action, param):
=====================================
gajim/config.py
=====================================
--- a/gajim/config.py
+++ b/gajim/config.py
@@ -1883,559 +1883,6 @@ class RemoveAccountWindow:
app.interface.instances['accounts'].remove_account(self.account)
self.window.destroy()
-class AccountCreationWizardWindow:
- def __init__(self):
- self.xml = gtkgui_helpers.get_gtk_builder(
- 'account_creation_wizard_window.ui')
- self.window = self.xml.get_object('account_creation_wizard_window')
- active_window = app.app.get_active_window()
- self.window.set_transient_for(active_window)
-
- # Connect events from comboboxtext_entry
- server_comboboxtext = self.xml.get_object('server_comboboxtext')
- entry = self.xml.get_object('server_comboboxtext_entry')
- entry.connect('key_press_event',
- self.on_server_comboboxentry_key_press_event, server_comboboxtext)
-
- server_comboboxtext1 = self.xml.get_object('server_comboboxtext1')
-
- self.update_proxy_list()
-
- # parse servers.xml
- servers_xml = os.path.join(
- configpaths.get('DATA'), 'other', 'servers.xml')
- servers = gtkgui_helpers.parse_server_xml(servers_xml)
- servers_model = self.xml.get_object('server_liststore')
- for server in servers:
- servers_model.append((server,))
-
- server_comboboxtext.set_model(servers_model)
- server_comboboxtext1.set_model(servers_model)
-
- # Generic widgets
- self.notebook = self.xml.get_object('notebook')
- self.cancel_button = self.xml.get_object('cancel_button')
- self.back_button = self.xml.get_object('back_button')
- self.forward_button = self.xml.get_object('forward_button')
- self.finish_button = self.xml.get_object('finish_button')
- self.advanced_button = self.xml.get_object('advanced_button')
- self.finish_label = self.xml.get_object('finish_label')
- self.go_online_checkbutton = self.xml.get_object(
- 'go_online_checkbutton')
- self.show_vcard_checkbutton = self.xml.get_object(
- 'show_vcard_checkbutton')
- self.progressbar = self.xml.get_object('progressbar')
-
- # some vars
- self.update_progressbar_timeout_id = None
-
- self.notebook.set_current_page(0)
- self.xml.connect_signals(self)
- self.window.show_all()
- app.ged.register_event_handler('new-account-connected', ged.GUI1,
- self._nec_new_acc_connected)
- app.ged.register_event_handler('new-account-not-connected', ged.GUI1,
- self._nec_new_acc_not_connected)
- app.ged.register_event_handler('account-created', ged.GUI1,
- self._nec_acc_is_ok)
- app.ged.register_event_handler('account-not-created', ged.GUI1,
- self._nec_acc_is_not_ok)
-
- def on_wizard_window_destroy(self, widget):
- page = self.notebook.get_current_page()
- if page in (4, 5) and self.account in app.connections:
- # connection instance is saved in app.connections and we canceled
- # the addition of the account
- del app.connections[self.account]
- if self.account in app.config.get_per('accounts'):
- app.config.del_per('accounts', self.account)
- app.ged.remove_event_handler('new-account-connected', ged.GUI1,
- self._nec_new_acc_connected)
- app.ged.remove_event_handler('new-account-not-connected', ged.GUI1,
- self._nec_new_acc_not_connected)
- app.ged.remove_event_handler('account-created', ged.GUI1,
- self._nec_acc_is_ok)
- app.ged.remove_event_handler('account-not-created', ged.GUI1,
- self._nec_acc_is_not_ok)
- del app.interface.instances['account_creation_wizard']
-
- def on_save_password_checkbutton_toggled(self, widget):
- self.xml.get_object('password_entry').grab_focus()
-
- def on_cancel_button_clicked(self, widget):
- self.window.destroy()
-
- def on_back_button_clicked(self, widget):
- cur_page = self.notebook.get_current_page()
- self.forward_button.set_sensitive(True)
- if cur_page in (1, 2):
- self.notebook.set_current_page(0)
- self.back_button.set_sensitive(False)
- elif cur_page == 3:
- self.xml.get_object('form_vbox').remove(self.data_form_widget)
- self.notebook.set_current_page(2) # show server page
- elif cur_page == 4:
- if self.account in app.connections:
- del app.connections[self.account]
- if self.account in app.config.get_per('accounts'):
- app.config.del_per('accounts', self.account)
- self.notebook.set_current_page(2)
- self.xml.get_object('form_vbox').remove(self.data_form_widget)
- elif cur_page == 6: # finish page
- self.forward_button.show()
- if self.modify:
- self.notebook.set_current_page(1) # Go to parameters page
- else:
- self.notebook.set_current_page(2) # Go to server page
-
- def on_anonymous_checkbutton1_toggled(self, widget):
- active = widget.get_active()
- self.xml.get_object('username_entry').set_sensitive(not active)
- self.xml.get_object('password_entry').set_sensitive(not active)
- self.xml.get_object('save_password_checkbutton').set_sensitive(
- not active)
-
- def show_finish_page(self):
- self.cancel_button.hide()
- self.back_button.hide()
- self.forward_button.hide()
- if self.modify:
- finish_text = '<big><b>%s</b></big>\n\n%s' % (
- _('Account has been added successfully'),
- _('You can set advanced account options by pressing the '
- 'Advanced button, or later by choosing the Accounts menu item '
- 'under the Edit menu from the main window.'))
- else:
- finish_text = '<big><b>%s</b></big>\n\n%s' % (
- _('Your new account has been created successfully'),
- _('You can set advanced account options by pressing the '
- 'Advanced button, or later by choosing the Accounts menu item '
- 'under the Edit menu from the main window.'))
- self.finish_label.set_markup(finish_text)
- self.finish_button.show()
- self.finish_button.set_property('has-default', True)
- self.advanced_button.show()
- self.go_online_checkbutton.show()
- img = self.xml.get_object('finish_image')
- if self.modify:
- img.set_from_icon_name(Gtk.STOCK_APPLY, Gtk.IconSize.DIALOG)
- else:
- path_to_file = gtkgui_helpers.get_icon_path('org.gajim.Gajim', 48)
- img.set_from_file(path_to_file)
- self.show_vcard_checkbutton.set_active(not self.modify)
- self.notebook.set_current_page(6) # show finish page
-
- def on_forward_button_clicked(self, widget):
- cur_page = self.notebook.get_current_page()
-
- if cur_page == 0:
- widget = self.xml.get_object('use_existing_account_radiobutton')
- if widget.get_active():
- self.modify = True
- self.notebook.set_current_page(1)
- else:
- self.modify = False
- self.notebook.set_current_page(2)
- self.back_button.set_sensitive(True)
- return
-
- elif cur_page == 1:
- # We are adding an existing account
- anonymous = self.xml.get_object('anonymous_checkbutton1').\
- get_active()
- username = self.xml.get_object('username_entry').get_text().strip()
- if not username and not anonymous:
- pritext = _('Invalid username')
- sectext = _(
- 'You must provide a username to configure this account.')
- ErrorDialog(pritext, sectext)
- return
- server = self.xml.get_object('server_comboboxtext_entry').\
- get_text().strip()
- savepass = self.xml.get_object('save_password_checkbutton').\
- get_active()
- password = self.xml.get_object('password_entry').get_text()
-
- if anonymous:
- jid = ''
- else:
- jid = username + '@'
- jid += server
- # check if jid is conform to RFC and stringprep it
- try:
- jid = helpers.parse_jid(jid)
- except helpers.InvalidFormat as s:
- pritext = _('Invalid JID')
- ErrorDialog(pritext, str(s))
- return
-
- self.account = server
- i = 1
- while self.account in app.config.get_per('accounts'):
- self.account = server + str(i)
- i += 1
-
- username, server = app.get_name_and_server_from_jid(jid)
- if self.xml.get_object('anonymous_checkbutton1').get_active():
- self.save_account('', server, False, '', anonymous=True)
- else:
- self.save_account(username, server, savepass, password)
- self.show_finish_page()
- elif cur_page == 2:
- # We are creating a new account
- server = self.xml.get_object('server_comboboxtext_entry1').\
- get_text()
-
- if not server:
- ErrorDialog(_('Invalid server'),
- _('Please provide a server on which you want to register.'))
- return
- self.account = server
- i = 1
- while self.account in app.config.get_per('accounts'):
- self.account = server + str(i)
- i += 1
-
- config = self.get_config('', server, '', '')
- # Get advanced options
- proxies_combobox = self.xml.get_object('proxies_combobox')
- active = proxies_combobox.get_active()
- proxy = proxies_combobox.get_model()[active][0]
- if proxy == _('None'):
- proxy = ''
- config['proxy'] = proxy
-
- config['use_custom_host'] = self.xml.get_object(
- 'custom_host_port_checkbutton').get_active()
- custom_port = self.xml.get_object('custom_port_entry').get_text()
- try:
- custom_port = int(custom_port)
- except Exception:
- ErrorDialog(_('Invalid entry'),
- _('Custom port must be a port number.'))
- return
- config['custom_port'] = custom_port
- config['custom_host'] = self.xml.get_object(
- 'custom_host_entry').get_text()
-
- if self.xml.get_object('anonymous_checkbutton2').get_active():
- self.modify = True
- self.save_account('', server, False, '', anonymous=True)
- self.show_finish_page()
- else:
- self.notebook.set_current_page(5) # show creating page
- self.back_button.hide()
- self.forward_button.hide()
- self.update_progressbar_timeout_id = GLib.timeout_add(100,
- self.update_progressbar)
- # Get form from serveur
- con = connection.Connection(self.account)
- app.connections[self.account] = con
- con.new_account(self.account, config)
- elif cur_page == 3:
- checked = self.xml.get_object('ssl_checkbutton').get_active()
- if checked:
- hostname = app.connections[self.account].new_account_info[
- 'hostname']
- # Check if cert is already in file
- certs = ''
- my_ca_certs = configpaths.get('MY_CACERTS')
- if os.path.isfile(my_ca_certs):
- with open(my_ca_certs) as f:
- certs = f.read()
- if self.ssl_cert in certs:
- ErrorDialog(_('Certificate Already in File'),
- _('This certificate is already in file %s, so it\'s '
- 'not added again.') % my_ca_certs)
- else:
- with open(my_ca_certs, 'a') as f:
- f.write(hostname + '\n')
- f.write(self.ssl_cert + '\n\n')
- app.connections[self.account].new_account_info[
- 'ssl_fingerprint_sha1'] = self.ssl_fingerprint_sha1
- app.connections[self.account].new_account_info[
- 'ssl_fingerprint_sha256'] = self.ssl_fingerprint_sha256
- self.notebook.set_current_page(4) # show fom page
- elif cur_page == 4:
- if self.is_form:
- form = self.data_form_widget.data_form
- else:
- form = self.data_form_widget.get_infos()
- app.connections[self.account].send_new_account_infos(form,
- self.is_form)
- self.xml.get_object('form_vbox').remove(self.data_form_widget)
- self.xml.get_object('progressbar_label').set_markup(
- '<b>Account is being created</b>\n\nPlease wait…')
- self.notebook.set_current_page(5) # show creating page
- self.back_button.hide()
- self.forward_button.hide()
- self.update_progressbar_timeout_id = GLib.timeout_add(100,
- self.update_progressbar)
-
- def update_proxy_list(self):
- proxies_combobox = self.xml.get_object('proxies_combobox')
- model = Gtk.ListStore(str)
- proxies_combobox.set_model(model)
- l = app.config.get_per('proxies')
- l.insert(0, _('None'))
- for i in range(len(l)):
- model.append([l[i]])
- proxies_combobox.set_active(0)
-
- def on_manage_proxies_button_clicked(self, widget):
- if 'manage_proxies' in app.interface.instances:
- app.interface.instances['manage_proxies'].window.present()
- else:
- app.interface.instances['manage_proxies'] = \
- ManageProxiesWindow()
-
- def on_custom_host_port_checkbutton_toggled(self, widget):
- self.xml.get_object('custom_host_hbox').set_sensitive(widget.\
- get_active())
-
- def update_progressbar(self):
- self.progressbar.pulse()
- return True # loop forever
-
- def _nec_new_acc_connected(self, obj):
- """
- Connection to server succeded, present the form to the user
- """
- # We receive events from all accounts from GED
- if obj.conn.name != self.account:
- return
- if self.update_progressbar_timeout_id is not None:
- GLib.source_remove(self.update_progressbar_timeout_id)
- self.back_button.show()
- self.forward_button.show()
- self.is_form = obj.is_form
- empty_config = True
- if obj.is_form:
- dataform = dataforms.ExtendForm(node=obj.config)
- self.data_form_widget = dataforms_widget.DataFormWidget()
- self.data_form_widget.selectable = True
- self.data_form_widget.set_data_form(dataform)
- empty_config = False
- else:
- self.data_form_widget = FakeDataForm(obj.config, selectable=True)
- for field in obj.config:
- if field in ('key', 'instructions', 'x', 'registered'):
- continue
- empty_config = False
- break
- self.data_form_widget.show_all()
- self.xml.get_object('form_vbox').pack_start(self.data_form_widget, True, True, 0)
- if empty_config:
- self.forward_button.set_sensitive(False)
- self.notebook.set_current_page(4) # show form page
- return
- self.ssl_fingerprint_sha1 = obj.ssl_fingerprint_sha1
- self.ssl_fingerprint_sha256 = obj.ssl_fingerprint_sha256
- self.ssl_cert = obj.ssl_cert
- if obj.ssl_msg:
- # An SSL warning occured, show it
- hostname = app.connections[self.account].new_account_info[
- 'hostname']
- self.xml.get_object('ssl_label').set_markup(_(
- '<b>Security Warning</b>'
- '\n\nThe authenticity of the %(hostname)s SSL certificate could'
- ' be invalid.\nSSL Error: %(error)s\n'
- 'Do you still want to connect to this server?') % {
- 'hostname': hostname, 'error': obj.ssl_msg})
- if obj.errnum in (18, 27):
- text = _('Add this certificate to the list of trusted '
- 'certificates.\nSHA-1 fingerprint of the certificate:\n'
- '%(sha1)s\nSHA-256 fingerprint of the certificate:\n'
- '%(sha256)s') % {'sha1': obj.ssl_fingerprint_sha1,
- 'sha256': obj.ssl_fingerprint_sha256}
- self.xml.get_object('ssl_checkbutton').set_label(text)
- else:
- self.xml.get_object('ssl_checkbutton').set_no_show_all(True)
- self.xml.get_object('ssl_checkbutton').hide()
- self.notebook.set_current_page(3) # show SSL page
- else:
- self.notebook.set_current_page(4) # show form page
-
- def _nec_new_acc_not_connected(self, obj):
- """
- Account creation failed: connection to server failed
- """
- # We receive events from all accounts from GED
- if obj.conn.name != self.account:
- return
- if self.account not in app.connections:
- return
- if self.update_progressbar_timeout_id is not None:
- GLib.source_remove(self.update_progressbar_timeout_id)
- del app.connections[self.account]
- if self.account in app.config.get_per('accounts'):
- app.config.del_per('accounts', self.account)
- self.back_button.show()
- self.cancel_button.show()
- self.go_online_checkbutton.hide()
- self.show_vcard_checkbutton.hide()
- img = self.xml.get_object('finish_image')
- img.set_from_icon_name("dialog-error", Gtk.IconSize.DIALOG)
- finish_text = '<big><b>%s</b></big>\n\n%s' % (
- _('An error occurred during account creation'), obj.reason)
- self.finish_label.set_markup(finish_text)
- self.notebook.set_current_page(6) # show finish page
-
- def _nec_acc_is_ok(self, obj):
- """
- Account creation succeeded
- """
- # We receive events from all accounts from GED
- if obj.conn.name != self.account:
- return
- self.create_vars(obj.account_info)
- self.show_finish_page()
-
- if self.update_progressbar_timeout_id is not None:
- GLib.source_remove(self.update_progressbar_timeout_id)
-
- def _nec_acc_is_not_ok(self, obj):
- """
- Account creation failed
- """
- # We receive events from all accounts from GED
- if obj.conn.name != self.account:
- return
- self.back_button.show()
- self.cancel_button.show()
- self.go_online_checkbutton.hide()
- self.show_vcard_checkbutton.hide()
- del app.connections[self.account]
- if self.account in app.config.get_per('accounts'):
- app.config.del_per('accounts', self.account)
- img = self.xml.get_object('finish_image')
- img.set_from_icon_name("dialog-error", Gtk.IconSize.DIALOG)
- finish_text = '<big><b>%s</b></big>\n\n%s' % (_(
- 'An error occurred during account creation'), obj.reason)
- self.finish_label.set_markup(finish_text)
- self.notebook.set_current_page(6) # show finish page
-
- if self.update_progressbar_timeout_id is not None:
- GLib.source_remove(self.update_progressbar_timeout_id)
-
- def on_advanced_button_clicked(self, widget):
- if 'accounts' in app.interface.instances:
- app.interface.instances['accounts'].present()
- else:
- app.interface.instances['accounts'] = AccountsWindow()
- app.interface.instances['accounts'].select_account(self.account)
- self.window.destroy()
-
- def on_finish_button_clicked(self, widget):
- go_online = self.xml.get_object('go_online_checkbutton').get_active()
- show_vcard = self.xml.get_object('show_vcard_checkbutton').get_active()
- self.window.destroy()
- if show_vcard:
- app.interface.show_vcard_when_connect.append(self.account)
- if go_online:
- app.interface.roster.send_status(self.account, 'online', '')
-
- def on_username_entry_key_press_event(self, widget, event):
- # Check for pressed @ and jump to combobox if found
- if event.keyval == Gdk.KEY_at:
- entry = self.xml.get_object('server_comboboxtext_entry')
- entry.grab_focus()
- entry.set_position(-1)
- return True
-
- def on_server_comboboxentry_key_press_event(self, widget, event, combobox):
- # If backspace is pressed in empty field, return to the nick entry field
- backspace = event.keyval == Gdk.KEY_BackSpace
- empty = len(combobox.get_active_text()) == 0
- if backspace and empty and self.modify:
- username_entry = self.xml.get_object('username_entry')
- username_entry.grab_focus()
- username_entry.set_position(-1)
- return True
-
- def get_config(self, login, server, savepass, password, anonymous=False):
- config = {}
- config['name'] = login
- config['account_label'] = '%s@%s' % (login, server)
- config['hostname'] = server
- config['savepass'] = savepass
- config['password'] = password
- config['anonymous_auth'] = anonymous
- config['priority'] = 5
- config['autoconnect'] = True
- config['no_log_for'] = ''
- config['sync_with_global_status'] = True
- config['proxy'] = ''
- config['use_custom_host'] = False
- config['custom_port'] = 0
- config['custom_host'] = ''
- config['keyname'] = ''
- config['keyid'] = ''
- return config
-
- def save_account(self, login, server, savepass, password, anonymous=False):
- if self.account in app.connections:
- ErrorDialog(_('Account name is in use'),
- _('You already have an account using this name.'))
- return
- con = connection.Connection(self.account)
- con.password = password
-
- config = self.get_config(login, server, savepass, password, anonymous)
-
- if not self.modify:
- con.new_account(self.account, config)
- return
- app.connections[self.account] = con
- self.create_vars(config)
-
- def create_vars(self, config):
- app.config.add_per('accounts', self.account)
-
- if not config['savepass']:
- config['password'] = ''
-
- for opt in config:
- app.config.set_per('accounts', self.account, opt, config[opt])
-
- # update variables
- app.interface.instances[self.account] = {'infos': {}, 'disco': {},
- 'gc_config': {}, 'search': {}, 'online_dialog': {},
- 'sub_request': {}}
- app.interface.minimized_controls[self.account] = {}
- app.connections[self.account].connected = 0
- app.connections[self.account].keepalives = app.config.get_per(
- 'accounts', self.account, 'keep_alive_every_foo_secs')
- app.groups[self.account] = {}
- app.contacts.add_account(self.account)
- app.gc_connected[self.account] = {}
- app.automatic_rooms[self.account] = {}
- app.newly_added[self.account] = []
- app.to_be_removed[self.account] = []
- app.nicks[self.account] = config['name']
- app.block_signed_in_notifications[self.account] = True
- app.sleeper_state[self.account] = 'off'
- app.encrypted_chats[self.account] = []
- app.last_message_time[self.account] = {}
- app.status_before_autoaway[self.account] = ''
- app.transport_avatar[self.account] = {}
- app.gajim_optional_features[self.account] = []
- app.caps_hash[self.account] = ''
- helpers.update_optional_features(self.account)
- # action must be added before account window is updated
- app.app.add_account_actions(self.account)
- # refresh accounts window
- if 'accounts' in app.interface.instances:
- app.interface.instances['accounts'].add_account(self.account)
- # refresh roster
- if len(app.connections) >= 2:
- # Do not merge accounts if only one exists
- app.interface.roster.regroup = app.config.get('mergeaccounts')
- else:
- app.interface.roster.regroup = False
- app.interface.roster.setup_and_draw_roster()
- gui_menu_builder.build_accounts_menu()
-
class ManageSoundsWindow:
def __init__(self):
=====================================
gajim/data/gui/features_window.ui
=====================================
--- a/gajim/data/gui/features_window.ui
+++ b/gajim/data/gui/features_window.ui
@@ -1,125 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.20.0 -->
+<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.12"/>
- <object class="GtkWindow" id="features_window">
+ <object class="GtkBox" id="features_box">
+ <property name="width_request">300</property>
+ <property name="height_request">530</property>
+ <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="border_width">12</property>
- <property name="title" translatable="yes">Features</property>
- <property name="default_width">300</property>
- <property name="default_height">530</property>
- <property name="type_hint">dialog</property>
- <signal name="key-press-event" handler="on_key_press_event" swapped="no"/>
+ <property name="margin_left">18</property>
+ <property name="margin_right">18</property>
+ <property name="margin_top">18</property>
+ <property name="margin_bottom">18</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkBox" id="vbox1">
+ <object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes"><b>List of possible features in Gajim:</b></property>
- <property name="use_markup">True</property>
- <property name="xalign">0</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
+ <property name="label" translatable="yes"><b>List of possible features in Gajim:</b></property>
+ <property name="use_markup">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">out</property>
<child>
- <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <object class="GtkTreeView" id="features_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="shadow_type">out</property>
- <child>
- <object class="GtkTreeView" id="features_treeview">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <signal name="cursor-changed" handler="on_features_treeview_cursor_changed" swapped="no"/>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection1"/>
- </child>
- </object>
+ <signal name="cursor-changed" handler="on_features_treeview_cursor_changed" swapped="no"/>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">3</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
<child>
- <object class="GtkButtonBox" id="hbuttonbox1">
+ <object class="GtkLabel" id="feature_desc_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="close_button">
- <property name="label">gtk-close</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="on_close_button_clicked" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
+ <property name="margin_left">12</property>
+ <property name="wrap">True</property>
+ <property name="selectable">True</property>
+ <property name="xalign">0</property>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">2</property>
- </packing>
</child>
- <child>
- <object class="GtkFrame" id="frame2">
+ <child type="label">
+ <object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="border_width">3</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <object class="GtkLabel" id="feature_desc_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="margin_left">12</property>
- <property name="wrap">True</property>
- <property name="selectable">True</property>
- <property name="xalign">0</property>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes"><b>Description</b></property>
- <property name="use_markup">True</property>
- </object>
- </child>
+ <property name="label" translatable="yes"><b>Description</b></property>
+ <property name="use_markup">True</property>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- </packing>
</child>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
</child>
</object>
</interface>
=====================================
gajim/gtk/__init__.py
=====================================
--- a/gajim/gtk/__init__.py
+++ b/gajim/gtk/__init__.py
@@ -1,16 +1,22 @@
# Copyright (C) 2003-2005 Vincent Hanquez <tab AT snarc.org>
+# Copyright (C) 2005 Alex Podaras <bigpod AT gmail.com>
+# Stéphan Kochen <stephan AT kochen.nl>
+# Alex Mauer <hawke AT hawkesnest.net>
# Copyright (C) 2003-2014 Yann Leboulanger <asterix AT lagaule.org>
-# Copyright (C) 2005 Alex Mauer <hawke AT hawkesnest.net>
# Copyright (C) 2005-2006 Dimitur Kirov <dkirov AT gmail.com>
# Travis Shirk <travis AT pobox.com>
# Copyright (C) 2005-2008 Nikos Kouremenos <kourem AT gmail.com>
+# Copyright (C) 2006 Junglecow J <junglecow AT gmail.com>
+# Copyright (C) 2006-2007 Travis Shirk <travis AT pobox.com>
+# Stefan Bethge <stefan AT lanpartei.de>
# Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
-# Copyright (C) 2007 Lukas Petrovicky <lukas AT petrovicky.net>
+# Copyright (C) 2007 James Newton <redshodan AT gmail.com>
+# Lukas Petrovicky <lukas AT petrovicky.net>
# Copyright (C) 2007-2008 Brendan Taylor <whateley AT gmail.com>
# Julien Pivotto <roidelapluie AT gmail.com>
# Stephan Erb <steve-e AT h3c.de>
-# Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
-# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
+# Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
+# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
#
# This file is part of Gajim.
#
@@ -57,3 +63,5 @@ from gajim.gtk.server_info import ServerInfoDialog
from gajim.gtk.pep_config import ManagePEPServicesWindow
from gajim.gtk.bookmarks import ManageBookmarksWindow
from gajim.gtk.profile import ProfileWindow
+from gajim.gtk.features import FeaturesDialog
+from gajim.gtk.account_wizard import AccountCreationWizard
=====================================
gajim/gtk/account_wizard.py
=====================================
--- /dev/null
+++ b/gajim/gtk/account_wizard.py
@@ -0,0 +1,602 @@
+# This file is part of Gajim.
+#
+# Gajim is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation; version 3 only.
+#
+# Gajim is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GLib
+
+from gajim.common import app
+from gajim.common import ged
+from gajim.common import configpaths
+from gajim.common import helpers
+from gajim.common import connection
+from gajim.common.modules import dataforms
+from gajim.gtk.util import get_builder
+from gajim.gtk import ErrorDialog
+from gajim import gtkgui_helpers
+from gajim import dataforms_widget
+from gajim import config
+from gajim import gui_menu_builder
+
+
+class AccountCreationWizard:
+ def __init__(self):
+ self.xml = get_builder('account_creation_wizard_window.ui')
+ self.window = self.xml.get_object('account_creation_wizard_window')
+ active_window = app.app.get_active_window()
+ self.window.set_transient_for(active_window)
+
+ # Connect events from comboboxtext_entry
+ server_comboboxtext = self.xml.get_object('server_comboboxtext')
+ entry = self.xml.get_object('server_comboboxtext_entry')
+ entry.connect('key_press_event',
+ self.on_entry_key_press_event, server_comboboxtext)
+
+ server_comboboxtext1 = self.xml.get_object('server_comboboxtext1')
+
+ self.update_proxy_list()
+
+ # parse servers.xml
+ servers_xml = os.path.join(
+ configpaths.get('DATA'), 'other', 'servers.xml')
+ servers = gtkgui_helpers.parse_server_xml(servers_xml)
+ servers_model = self.xml.get_object('server_liststore')
+ for server in servers:
+ servers_model.append((server,))
+
+ server_comboboxtext.set_model(servers_model)
+ server_comboboxtext1.set_model(servers_model)
+
+ # Generic widgets
+ self.notebook = self.xml.get_object('notebook')
+ self.cancel_button = self.xml.get_object('cancel_button')
+ self.back_button = self.xml.get_object('back_button')
+ self.forward_button = self.xml.get_object('forward_button')
+ self.finish_button = self.xml.get_object('finish_button')
+ self.advanced_button = self.xml.get_object('advanced_button')
+ self.finish_label = self.xml.get_object('finish_label')
+ self.go_online_checkbutton = self.xml.get_object(
+ 'go_online_checkbutton')
+ self.show_vcard_checkbutton = self.xml.get_object(
+ 'show_vcard_checkbutton')
+ self.progressbar = self.xml.get_object('progressbar')
+
+ # some vars
+ self.update_progressbar_timeout_id = None
+
+ self.notebook.set_current_page(0)
+ self.xml.connect_signals(self)
+ self.window.show_all()
+ app.ged.register_event_handler(
+ 'new-account-connected', ged.GUI1,
+ self._nec_new_acc_connected)
+ app.ged.register_event_handler(
+ 'new-account-not-connected', ged.GUI1,
+ self._nec_new_acc_not_connected)
+ app.ged.register_event_handler(
+ 'account-created', ged.GUI1,
+ self._nec_acc_is_ok)
+ app.ged.register_event_handler(
+ 'account-not-created', ged.GUI1,
+ self._nec_acc_is_not_ok)
+
+ def on_wizard_window_destroy(self, widget):
+ page = self.notebook.get_current_page()
+ if page in (4, 5) and self.account in app.connections:
+ # connection instance is saved in app.connections and we canceled
+ # the addition of the account
+ del app.connections[self.account]
+ if self.account in app.config.get_per('accounts'):
+ app.config.del_per('accounts', self.account)
+ app.ged.remove_event_handler(
+ 'new-account-connected', ged.GUI1,
+ self._nec_new_acc_connected)
+ app.ged.remove_event_handler(
+ 'new-account-not-connected', ged.GUI1,
+ self._nec_new_acc_not_connected)
+ app.ged.remove_event_handler(
+ 'account-created', ged.GUI1,
+ self._nec_acc_is_ok)
+ app.ged.remove_event_handler(
+ 'account-not-created', ged.GUI1,
+ self._nec_acc_is_not_ok)
+ del app.interface.instances['account_creation_wizard']
+
+ def on_save_password_checkbutton_toggled(self, widget):
+ self.xml.get_object('password_entry').grab_focus()
+
+ def on_cancel_button_clicked(self, widget):
+ self.window.destroy()
+
+ def on_back_button_clicked(self, widget):
+ cur_page = self.notebook.get_current_page()
+ self.forward_button.set_sensitive(True)
+ if cur_page in (1, 2):
+ self.notebook.set_current_page(0)
+ self.back_button.set_sensitive(False)
+ elif cur_page == 3:
+ self.xml.get_object('form_vbox').remove(self.data_form_widget)
+ self.notebook.set_current_page(2) # show server page
+ elif cur_page == 4:
+ if self.account in app.connections:
+ del app.connections[self.account]
+ if self.account in app.config.get_per('accounts'):
+ app.config.del_per('accounts', self.account)
+ self.notebook.set_current_page(2)
+ self.xml.get_object('form_vbox').remove(self.data_form_widget)
+ elif cur_page == 6: # finish page
+ self.forward_button.show()
+ if self.modify:
+ self.notebook.set_current_page(1) # Go to parameters page
+ else:
+ self.notebook.set_current_page(2) # Go to server page
+
+ def on_anonymous_checkbutton1_toggled(self, widget):
+ active = widget.get_active()
+ self.xml.get_object('username_entry').set_sensitive(not active)
+ self.xml.get_object('password_entry').set_sensitive(not active)
+ self.xml.get_object('save_password_checkbutton').set_sensitive(
+ not active)
+
+ def show_finish_page(self):
+ self.cancel_button.hide()
+ self.back_button.hide()
+ self.forward_button.hide()
+ if self.modify:
+ finish_text = '<big><b>%s</b></big>\n\n%s' % (
+ _('Account has been added successfully'),
+ _('You can set advanced account options by pressing the '
+ 'Advanced button, or later by choosing the Accounts menu item '
+ 'under the Edit menu from the main window.'))
+ else:
+ finish_text = '<big><b>%s</b></big>\n\n%s' % (
+ _('Your new account has been created successfully'),
+ _('You can set advanced account options by pressing the '
+ 'Advanced button, or later by choosing the Accounts menu item '
+ 'under the Edit menu from the main window.'))
+ self.finish_label.set_markup(finish_text)
+ self.finish_button.show()
+ self.finish_button.set_property('has-default', True)
+ self.advanced_button.show()
+ self.go_online_checkbutton.show()
+ img = self.xml.get_object('finish_image')
+ if self.modify:
+ img.set_from_icon_name(Gtk.STOCK_APPLY, Gtk.IconSize.DIALOG)
+ else:
+ path_to_file = gtkgui_helpers.get_icon_path('org.gajim.Gajim', 48)
+ img.set_from_file(path_to_file)
+ self.show_vcard_checkbutton.set_active(not self.modify)
+ self.notebook.set_current_page(6) # show finish page
+
+ def on_forward_button_clicked(self, widget):
+ cur_page = self.notebook.get_current_page()
+
+ if cur_page == 0:
+ widget = self.xml.get_object('use_existing_account_radiobutton')
+ if widget.get_active():
+ self.modify = True
+ self.notebook.set_current_page(1)
+ else:
+ self.modify = False
+ self.notebook.set_current_page(2)
+ self.back_button.set_sensitive(True)
+ return
+
+ elif cur_page == 1:
+ # We are adding an existing account
+ anonymous = self.xml.get_object('anonymous_checkbutton1').\
+ get_active()
+ username = self.xml.get_object('username_entry').get_text().strip()
+ if not username and not anonymous:
+ pritext = _('Invalid username')
+ sectext = _(
+ 'You must provide a username to configure this account.')
+ ErrorDialog(pritext, sectext)
+ return
+ server = self.xml.get_object('server_comboboxtext_entry').\
+ get_text().strip()
+ savepass = self.xml.get_object('save_password_checkbutton').\
+ get_active()
+ password = self.xml.get_object('password_entry').get_text()
+
+ if anonymous:
+ jid = ''
+ else:
+ jid = username + '@'
+ jid += server
+ # check if jid is conform to RFC and stringprep it
+ try:
+ jid = helpers.parse_jid(jid)
+ except helpers.InvalidFormat as s:
+ pritext = _('Invalid JID')
+ ErrorDialog(pritext, str(s))
+ return
+
+ self.account = server
+ i = 1
+ while self.account in app.config.get_per('accounts'):
+ self.account = server + str(i)
+ i += 1
+
+ username, server = app.get_name_and_server_from_jid(jid)
+ if self.xml.get_object('anonymous_checkbutton1').get_active():
+ self.save_account('', server, False, '', anonymous=True)
+ else:
+ self.save_account(username, server, savepass, password)
+ self.show_finish_page()
+ elif cur_page == 2:
+ # We are creating a new account
+ server = self.xml.get_object('server_comboboxtext_entry1').\
+ get_text()
+
+ if not server:
+ ErrorDialog(
+ _('Invalid server'),
+ _('Please provide a server on which you want to register.'))
+ return
+ self.account = server
+ i = 1
+ while self.account in app.config.get_per('accounts'):
+ self.account = server + str(i)
+ i += 1
+
+ config = self.get_config('', server, '', '')
+ # Get advanced options
+ proxies_combobox = self.xml.get_object('proxies_combobox')
+ active = proxies_combobox.get_active()
+ proxy = proxies_combobox.get_model()[active][0]
+ if proxy == _('None'):
+ proxy = ''
+ config['proxy'] = proxy
+
+ config['use_custom_host'] = self.xml.get_object(
+ 'custom_host_port_checkbutton').get_active()
+ custom_port = self.xml.get_object('custom_port_entry').get_text()
+ try:
+ custom_port = int(custom_port)
+ except Exception:
+ ErrorDialog(
+ _('Invalid entry'),
+ _('Custom port must be a port number.'))
+ return
+ config['custom_port'] = custom_port
+ config['custom_host'] = self.xml.get_object(
+ 'custom_host_entry').get_text()
+
+ if self.xml.get_object('anonymous_checkbutton2').get_active():
+ self.modify = True
+ self.save_account('', server, False, '', anonymous=True)
+ self.show_finish_page()
+ else:
+ self.notebook.set_current_page(5) # show creating page
+ self.back_button.hide()
+ self.forward_button.hide()
+ self.update_progressbar_timeout_id = GLib.timeout_add(
+ 100, self.update_progressbar)
+ # Get form from serveur
+ con = connection.Connection(self.account)
+ app.connections[self.account] = con
+ con.new_account(self.account, config)
+ elif cur_page == 3:
+ checked = self.xml.get_object('ssl_checkbutton').get_active()
+ if checked:
+ hostname = app.connections[self.account].new_account_info[
+ 'hostname']
+ # Check if cert is already in file
+ certs = ''
+ my_ca_certs = configpaths.get('MY_CACERTS')
+ if os.path.isfile(my_ca_certs):
+ with open(my_ca_certs) as f:
+ certs = f.read()
+ if self.ssl_cert in certs:
+ ErrorDialog(
+ _('Certificate Already in File'),
+ _('This certificate is already in file %s, so it\'s '
+ 'not added again.') % my_ca_certs)
+ else:
+ with open(my_ca_certs, 'a') as f:
+ f.write(hostname + '\n')
+ f.write(self.ssl_cert + '\n\n')
+ app.connections[self.account].new_account_info[
+ 'ssl_fingerprint_sha1'] = self.ssl_fingerprint_sha1
+ app.connections[self.account].new_account_info[
+ 'ssl_fingerprint_sha256'] = self.ssl_fingerprint_sha256
+ self.notebook.set_current_page(4) # show fom page
+ elif cur_page == 4:
+ if self.is_form:
+ form = self.data_form_widget.data_form
+ else:
+ form = self.data_form_widget.get_infos()
+ app.connections[self.account].send_new_account_infos(
+ form, self.is_form)
+ self.xml.get_object('form_vbox').remove(self.data_form_widget)
+ self.xml.get_object('progressbar_label').set_markup(
+ '<b>Account is being created</b>\n\nPlease wait…')
+ self.notebook.set_current_page(5) # show creating page
+ self.back_button.hide()
+ self.forward_button.hide()
+ self.update_progressbar_timeout_id = GLib.timeout_add(
+ 100, self.update_progressbar)
+
+ def update_proxy_list(self):
+ proxies_combobox = self.xml.get_object('proxies_combobox')
+ model = Gtk.ListStore(str)
+ proxies_combobox.set_model(model)
+ proxies = app.config.get_per('proxies')
+ proxies.insert(0, _('None'))
+ for i in range(len(proxies)):
+ model.append([proxies[i]])
+ proxies_combobox.set_active(0)
+
+ def on_manage_proxies_button_clicked(self, widget):
+ if 'manage_proxies' in app.interface.instances:
+ app.interface.instances['manage_proxies'].window.present()
+ else:
+ app.interface.instances['manage_proxies'] = \
+ config.ManageProxiesWindow()
+
+ def on_custom_host_port_checkbutton_toggled(self, widget):
+ self.xml.get_object('custom_host_hbox').set_sensitive(
+ widget.get_active())
+
+ def update_progressbar(self):
+ self.progressbar.pulse()
+ return True # loop forever
+
+ def _nec_new_acc_connected(self, obj):
+ """
+ Connection to server succeded, present the form to the user
+ """
+ # We receive events from all accounts from GED
+ if obj.conn.name != self.account:
+ return
+ if self.update_progressbar_timeout_id is not None:
+ GLib.source_remove(self.update_progressbar_timeout_id)
+ self.back_button.show()
+ self.forward_button.show()
+ self.is_form = obj.is_form
+ empty_config = True
+ if obj.is_form:
+ dataform = dataforms.ExtendForm(node=obj.config)
+ self.data_form_widget = dataforms_widget.DataFormWidget()
+ self.data_form_widget.selectable = True
+ self.data_form_widget.set_data_form(dataform)
+ empty_config = False
+ else:
+ self.data_form_widget = config.FakeDataForm(
+ obj.config, selectable=True)
+ for field in obj.config:
+ if field in ('key', 'instructions', 'x', 'registered'):
+ continue
+ empty_config = False
+ break
+ self.data_form_widget.show_all()
+ self.xml.get_object('form_vbox').pack_start(
+ self.data_form_widget, True, True, 0)
+ if empty_config:
+ self.forward_button.set_sensitive(False)
+ self.notebook.set_current_page(4) # show form page
+ return
+ self.ssl_fingerprint_sha1 = obj.ssl_fingerprint_sha1
+ self.ssl_fingerprint_sha256 = obj.ssl_fingerprint_sha256
+ self.ssl_cert = obj.ssl_cert
+ if obj.ssl_msg:
+ # An SSL warning occured, show it
+ hostname = app.connections[self.account].new_account_info[
+ 'hostname']
+ self.xml.get_object('ssl_label').set_markup(_(
+ '<b>Security Warning</b>'
+ '\n\nThe authenticity of the %(hostname)s SSL certificate could'
+ ' be invalid.\nSSL Error: %(error)s\n'
+ 'Do you still want to connect to this server?') % {
+ 'hostname': hostname, 'error': obj.ssl_msg})
+ if obj.errnum in (18, 27):
+ text = _(
+ 'Add this certificate to the list of trusted '
+ 'certificates.\nSHA-1 fingerprint of the certificate:\n'
+ '%(sha1)s\nSHA-256 fingerprint of the certificate:\n'
+ '%(sha256)s') % {'sha1': obj.ssl_fingerprint_sha1,
+ 'sha256': obj.ssl_fingerprint_sha256}
+ self.xml.get_object('ssl_checkbutton').set_label(text)
+ else:
+ self.xml.get_object('ssl_checkbutton').set_no_show_all(True)
+ self.xml.get_object('ssl_checkbutton').hide()
+ self.notebook.set_current_page(3) # show SSL page
+ else:
+ self.notebook.set_current_page(4) # show form page
+
+ def _nec_new_acc_not_connected(self, obj):
+ """
+ Account creation failed: connection to server failed
+ """
+ # We receive events from all accounts from GED
+ if obj.conn.name != self.account:
+ return
+ if self.account not in app.connections:
+ return
+ if self.update_progressbar_timeout_id is not None:
+ GLib.source_remove(self.update_progressbar_timeout_id)
+ del app.connections[self.account]
+ if self.account in app.config.get_per('accounts'):
+ app.config.del_per('accounts', self.account)
+ self.back_button.show()
+ self.cancel_button.show()
+ self.go_online_checkbutton.hide()
+ self.show_vcard_checkbutton.hide()
+ img = self.xml.get_object('finish_image')
+ img.set_from_icon_name("dialog-error", Gtk.IconSize.DIALOG)
+ finish_text = '<big><b>%s</b></big>\n\n%s' % (
+ _('An error occurred during account creation'), obj.reason)
+ self.finish_label.set_markup(finish_text)
+ self.notebook.set_current_page(6) # show finish page
+
+ def _nec_acc_is_ok(self, obj):
+ """
+ Account creation succeeded
+ """
+ # We receive events from all accounts from GED
+ if obj.conn.name != self.account:
+ return
+ self.create_vars(obj.account_info)
+ self.show_finish_page()
+
+ if self.update_progressbar_timeout_id is not None:
+ GLib.source_remove(self.update_progressbar_timeout_id)
+
+ def _nec_acc_is_not_ok(self, obj):
+ """
+ Account creation failed
+ """
+ # We receive events from all accounts from GED
+ if obj.conn.name != self.account:
+ return
+ self.back_button.show()
+ self.cancel_button.show()
+ self.go_online_checkbutton.hide()
+ self.show_vcard_checkbutton.hide()
+ del app.connections[self.account]
+ if self.account in app.config.get_per('accounts'):
+ app.config.del_per('accounts', self.account)
+ img = self.xml.get_object('finish_image')
+ img.set_from_icon_name("dialog-error", Gtk.IconSize.DIALOG)
+ finish_text = '<big><b>%s</b></big>\n\n%s' % (_(
+ 'An error occurred during account creation'), obj.reason)
+ self.finish_label.set_markup(finish_text)
+ self.notebook.set_current_page(6) # show finish page
+
+ if self.update_progressbar_timeout_id is not None:
+ GLib.source_remove(self.update_progressbar_timeout_id)
+
+ def on_advanced_button_clicked(self, widget):
+ from gajim.accounts_window import AccountsWindow
+ if 'accounts' in app.interface.instances:
+ app.interface.instances['accounts'].present()
+ else:
+ app.interface.instances['accounts'] = AccountsWindow()
+ app.interface.instances['accounts'].select_account(self.account)
+ self.window.destroy()
+
+ def on_finish_button_clicked(self, widget):
+ go_online = self.xml.get_object('go_online_checkbutton').get_active()
+ show_vcard = self.xml.get_object('show_vcard_checkbutton').get_active()
+ self.window.destroy()
+ if show_vcard:
+ app.interface.show_vcard_when_connect.append(self.account)
+ if go_online:
+ app.interface.roster.send_status(self.account, 'online', '')
+
+ def on_username_entry_key_press_event(self, widget, event):
+ # Check for pressed @ and jump to combobox if found
+ if event.keyval == Gdk.KEY_at:
+ entry = self.xml.get_object('server_comboboxtext_entry')
+ entry.grab_focus()
+ entry.set_position(-1)
+ return True
+
+ def on_entry_key_press_event(self, widget, event, combobox):
+ # If backspace is pressed in empty field, return to the nick entry field
+ backspace = event.keyval == Gdk.KEY_BackSpace
+ empty = len(combobox.get_active_text()) == 0
+ if backspace and empty and self.modify:
+ username_entry = self.xml.get_object('username_entry')
+ username_entry.grab_focus()
+ username_entry.set_position(-1)
+ return True
+
+ def get_config(self, login, server, savepass, password, anonymous=False):
+ config = {}
+ config['name'] = login
+ config['account_label'] = '%s@%s' % (login, server)
+ config['hostname'] = server
+ config['savepass'] = savepass
+ config['password'] = password
+ config['anonymous_auth'] = anonymous
+ config['priority'] = 5
+ config['autoconnect'] = True
+ config['no_log_for'] = ''
+ config['sync_with_global_status'] = True
+ config['proxy'] = ''
+ config['use_custom_host'] = False
+ config['custom_port'] = 0
+ config['custom_host'] = ''
+ config['keyname'] = ''
+ config['keyid'] = ''
+ return config
+
+ def save_account(self, login, server, savepass, password, anonymous=False):
+ if self.account in app.connections:
+ ErrorDialog(
+ _('Account name is in use'),
+ _('You already have an account using this name.'))
+ return
+ con = connection.Connection(self.account)
+ con.password = password
+
+ config = self.get_config(login, server, savepass, password, anonymous)
+
+ if not self.modify:
+ con.new_account(self.account, config)
+ return
+ app.connections[self.account] = con
+ self.create_vars(config)
+
+ def create_vars(self, config):
+ app.config.add_per('accounts', self.account)
+
+ if not config['savepass']:
+ config['password'] = ''
+
+ for opt in config:
+ app.config.set_per('accounts', self.account, opt, config[opt])
+
+ # update variables
+ app.interface.instances[self.account] = {
+ 'infos': {}, 'disco': {},
+ 'gc_config': {}, 'search': {}, 'online_dialog': {},
+ 'sub_request': {}}
+ app.interface.minimized_controls[self.account] = {}
+ app.connections[self.account].connected = 0
+ app.connections[self.account].keepalives = app.config.get_per(
+ 'accounts', self.account, 'keep_alive_every_foo_secs')
+ app.groups[self.account] = {}
+ app.contacts.add_account(self.account)
+ app.gc_connected[self.account] = {}
+ app.automatic_rooms[self.account] = {}
+ app.newly_added[self.account] = []
+ app.to_be_removed[self.account] = []
+ app.nicks[self.account] = config['name']
+ app.block_signed_in_notifications[self.account] = True
+ app.sleeper_state[self.account] = 'off'
+ app.encrypted_chats[self.account] = []
+ app.last_message_time[self.account] = {}
+ app.status_before_autoaway[self.account] = ''
+ app.transport_avatar[self.account] = {}
+ app.gajim_optional_features[self.account] = []
+ app.caps_hash[self.account] = ''
+ helpers.update_optional_features(self.account)
+ # action must be added before account window is updated
+ app.app.add_account_actions(self.account)
+ # refresh accounts window
+ if 'accounts' in app.interface.instances:
+ app.interface.instances['accounts'].add_account(self.account)
+ # refresh roster
+ if len(app.connections) >= 2:
+ # Do not merge accounts if only one exists
+ app.interface.roster.regroup = app.config.get('mergeaccounts')
+ else:
+ app.interface.roster.regroup = False
+ app.interface.roster.setup_and_draw_roster()
+ gui_menu_builder.build_accounts_menu()
=====================================
gajim/features_window.py → gajim/gtk/features.py
=====================================
--- a/gajim/features_window.py
+++ b/gajim/gtk/features.py
@@ -1,83 +1,93 @@
-# -*- coding:utf-8 -*-
-## src/features_window.py
-##
-## Copyright (C) 2007 Jean-Marie Traissard <jim AT lapin.org>
-## Julien Pivotto <roidelapluie AT gmail.com>
-## Stefan Bethge <stefan AT lanpartei.de>
-## Stephan Erb <steve-e AT h3c.de>
-## Copyright (C) 2007-2014 Yann Leboulanger <asterix AT lagaule.org>
-## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
+# Copyright (C) 2007 Jean-Marie Traissard <jim AT lapin.org>
+# Julien Pivotto <roidelapluie AT gmail.com>
+# Stefan Bethge <stefan AT lanpartei.de>
+# Stephan Erb <steve-e AT h3c.de>
+# Copyright (C) 2007-2014 Yann Leboulanger <asterix AT lagaule.org>
+# Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
+#
+# This file is part of Gajim.
+#
+# Gajim is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation; version 3 only.
+#
+# Gajim is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
import os
+
import gi
from gi.repository import Gtk, Gdk
-from gajim import gtkgui_helpers
from gajim.common import app
from gajim.common.i18n import Q_
+from gajim.gtk.util import get_builder
-class FeaturesWindow:
- """
- Class for features window
- """
+class FeaturesDialog(Gtk.Dialog):
def __init__(self):
- self.xml = gtkgui_helpers.get_gtk_builder('features_window.ui')
- self.window = self.xml.get_object('features_window')
- self.window.set_transient_for(app.interface.roster.window)
- treeview = self.xml.get_object('features_treeview')
- self.desc_label = self.xml.get_object('feature_desc_label')
+ flags = Gtk.DialogFlags.DESTROY_WITH_PARENT
+ super().__init__(_('Features'), None, flags)
+
+ self.connect('key-press-event', self.on_key_press_event)
+ self.set_transient_for(app.interface.roster.window)
+
+ self.builder = get_builder('features_window.ui')
+ content = self.get_content_area()
+ content.add(self.builder.get_object('features_box'))
+
+ treeview = self.builder.get_object('features_treeview')
+ self.desc_label = self.builder.get_object('feature_desc_label')
# {name: (available_function, unix_text, windows_text)}
self.features = {
- _('Bonjour / Zeroconf'): (self.zeroconf_available,
+ _('Bonjour / Zeroconf'): (
+ self.zeroconf_available,
_('Serverless chatting with autodetected clients in a local network.'),
_('Requires python-dbus.'),
_('Requires pybonjour and bonjour SDK running (%(url)s)') % {'url': 'https://developer.apple.com/opensource/).'}),
- _('Command line'): (self.dbus_available,
+ _('Command line'): (
+ self.dbus_available,
_('A script to control Gajim via commandline.'),
_('Requires python-dbus.'),
_('Feature not available under Windows.')),
- _('OpenPGP message encryption'): (self.gpg_available,
+ _('OpenPGP message encryption'): (
+ self.gpg_available,
_('Ability to encrypting chat messages with OpenPGP.'),
_('Requires gpg and python-gnupg (%(url)s).') % {'url': 'https://bitbucket.org/vinay.sajip/python-gnupg'},
_('Requires gpg.exe in PATH.')),
- _('Password encryption'): (self.some_keyring_available,
+ _('Password encryption'): (
+ self.some_keyring_available,
_('Passwords can be stored securely and not just in plaintext.'),
_('Requires libsecret and a provider (such as GNOME Keyring and KSecretService).'),
_('On Windows the Windows Credential Vault is used.')),
- _('Spell Checker'): (self.speller_available,
+ _('Spell Checker'): (
+ self.speller_available,
_('Spellchecking of composed messages.'),
_('Requires Gspell'),
_('Requires Gspell')),
- _('Automatic status'): (self.idle_available,
+ _('Automatic status'): (
+ self.idle_available,
_('Ability to measure idle time, in order to set auto status.'),
_('Requires libxss library.'),
_('Requires python2.5.')),
- _('RST Generator'): (self.docutils_available,
+ _('RST Generator'): (
+ self.docutils_available,
_('Generate XHTML output from RST code (see http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html).'),
_('Requires python-docutils.'),
_('Requires python-docutils.')),
- _('Audio / Video'): (self.farstream_available,
+ _('Audio / Video'): (
+ self.farstream_available,
_('Ability to start audio and video chat.'),
_('Requires gir1.2-farstream-0.2, gir1.2-gstreamer-1.0, gstreamer1.0-libav and gstreamer1.0-plugins-ugly.'),
_('Feature not available under Windows.')),
- _('UPnP-IGD'): (self.gupnp_igd_available,
+ _('UPnP-IGD'): (
+ self.gupnp_igd_available,
_('Ability to request your router to forward port for file transfer.'),
_('Requires gir1.2-gupnpigd-1.0.'),
_('Feature not available under Windows.')),
@@ -108,16 +118,15 @@ class FeaturesWindow:
self.model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
- self.xml.connect_signals(self)
- self.window.show_all()
- self.xml.get_object('close_button').grab_focus()
+ self.builder.connect_signals(self)
+ self.show_all()
def on_key_press_event(self, widget, event):
if event.keyval == Gdk.KEY_Escape:
- self.window.destroy()
+ self.destroy()
def on_close_button_clicked(self, widget):
- self.window.destroy()
+ self.destroy()
def on_features_treeview_cursor_changed(self, widget):
selection = widget.get_selection()
=====================================
gajim/roster_window.py
=====================================
--- a/gajim/roster_window.py
+++ b/gajim/roster_window.py
@@ -70,6 +70,7 @@ from gajim.gtk import SingleMessageWindow
from gajim.gtk import AddNewContactWindow
from gajim.gtk import ManagePEPServicesWindow
from gajim.gtk import ManageBookmarksWindow
+from gajim.gtk import AccountCreationWizard
from gajim.common.const import AvatarSize
@@ -5881,7 +5882,7 @@ class RosterWindow:
# if we have no account configured or only Local account but not enabled
def _open_wizard():
app.interface.instances['account_creation_wizard'] = \
- config.AccountCreationWizardWindow()
+ AccountCreationWizard()
# Open wizard only after roster is created, so we can make it
# transient for the roster window
GLib.idle_add(_open_wizard)
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/137bf1f8311c2a244718c738a0963669e713315f...a7d9701c18dabd44801ed17dbe52c2f2245c62c4
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/137bf1f8311c2a244718c738a0963669e713315f...a7d9701c18dabd44801ed17dbe52c2f2245c62c4
You're receiving this email because of your account on dev.gajim.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.gajim.org/pipermail/commits/attachments/20180730/437044a6/attachment-0001.html>
More information about the Commits
mailing list