Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
b3f1416c
by Philipp Hörist at 2018-07-29T21:58:38Z
-
a7d9701c
by Philipp Hörist at 2018-07-29T22:20:38Z
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:
| ... | ... | @@ -21,7 +21,6 @@ from gajim.common.app import interface |
| 21 | 21 |
from gajim.common.exceptions import GajimGeneralException
|
| 22 | 22 |
from gajim import config
|
| 23 | 23 |
from gajim import dialogs
|
| 24 |
-from gajim import features_window
|
|
| 25 | 24 |
from gajim import shortcuts_window
|
| 26 | 25 |
from gajim import accounts_window
|
| 27 | 26 |
import gajim.plugins.gui
|
| ... | ... | @@ -38,6 +37,8 @@ from gajim.gtk import XMLConsoleWindow |
| 38 | 37 |
from gajim.gtk import AboutDialog
|
| 39 | 38 |
from gajim.gtk import PrivacyListsWindow
|
| 40 | 39 |
from gajim.gtk import ManageBookmarksWindow
|
| 40 |
+from gajim.gtk import FeaturesDialog
|
|
| 41 |
+from gajim.gtk import AccountCreationWizard
|
|
| 41 | 42 |
|
| 42 | 43 |
|
| 43 | 44 |
# General Actions
|
| ... | ... | @@ -176,7 +177,7 @@ def on_add_account(action, param): |
| 176 | 177 |
app.interface.instances['account_creation_wizard'].window.present()
|
| 177 | 178 |
else:
|
| 178 | 179 |
app.interface.instances['account_creation_wizard'] = \
|
| 179 |
- config.AccountCreationWizardWindow()
|
|
| 180 |
+ AccountCreationWizard()
|
|
| 180 | 181 |
|
| 181 | 182 |
|
| 182 | 183 |
def on_import_contacts(action, param):
|
| ... | ... | @@ -283,7 +284,7 @@ def on_keyboard_shortcuts(action, param): |
| 283 | 284 |
|
| 284 | 285 |
|
| 285 | 286 |
def on_features(action, param):
|
| 286 |
- features_window.FeaturesWindow()
|
|
| 287 |
+ FeaturesDialog()
|
|
| 287 | 288 |
|
| 288 | 289 |
|
| 289 | 290 |
def on_about(action, param):
|
| ... | ... | @@ -1883,559 +1883,6 @@ class RemoveAccountWindow: |
| 1883 | 1883 |
app.interface.instances['accounts'].remove_account(self.account)
|
| 1884 | 1884 |
self.window.destroy()
|
| 1885 | 1885 |
|
| 1886 |
-class AccountCreationWizardWindow:
|
|
| 1887 |
- def __init__(self):
|
|
| 1888 |
- self.xml = gtkgui_helpers.get_gtk_builder(
|
|
| 1889 |
- 'account_creation_wizard_window.ui')
|
|
| 1890 |
- self.window = self.xml.get_object('account_creation_wizard_window')
|
|
| 1891 |
- active_window = app.app.get_active_window()
|
|
| 1892 |
- self.window.set_transient_for(active_window)
|
|
| 1893 |
- |
|
| 1894 |
- # Connect events from comboboxtext_entry
|
|
| 1895 |
- server_comboboxtext = self.xml.get_object('server_comboboxtext')
|
|
| 1896 |
- entry = self.xml.get_object('server_comboboxtext_entry')
|
|
| 1897 |
- entry.connect('key_press_event',
|
|
| 1898 |
- self.on_server_comboboxentry_key_press_event, server_comboboxtext)
|
|
| 1899 |
- |
|
| 1900 |
- server_comboboxtext1 = self.xml.get_object('server_comboboxtext1')
|
|
| 1901 |
- |
|
| 1902 |
- self.update_proxy_list()
|
|
| 1903 |
- |
|
| 1904 |
- # parse servers.xml
|
|
| 1905 |
- servers_xml = os.path.join(
|
|
| 1906 |
- configpaths.get('DATA'), 'other', 'servers.xml')
|
|
| 1907 |
- servers = gtkgui_helpers.parse_server_xml(servers_xml)
|
|
| 1908 |
- servers_model = self.xml.get_object('server_liststore')
|
|
| 1909 |
- for server in servers:
|
|
| 1910 |
- servers_model.append((server,))
|
|
| 1911 |
- |
|
| 1912 |
- server_comboboxtext.set_model(servers_model)
|
|
| 1913 |
- server_comboboxtext1.set_model(servers_model)
|
|
| 1914 |
- |
|
| 1915 |
- # Generic widgets
|
|
| 1916 |
- self.notebook = self.xml.get_object('notebook')
|
|
| 1917 |
- self.cancel_button = self.xml.get_object('cancel_button')
|
|
| 1918 |
- self.back_button = self.xml.get_object('back_button')
|
|
| 1919 |
- self.forward_button = self.xml.get_object('forward_button')
|
|
| 1920 |
- self.finish_button = self.xml.get_object('finish_button')
|
|
| 1921 |
- self.advanced_button = self.xml.get_object('advanced_button')
|
|
| 1922 |
- self.finish_label = self.xml.get_object('finish_label')
|
|
| 1923 |
- self.go_online_checkbutton = self.xml.get_object(
|
|
| 1924 |
- 'go_online_checkbutton')
|
|
| 1925 |
- self.show_vcard_checkbutton = self.xml.get_object(
|
|
| 1926 |
- 'show_vcard_checkbutton')
|
|
| 1927 |
- self.progressbar = self.xml.get_object('progressbar')
|
|
| 1928 |
- |
|
| 1929 |
- # some vars
|
|
| 1930 |
- self.update_progressbar_timeout_id = None
|
|
| 1931 |
- |
|
| 1932 |
- self.notebook.set_current_page(0)
|
|
| 1933 |
- self.xml.connect_signals(self)
|
|
| 1934 |
- self.window.show_all()
|
|
| 1935 |
- app.ged.register_event_handler('new-account-connected', ged.GUI1,
|
|
| 1936 |
- self._nec_new_acc_connected)
|
|
| 1937 |
- app.ged.register_event_handler('new-account-not-connected', ged.GUI1,
|
|
| 1938 |
- self._nec_new_acc_not_connected)
|
|
| 1939 |
- app.ged.register_event_handler('account-created', ged.GUI1,
|
|
| 1940 |
- self._nec_acc_is_ok)
|
|
| 1941 |
- app.ged.register_event_handler('account-not-created', ged.GUI1,
|
|
| 1942 |
- self._nec_acc_is_not_ok)
|
|
| 1943 |
- |
|
| 1944 |
- def on_wizard_window_destroy(self, widget):
|
|
| 1945 |
- page = self.notebook.get_current_page()
|
|
| 1946 |
- if page in (4, 5) and self.account in app.connections:
|
|
| 1947 |
- # connection instance is saved in app.connections and we canceled
|
|
| 1948 |
- # the addition of the account
|
|
| 1949 |
- del app.connections[self.account]
|
|
| 1950 |
- if self.account in app.config.get_per('accounts'):
|
|
| 1951 |
- app.config.del_per('accounts', self.account)
|
|
| 1952 |
- app.ged.remove_event_handler('new-account-connected', ged.GUI1,
|
|
| 1953 |
- self._nec_new_acc_connected)
|
|
| 1954 |
- app.ged.remove_event_handler('new-account-not-connected', ged.GUI1,
|
|
| 1955 |
- self._nec_new_acc_not_connected)
|
|
| 1956 |
- app.ged.remove_event_handler('account-created', ged.GUI1,
|
|
| 1957 |
- self._nec_acc_is_ok)
|
|
| 1958 |
- app.ged.remove_event_handler('account-not-created', ged.GUI1,
|
|
| 1959 |
- self._nec_acc_is_not_ok)
|
|
| 1960 |
- del app.interface.instances['account_creation_wizard']
|
|
| 1961 |
- |
|
| 1962 |
- def on_save_password_checkbutton_toggled(self, widget):
|
|
| 1963 |
- self.xml.get_object('password_entry').grab_focus()
|
|
| 1964 |
- |
|
| 1965 |
- def on_cancel_button_clicked(self, widget):
|
|
| 1966 |
- self.window.destroy()
|
|
| 1967 |
- |
|
| 1968 |
- def on_back_button_clicked(self, widget):
|
|
| 1969 |
- cur_page = self.notebook.get_current_page()
|
|
| 1970 |
- self.forward_button.set_sensitive(True)
|
|
| 1971 |
- if cur_page in (1, 2):
|
|
| 1972 |
- self.notebook.set_current_page(0)
|
|
| 1973 |
- self.back_button.set_sensitive(False)
|
|
| 1974 |
- elif cur_page == 3:
|
|
| 1975 |
- self.xml.get_object('form_vbox').remove(self.data_form_widget)
|
|
| 1976 |
- self.notebook.set_current_page(2) # show server page
|
|
| 1977 |
- elif cur_page == 4:
|
|
| 1978 |
- if self.account in app.connections:
|
|
| 1979 |
- del app.connections[self.account]
|
|
| 1980 |
- if self.account in app.config.get_per('accounts'):
|
|
| 1981 |
- app.config.del_per('accounts', self.account)
|
|
| 1982 |
- self.notebook.set_current_page(2)
|
|
| 1983 |
- self.xml.get_object('form_vbox').remove(self.data_form_widget)
|
|
| 1984 |
- elif cur_page == 6: # finish page
|
|
| 1985 |
- self.forward_button.show()
|
|
| 1986 |
- if self.modify:
|
|
| 1987 |
- self.notebook.set_current_page(1) # Go to parameters page
|
|
| 1988 |
- else:
|
|
| 1989 |
- self.notebook.set_current_page(2) # Go to server page
|
|
| 1990 |
- |
|
| 1991 |
- def on_anonymous_checkbutton1_toggled(self, widget):
|
|
| 1992 |
- active = widget.get_active()
|
|
| 1993 |
- self.xml.get_object('username_entry').set_sensitive(not active)
|
|
| 1994 |
- self.xml.get_object('password_entry').set_sensitive(not active)
|
|
| 1995 |
- self.xml.get_object('save_password_checkbutton').set_sensitive(
|
|
| 1996 |
- not active)
|
|
| 1997 |
- |
|
| 1998 |
- def show_finish_page(self):
|
|
| 1999 |
- self.cancel_button.hide()
|
|
| 2000 |
- self.back_button.hide()
|
|
| 2001 |
- self.forward_button.hide()
|
|
| 2002 |
- if self.modify:
|
|
| 2003 |
- finish_text = '<big><b>%s</b></big>\n\n%s' % (
|
|
| 2004 |
- _('Account has been added successfully'),
|
|
| 2005 |
- _('You can set advanced account options by pressing the '
|
|
| 2006 |
- 'Advanced button, or later by choosing the Accounts menu item '
|
|
| 2007 |
- 'under the Edit menu from the main window.'))
|
|
| 2008 |
- else:
|
|
| 2009 |
- finish_text = '<big><b>%s</b></big>\n\n%s' % (
|
|
| 2010 |
- _('Your new account has been created successfully'),
|
|
| 2011 |
- _('You can set advanced account options by pressing the '
|
|
| 2012 |
- 'Advanced button, or later by choosing the Accounts menu item '
|
|
| 2013 |
- 'under the Edit menu from the main window.'))
|
|
| 2014 |
- self.finish_label.set_markup(finish_text)
|
|
| 2015 |
- self.finish_button.show()
|
|
| 2016 |
- self.finish_button.set_property('has-default', True)
|
|
| 2017 |
- self.advanced_button.show()
|
|
| 2018 |
- self.go_online_checkbutton.show()
|
|
| 2019 |
- img = self.xml.get_object('finish_image')
|
|
| 2020 |
- if self.modify:
|
|
| 2021 |
- img.set_from_icon_name(Gtk.STOCK_APPLY, Gtk.IconSize.DIALOG)
|
|
| 2022 |
- else:
|
|
| 2023 |
- path_to_file = gtkgui_helpers.get_icon_path('org.gajim.Gajim', 48)
|
|
| 2024 |
- img.set_from_file(path_to_file)
|
|
| 2025 |
- self.show_vcard_checkbutton.set_active(not self.modify)
|
|
| 2026 |
- self.notebook.set_current_page(6) # show finish page
|
|
| 2027 |
- |
|
| 2028 |
- def on_forward_button_clicked(self, widget):
|
|
| 2029 |
- cur_page = self.notebook.get_current_page()
|
|
| 2030 |
- |
|
| 2031 |
- if cur_page == 0:
|
|
| 2032 |
- widget = self.xml.get_object('use_existing_account_radiobutton')
|
|
| 2033 |
- if widget.get_active():
|
|
| 2034 |
- self.modify = True
|
|
| 2035 |
- self.notebook.set_current_page(1)
|
|
| 2036 |
- else:
|
|
| 2037 |
- self.modify = False
|
|
| 2038 |
- self.notebook.set_current_page(2)
|
|
| 2039 |
- self.back_button.set_sensitive(True)
|
|
| 2040 |
- return
|
|
| 2041 |
- |
|
| 2042 |
- elif cur_page == 1:
|
|
| 2043 |
- # We are adding an existing account
|
|
| 2044 |
- anonymous = self.xml.get_object('anonymous_checkbutton1').\
|
|
| 2045 |
- get_active()
|
|
| 2046 |
- username = self.xml.get_object('username_entry').get_text().strip()
|
|
| 2047 |
- if not username and not anonymous:
|
|
| 2048 |
- pritext = _('Invalid username')
|
|
| 2049 |
- sectext = _(
|
|
| 2050 |
- 'You must provide a username to configure this account.')
|
|
| 2051 |
- ErrorDialog(pritext, sectext)
|
|
| 2052 |
- return
|
|
| 2053 |
- server = self.xml.get_object('server_comboboxtext_entry').\
|
|
| 2054 |
- get_text().strip()
|
|
| 2055 |
- savepass = self.xml.get_object('save_password_checkbutton').\
|
|
| 2056 |
- get_active()
|
|
| 2057 |
- password = self.xml.get_object('password_entry').get_text()
|
|
| 2058 |
- |
|
| 2059 |
- if anonymous:
|
|
| 2060 |
- jid = ''
|
|
| 2061 |
- else:
|
|
| 2062 |
- jid = username + '@'
|
|
| 2063 |
- jid += server
|
|
| 2064 |
- # check if jid is conform to RFC and stringprep it
|
|
| 2065 |
- try:
|
|
| 2066 |
- jid = helpers.parse_jid(jid)
|
|
| 2067 |
- except helpers.InvalidFormat as s:
|
|
| 2068 |
- pritext = _('Invalid JID')
|
|
| 2069 |
- ErrorDialog(pritext, str(s))
|
|
| 2070 |
- return
|
|
| 2071 |
- |
|
| 2072 |
- self.account = server
|
|
| 2073 |
- i = 1
|
|
| 2074 |
- while self.account in app.config.get_per('accounts'):
|
|
| 2075 |
- self.account = server + str(i)
|
|
| 2076 |
- i += 1
|
|
| 2077 |
- |
|
| 2078 |
- username, server = app.get_name_and_server_from_jid(jid)
|
|
| 2079 |
- if self.xml.get_object('anonymous_checkbutton1').get_active():
|
|
| 2080 |
- self.save_account('', server, False, '', anonymous=True)
|
|
| 2081 |
- else:
|
|
| 2082 |
- self.save_account(username, server, savepass, password)
|
|
| 2083 |
- self.show_finish_page()
|
|
| 2084 |
- elif cur_page == 2:
|
|
| 2085 |
- # We are creating a new account
|
|
| 2086 |
- server = self.xml.get_object('server_comboboxtext_entry1').\
|
|
| 2087 |
- get_text()
|
|
| 2088 |
- |
|
| 2089 |
- if not server:
|
|
| 2090 |
- ErrorDialog(_('Invalid server'),
|
|
| 2091 |
- _('Please provide a server on which you want to register.'))
|
|
| 2092 |
- return
|
|
| 2093 |
- self.account = server
|
|
| 2094 |
- i = 1
|
|
| 2095 |
- while self.account in app.config.get_per('accounts'):
|
|
| 2096 |
- self.account = server + str(i)
|
|
| 2097 |
- i += 1
|
|
| 2098 |
- |
|
| 2099 |
- config = self.get_config('', server, '', '')
|
|
| 2100 |
- # Get advanced options
|
|
| 2101 |
- proxies_combobox = self.xml.get_object('proxies_combobox')
|
|
| 2102 |
- active = proxies_combobox.get_active()
|
|
| 2103 |
- proxy = proxies_combobox.get_model()[active][0]
|
|
| 2104 |
- if proxy == _('None'):
|
|
| 2105 |
- proxy = ''
|
|
| 2106 |
- config['proxy'] = proxy
|
|
| 2107 |
- |
|
| 2108 |
- config['use_custom_host'] = self.xml.get_object(
|
|
| 2109 |
- 'custom_host_port_checkbutton').get_active()
|
|
| 2110 |
- custom_port = self.xml.get_object('custom_port_entry').get_text()
|
|
| 2111 |
- try:
|
|
| 2112 |
- custom_port = int(custom_port)
|
|
| 2113 |
- except Exception:
|
|
| 2114 |
- ErrorDialog(_('Invalid entry'),
|
|
| 2115 |
- _('Custom port must be a port number.'))
|
|
| 2116 |
- return
|
|
| 2117 |
- config['custom_port'] = custom_port
|
|
| 2118 |
- config['custom_host'] = self.xml.get_object(
|
|
| 2119 |
- 'custom_host_entry').get_text()
|
|
| 2120 |
- |
|
| 2121 |
- if self.xml.get_object('anonymous_checkbutton2').get_active():
|
|
| 2122 |
- self.modify = True
|
|
| 2123 |
- self.save_account('', server, False, '', anonymous=True)
|
|
| 2124 |
- self.show_finish_page()
|
|
| 2125 |
- else:
|
|
| 2126 |
- self.notebook.set_current_page(5) # show creating page
|
|
| 2127 |
- self.back_button.hide()
|
|
| 2128 |
- self.forward_button.hide()
|
|
| 2129 |
- self.update_progressbar_timeout_id = GLib.timeout_add(100,
|
|
| 2130 |
- self.update_progressbar)
|
|
| 2131 |
- # Get form from serveur
|
|
| 2132 |
- con = connection.Connection(self.account)
|
|
| 2133 |
- app.connections[self.account] = con
|
|
| 2134 |
- con.new_account(self.account, config)
|
|
| 2135 |
- elif cur_page == 3:
|
|
| 2136 |
- checked = self.xml.get_object('ssl_checkbutton').get_active()
|
|
| 2137 |
- if checked:
|
|
| 2138 |
- hostname = app.connections[self.account].new_account_info[
|
|
| 2139 |
- 'hostname']
|
|
| 2140 |
- # Check if cert is already in file
|
|
| 2141 |
- certs = ''
|
|
| 2142 |
- my_ca_certs = configpaths.get('MY_CACERTS')
|
|
| 2143 |
- if os.path.isfile(my_ca_certs):
|
|
| 2144 |
- with open(my_ca_certs) as f:
|
|
| 2145 |
- certs = f.read()
|
|
| 2146 |
- if self.ssl_cert in certs:
|
|
| 2147 |
- ErrorDialog(_('Certificate Already in File'),
|
|
| 2148 |
- _('This certificate is already in file %s, so it\'s '
|
|
| 2149 |
- 'not added again.') % my_ca_certs)
|
|
| 2150 |
- else:
|
|
| 2151 |
- with open(my_ca_certs, 'a') as f:
|
|
| 2152 |
- f.write(hostname + '\n')
|
|
| 2153 |
- f.write(self.ssl_cert + '\n\n')
|
|
| 2154 |
- app.connections[self.account].new_account_info[
|
|
| 2155 |
- 'ssl_fingerprint_sha1'] = self.ssl_fingerprint_sha1
|
|
| 2156 |
- app.connections[self.account].new_account_info[
|
|
| 2157 |
- 'ssl_fingerprint_sha256'] = self.ssl_fingerprint_sha256
|
|
| 2158 |
- self.notebook.set_current_page(4) # show fom page
|
|
| 2159 |
- elif cur_page == 4:
|
|
| 2160 |
- if self.is_form:
|
|
| 2161 |
- form = self.data_form_widget.data_form
|
|
| 2162 |
- else:
|
|
| 2163 |
- form = self.data_form_widget.get_infos()
|
|
| 2164 |
- app.connections[self.account].send_new_account_infos(form,
|
|
| 2165 |
- self.is_form)
|
|
| 2166 |
- self.xml.get_object('form_vbox').remove(self.data_form_widget)
|
|
| 2167 |
- self.xml.get_object('progressbar_label').set_markup(
|
|
| 2168 |
- '<b>Account is being created</b>\n\nPlease wait…')
|
|
| 2169 |
- self.notebook.set_current_page(5) # show creating page
|
|
| 2170 |
- self.back_button.hide()
|
|
| 2171 |
- self.forward_button.hide()
|
|
| 2172 |
- self.update_progressbar_timeout_id = GLib.timeout_add(100,
|
|
| 2173 |
- self.update_progressbar)
|
|
| 2174 |
- |
|
| 2175 |
- def update_proxy_list(self):
|
|
| 2176 |
- proxies_combobox = self.xml.get_object('proxies_combobox')
|
|
| 2177 |
- model = Gtk.ListStore(str)
|
|
| 2178 |
- proxies_combobox.set_model(model)
|
|
| 2179 |
- l = app.config.get_per('proxies')
|
|
| 2180 |
- l.insert(0, _('None'))
|
|
| 2181 |
- for i in range(len(l)):
|
|
| 2182 |
- model.append([l[i]])
|
|
| 2183 |
- proxies_combobox.set_active(0)
|
|
| 2184 |
- |
|
| 2185 |
- def on_manage_proxies_button_clicked(self, widget):
|
|
| 2186 |
- if 'manage_proxies' in app.interface.instances:
|
|
| 2187 |
- app.interface.instances['manage_proxies'].window.present()
|
|
| 2188 |
- else:
|
|
| 2189 |
- app.interface.instances['manage_proxies'] = \
|
|
| 2190 |
- ManageProxiesWindow()
|
|
| 2191 |
- |
|
| 2192 |
- def on_custom_host_port_checkbutton_toggled(self, widget):
|
|
| 2193 |
- self.xml.get_object('custom_host_hbox').set_sensitive(widget.\
|
|
| 2194 |
- get_active())
|
|
| 2195 |
- |
|
| 2196 |
- def update_progressbar(self):
|
|
| 2197 |
- self.progressbar.pulse()
|
|
| 2198 |
- return True # loop forever
|
|
| 2199 |
- |
|
| 2200 |
- def _nec_new_acc_connected(self, obj):
|
|
| 2201 |
- """
|
|
| 2202 |
- Connection to server succeded, present the form to the user
|
|
| 2203 |
- """
|
|
| 2204 |
- # We receive events from all accounts from GED
|
|
| 2205 |
- if obj.conn.name != self.account:
|
|
| 2206 |
- return
|
|
| 2207 |
- if self.update_progressbar_timeout_id is not None:
|
|
| 2208 |
- GLib.source_remove(self.update_progressbar_timeout_id)
|
|
| 2209 |
- self.back_button.show()
|
|
| 2210 |
- self.forward_button.show()
|
|
| 2211 |
- self.is_form = obj.is_form
|
|
| 2212 |
- empty_config = True
|
|
| 2213 |
- if obj.is_form:
|
|
| 2214 |
- dataform = dataforms.ExtendForm(node=obj.config)
|
|
| 2215 |
- self.data_form_widget = dataforms_widget.DataFormWidget()
|
|
| 2216 |
- self.data_form_widget.selectable = True
|
|
| 2217 |
- self.data_form_widget.set_data_form(dataform)
|
|
| 2218 |
- empty_config = False
|
|
| 2219 |
- else:
|
|
| 2220 |
- self.data_form_widget = FakeDataForm(obj.config, selectable=True)
|
|
| 2221 |
- for field in obj.config:
|
|
| 2222 |
- if field in ('key', 'instructions', 'x', 'registered'):
|
|
| 2223 |
- continue
|
|
| 2224 |
- empty_config = False
|
|
| 2225 |
- break
|
|
| 2226 |
- self.data_form_widget.show_all()
|
|
| 2227 |
- self.xml.get_object('form_vbox').pack_start(self.data_form_widget, True, True, 0)
|
|
| 2228 |
- if empty_config:
|
|
| 2229 |
- self.forward_button.set_sensitive(False)
|
|
| 2230 |
- self.notebook.set_current_page(4) # show form page
|
|
| 2231 |
- return
|
|
| 2232 |
- self.ssl_fingerprint_sha1 = obj.ssl_fingerprint_sha1
|
|
| 2233 |
- self.ssl_fingerprint_sha256 = obj.ssl_fingerprint_sha256
|
|
| 2234 |
- self.ssl_cert = obj.ssl_cert
|
|
| 2235 |
- if obj.ssl_msg:
|
|
| 2236 |
- # An SSL warning occured, show it
|
|
| 2237 |
- hostname = app.connections[self.account].new_account_info[
|
|
| 2238 |
- 'hostname']
|
|
| 2239 |
- self.xml.get_object('ssl_label').set_markup(_(
|
|
| 2240 |
- '<b>Security Warning</b>'
|
|
| 2241 |
- '\n\nThe authenticity of the %(hostname)s SSL certificate could'
|
|
| 2242 |
- ' be invalid.\nSSL Error: %(error)s\n'
|
|
| 2243 |
- 'Do you still want to connect to this server?') % {
|
|
| 2244 |
- 'hostname': hostname, 'error': obj.ssl_msg})
|
|
| 2245 |
- if obj.errnum in (18, 27):
|
|
| 2246 |
- text = _('Add this certificate to the list of trusted '
|
|
| 2247 |
- 'certificates.\nSHA-1 fingerprint of the certificate:\n'
|
|
| 2248 |
- '%(sha1)s\nSHA-256 fingerprint of the certificate:\n'
|
|
| 2249 |
- '%(sha256)s') % {'sha1': obj.ssl_fingerprint_sha1,
|
|
| 2250 |
- 'sha256': obj.ssl_fingerprint_sha256}
|
|
| 2251 |
- self.xml.get_object('ssl_checkbutton').set_label(text)
|
|
| 2252 |
- else:
|
|
| 2253 |
- self.xml.get_object('ssl_checkbutton').set_no_show_all(True)
|
|
| 2254 |
- self.xml.get_object('ssl_checkbutton').hide()
|
|
| 2255 |
- self.notebook.set_current_page(3) # show SSL page
|
|
| 2256 |
- else:
|
|
| 2257 |
- self.notebook.set_current_page(4) # show form page
|
|
| 2258 |
- |
|
| 2259 |
- def _nec_new_acc_not_connected(self, obj):
|
|
| 2260 |
- """
|
|
| 2261 |
- Account creation failed: connection to server failed
|
|
| 2262 |
- """
|
|
| 2263 |
- # We receive events from all accounts from GED
|
|
| 2264 |
- if obj.conn.name != self.account:
|
|
| 2265 |
- return
|
|
| 2266 |
- if self.account not in app.connections:
|
|
| 2267 |
- return
|
|
| 2268 |
- if self.update_progressbar_timeout_id is not None:
|
|
| 2269 |
- GLib.source_remove(self.update_progressbar_timeout_id)
|
|
| 2270 |
- del app.connections[self.account]
|
|
| 2271 |
- if self.account in app.config.get_per('accounts'):
|
|
| 2272 |
- app.config.del_per('accounts', self.account)
|
|
| 2273 |
- self.back_button.show()
|
|
| 2274 |
- self.cancel_button.show()
|
|
| 2275 |
- self.go_online_checkbutton.hide()
|
|
| 2276 |
- self.show_vcard_checkbutton.hide()
|
|
| 2277 |
- img = self.xml.get_object('finish_image')
|
|
| 2278 |
- img.set_from_icon_name("dialog-error", Gtk.IconSize.DIALOG)
|
|
| 2279 |
- finish_text = '<big><b>%s</b></big>\n\n%s' % (
|
|
| 2280 |
- _('An error occurred during account creation'), obj.reason)
|
|
| 2281 |
- self.finish_label.set_markup(finish_text)
|
|
| 2282 |
- self.notebook.set_current_page(6) # show finish page
|
|
| 2283 |
- |
|
| 2284 |
- def _nec_acc_is_ok(self, obj):
|
|
| 2285 |
- """
|
|
| 2286 |
- Account creation succeeded
|
|
| 2287 |
- """
|
|
| 2288 |
- # We receive events from all accounts from GED
|
|
| 2289 |
- if obj.conn.name != self.account:
|
|
| 2290 |
- return
|
|
| 2291 |
- self.create_vars(obj.account_info)
|
|
| 2292 |
- self.show_finish_page()
|
|
| 2293 |
- |
|
| 2294 |
- if self.update_progressbar_timeout_id is not None:
|
|
| 2295 |
- GLib.source_remove(self.update_progressbar_timeout_id)
|
|
| 2296 |
- |
|
| 2297 |
- def _nec_acc_is_not_ok(self, obj):
|
|
| 2298 |
- """
|
|
| 2299 |
- Account creation failed
|
|
| 2300 |
- """
|
|
| 2301 |
- # We receive events from all accounts from GED
|
|
| 2302 |
- if obj.conn.name != self.account:
|
|
| 2303 |
- return
|
|
| 2304 |
- self.back_button.show()
|
|
| 2305 |
- self.cancel_button.show()
|
|
| 2306 |
- self.go_online_checkbutton.hide()
|
|
| 2307 |
- self.show_vcard_checkbutton.hide()
|
|
| 2308 |
- del app.connections[self.account]
|
|
| 2309 |
- if self.account in app.config.get_per('accounts'):
|
|
| 2310 |
- app.config.del_per('accounts', self.account)
|
|
| 2311 |
- img = self.xml.get_object('finish_image')
|
|
| 2312 |
- img.set_from_icon_name("dialog-error", Gtk.IconSize.DIALOG)
|
|
| 2313 |
- finish_text = '<big><b>%s</b></big>\n\n%s' % (_(
|
|
| 2314 |
- 'An error occurred during account creation'), obj.reason)
|
|
| 2315 |
- self.finish_label.set_markup(finish_text)
|
|
| 2316 |
- self.notebook.set_current_page(6) # show finish page
|
|
| 2317 |
- |
|
| 2318 |
- if self.update_progressbar_timeout_id is not None:
|
|
| 2319 |
- GLib.source_remove(self.update_progressbar_timeout_id)
|
|
| 2320 |
- |
|
| 2321 |
- def on_advanced_button_clicked(self, widget):
|
|
| 2322 |
- if 'accounts' in app.interface.instances:
|
|
| 2323 |
- app.interface.instances['accounts'].present()
|
|
| 2324 |
- else:
|
|
| 2325 |
- app.interface.instances['accounts'] = AccountsWindow()
|
|
| 2326 |
- app.interface.instances['accounts'].select_account(self.account)
|
|
| 2327 |
- self.window.destroy()
|
|
| 2328 |
- |
|
| 2329 |
- def on_finish_button_clicked(self, widget):
|
|
| 2330 |
- go_online = self.xml.get_object('go_online_checkbutton').get_active()
|
|
| 2331 |
- show_vcard = self.xml.get_object('show_vcard_checkbutton').get_active()
|
|
| 2332 |
- self.window.destroy()
|
|
| 2333 |
- if show_vcard:
|
|
| 2334 |
- app.interface.show_vcard_when_connect.append(self.account)
|
|
| 2335 |
- if go_online:
|
|
| 2336 |
- app.interface.roster.send_status(self.account, 'online', '')
|
|
| 2337 |
- |
|
| 2338 |
- def on_username_entry_key_press_event(self, widget, event):
|
|
| 2339 |
- # Check for pressed @ and jump to combobox if found
|
|
| 2340 |
- if event.keyval == Gdk.KEY_at:
|
|
| 2341 |
- entry = self.xml.get_object('server_comboboxtext_entry')
|
|
| 2342 |
- entry.grab_focus()
|
|
| 2343 |
- entry.set_position(-1)
|
|
| 2344 |
- return True
|
|
| 2345 |
- |
|
| 2346 |
- def on_server_comboboxentry_key_press_event(self, widget, event, combobox):
|
|
| 2347 |
- # If backspace is pressed in empty field, return to the nick entry field
|
|
| 2348 |
- backspace = event.keyval == Gdk.KEY_BackSpace
|
|
| 2349 |
- empty = len(combobox.get_active_text()) == 0
|
|
| 2350 |
- if backspace and empty and self.modify:
|
|
| 2351 |
- username_entry = self.xml.get_object('username_entry')
|
|
| 2352 |
- username_entry.grab_focus()
|
|
| 2353 |
- username_entry.set_position(-1)
|
|
| 2354 |
- return True
|
|
| 2355 |
- |
|
| 2356 |
- def get_config(self, login, server, savepass, password, anonymous=False):
|
|
| 2357 |
- config = {}
|
|
| 2358 |
- config['name'] = login
|
|
| 2359 |
- config['account_label'] = '%s@%s' % (login, server)
|
|
| 2360 |
- config['hostname'] = server
|
|
| 2361 |
- config['savepass'] = savepass
|
|
| 2362 |
- config['password'] = password
|
|
| 2363 |
- config['anonymous_auth'] = anonymous
|
|
| 2364 |
- config['priority'] = 5
|
|
| 2365 |
- config['autoconnect'] = True
|
|
| 2366 |
- config['no_log_for'] = ''
|
|
| 2367 |
- config['sync_with_global_status'] = True
|
|
| 2368 |
- config['proxy'] = ''
|
|
| 2369 |
- config['use_custom_host'] = False
|
|
| 2370 |
- config['custom_port'] = 0
|
|
| 2371 |
- config['custom_host'] = ''
|
|
| 2372 |
- config['keyname'] = ''
|
|
| 2373 |
- config['keyid'] = ''
|
|
| 2374 |
- return config
|
|
| 2375 |
- |
|
| 2376 |
- def save_account(self, login, server, savepass, password, anonymous=False):
|
|
| 2377 |
- if self.account in app.connections:
|
|
| 2378 |
- ErrorDialog(_('Account name is in use'),
|
|
| 2379 |
- _('You already have an account using this name.'))
|
|
| 2380 |
- return
|
|
| 2381 |
- con = connection.Connection(self.account)
|
|
| 2382 |
- con.password = password
|
|
| 2383 |
- |
|
| 2384 |
- config = self.get_config(login, server, savepass, password, anonymous)
|
|
| 2385 |
- |
|
| 2386 |
- if not self.modify:
|
|
| 2387 |
- con.new_account(self.account, config)
|
|
| 2388 |
- return
|
|
| 2389 |
- app.connections[self.account] = con
|
|
| 2390 |
- self.create_vars(config)
|
|
| 2391 |
- |
|
| 2392 |
- def create_vars(self, config):
|
|
| 2393 |
- app.config.add_per('accounts', self.account)
|
|
| 2394 |
- |
|
| 2395 |
- if not config['savepass']:
|
|
| 2396 |
- config['password'] = ''
|
|
| 2397 |
- |
|
| 2398 |
- for opt in config:
|
|
| 2399 |
- app.config.set_per('accounts', self.account, opt, config[opt])
|
|
| 2400 |
- |
|
| 2401 |
- # update variables
|
|
| 2402 |
- app.interface.instances[self.account] = {'infos': {}, 'disco': {},
|
|
| 2403 |
- 'gc_config': {}, 'search': {}, 'online_dialog': {},
|
|
| 2404 |
- 'sub_request': {}}
|
|
| 2405 |
- app.interface.minimized_controls[self.account] = {}
|
|
| 2406 |
- app.connections[self.account].connected = 0
|
|
| 2407 |
- app.connections[self.account].keepalives = app.config.get_per(
|
|
| 2408 |
- 'accounts', self.account, 'keep_alive_every_foo_secs')
|
|
| 2409 |
- app.groups[self.account] = {}
|
|
| 2410 |
- app.contacts.add_account(self.account)
|
|
| 2411 |
- app.gc_connected[self.account] = {}
|
|
| 2412 |
- app.automatic_rooms[self.account] = {}
|
|
| 2413 |
- app.newly_added[self.account] = []
|
|
| 2414 |
- app.to_be_removed[self.account] = []
|
|
| 2415 |
- app.nicks[self.account] = config['name']
|
|
| 2416 |
- app.block_signed_in_notifications[self.account] = True
|
|
| 2417 |
- app.sleeper_state[self.account] = 'off'
|
|
| 2418 |
- app.encrypted_chats[self.account] = []
|
|
| 2419 |
- app.last_message_time[self.account] = {}
|
|
| 2420 |
- app.status_before_autoaway[self.account] = ''
|
|
| 2421 |
- app.transport_avatar[self.account] = {}
|
|
| 2422 |
- app.gajim_optional_features[self.account] = []
|
|
| 2423 |
- app.caps_hash[self.account] = ''
|
|
| 2424 |
- helpers.update_optional_features(self.account)
|
|
| 2425 |
- # action must be added before account window is updated
|
|
| 2426 |
- app.app.add_account_actions(self.account)
|
|
| 2427 |
- # refresh accounts window
|
|
| 2428 |
- if 'accounts' in app.interface.instances:
|
|
| 2429 |
- app.interface.instances['accounts'].add_account(self.account)
|
|
| 2430 |
- # refresh roster
|
|
| 2431 |
- if len(app.connections) >= 2:
|
|
| 2432 |
- # Do not merge accounts if only one exists
|
|
| 2433 |
- app.interface.roster.regroup = app.config.get('mergeaccounts')
|
|
| 2434 |
- else:
|
|
| 2435 |
- app.interface.roster.regroup = False
|
|
| 2436 |
- app.interface.roster.setup_and_draw_roster()
|
|
| 2437 |
- gui_menu_builder.build_accounts_menu()
|
|
| 2438 |
- |
|
| 2439 | 1886 |
|
| 2440 | 1887 |
class ManageSoundsWindow:
|
| 2441 | 1888 |
def __init__(self):
|
| 1 | 1 |
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
-<!-- Generated with glade 3.20.0 -->
|
|
| 2 |
+<!-- Generated with glade 3.22.1 -->
|
|
| 3 | 3 |
<interface>
|
| 4 | 4 |
<requires lib="gtk+" version="3.12"/>
|
| 5 |
- <object class="GtkWindow" id="features_window">
|
|
| 5 |
+ <object class="GtkBox" id="features_box">
|
|
| 6 |
+ <property name="width_request">300</property>
|
|
| 7 |
+ <property name="height_request">530</property>
|
|
| 8 |
+ <property name="visible">True</property>
|
|
| 6 | 9 |
<property name="can_focus">False</property>
|
| 7 | 10 |
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
| 8 |
- <property name="border_width">12</property>
|
|
| 9 |
- <property name="title" translatable="yes">Features</property>
|
|
| 10 |
- <property name="default_width">300</property>
|
|
| 11 |
- <property name="default_height">530</property>
|
|
| 12 |
- <property name="type_hint">dialog</property>
|
|
| 13 |
- <signal name="key-press-event" handler="on_key_press_event" swapped="no"/>
|
|
| 11 |
+ <property name="margin_left">18</property>
|
|
| 12 |
+ <property name="margin_right">18</property>
|
|
| 13 |
+ <property name="margin_top">18</property>
|
|
| 14 |
+ <property name="margin_bottom">18</property>
|
|
| 15 |
+ <property name="orientation">vertical</property>
|
|
| 16 |
+ <property name="spacing">6</property>
|
|
| 14 | 17 |
<child>
|
| 15 |
- <object class="GtkBox" id="vbox1">
|
|
| 18 |
+ <object class="GtkLabel">
|
|
| 16 | 19 |
<property name="visible">True</property>
|
| 17 | 20 |
<property name="can_focus">False</property>
|
| 18 | 21 |
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
| 19 |
- <property name="orientation">vertical</property>
|
|
| 20 |
- <property name="spacing">6</property>
|
|
| 21 |
- <child>
|
|
| 22 |
- <object class="GtkLabel" id="label1">
|
|
| 23 |
- <property name="visible">True</property>
|
|
| 24 |
- <property name="can_focus">False</property>
|
|
| 25 |
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
|
| 26 |
- <property name="label" translatable="yes"><b>List of possible features in Gajim:</b></property>
|
|
| 27 |
- <property name="use_markup">True</property>
|
|
| 28 |
- <property name="xalign">0</property>
|
|
| 29 |
- </object>
|
|
| 30 |
- <packing>
|
|
| 31 |
- <property name="expand">False</property>
|
|
| 32 |
- <property name="fill">False</property>
|
|
| 33 |
- <property name="position">0</property>
|
|
| 34 |
- </packing>
|
|
| 35 |
- </child>
|
|
| 22 |
+ <property name="label" translatable="yes"><b>List of possible features in Gajim:</b></property>
|
|
| 23 |
+ <property name="use_markup">True</property>
|
|
| 24 |
+ <property name="xalign">0</property>
|
|
| 25 |
+ </object>
|
|
| 26 |
+ <packing>
|
|
| 27 |
+ <property name="expand">False</property>
|
|
| 28 |
+ <property name="fill">False</property>
|
|
| 29 |
+ <property name="position">0</property>
|
|
| 30 |
+ </packing>
|
|
| 31 |
+ </child>
|
|
| 32 |
+ <child>
|
|
| 33 |
+ <object class="GtkScrolledWindow">
|
|
| 34 |
+ <property name="visible">True</property>
|
|
| 35 |
+ <property name="can_focus">True</property>
|
|
| 36 |
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
|
| 37 |
+ <property name="vexpand">True</property>
|
|
| 38 |
+ <property name="shadow_type">out</property>
|
|
| 36 | 39 |
<child>
|
| 37 |
- <object class="GtkScrolledWindow" id="scrolledwindow1">
|
|
| 40 |
+ <object class="GtkTreeView" id="features_treeview">
|
|
| 38 | 41 |
<property name="visible">True</property>
|
| 39 | 42 |
<property name="can_focus">True</property>
|
| 40 | 43 |
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
| 41 |
- <property name="shadow_type">out</property>
|
|
| 42 |
- <child>
|
|
| 43 |
- <object class="GtkTreeView" id="features_treeview">
|
|
| 44 |
- <property name="visible">True</property>
|
|
| 45 |
- <property name="can_focus">True</property>
|
|
| 46 |
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
|
| 47 |
- <signal name="cursor-changed" handler="on_features_treeview_cursor_changed" swapped="no"/>
|
|
| 48 |
- <child internal-child="selection">
|
|
| 49 |
- <object class="GtkTreeSelection" id="treeview-selection1"/>
|
|
| 50 |
- </child>
|
|
| 51 |
- </object>
|
|
| 44 |
+ <signal name="cursor-changed" handler="on_features_treeview_cursor_changed" swapped="no"/>
|
|
| 45 |
+ <child internal-child="selection">
|
|
| 46 |
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
|
|
| 52 | 47 |
</child>
|
| 53 | 48 |
</object>
|
| 54 |
- <packing>
|
|
| 55 |
- <property name="expand">True</property>
|
|
| 56 |
- <property name="fill">True</property>
|
|
| 57 |
- <property name="position">1</property>
|
|
| 58 |
- </packing>
|
|
| 59 | 49 |
</child>
|
| 50 |
+ </object>
|
|
| 51 |
+ <packing>
|
|
| 52 |
+ <property name="expand">True</property>
|
|
| 53 |
+ <property name="fill">True</property>
|
|
| 54 |
+ <property name="position">1</property>
|
|
| 55 |
+ </packing>
|
|
| 56 |
+ </child>
|
|
| 57 |
+ <child>
|
|
| 58 |
+ <object class="GtkFrame">
|
|
| 59 |
+ <property name="visible">True</property>
|
|
| 60 |
+ <property name="can_focus">False</property>
|
|
| 61 |
+ <property name="border_width">3</property>
|
|
| 62 |
+ <property name="label_xalign">0</property>
|
|
| 63 |
+ <property name="shadow_type">none</property>
|
|
| 60 | 64 |
<child>
|
| 61 |
- <object class="GtkButtonBox" id="hbuttonbox1">
|
|
| 65 |
+ <object class="GtkLabel" id="feature_desc_label">
|
|
| 62 | 66 |
<property name="visible">True</property>
|
| 63 | 67 |
<property name="can_focus">False</property>
|
| 64 |
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
|
| 65 |
- <property name="layout_style">end</property>
|
|
| 66 |
- <child>
|
|
| 67 |
- <object class="GtkButton" id="close_button">
|
|
| 68 |
- <property name="label">gtk-close</property>
|
|
| 69 |
- <property name="visible">True</property>
|
|
| 70 |
- <property name="can_focus">True</property>
|
|
| 71 |
- <property name="receives_default">True</property>
|
|
| 72 |
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
|
| 73 |
- <property name="use_stock">True</property>
|
|
| 74 |
- <signal name="clicked" handler="on_close_button_clicked" swapped="no"/>
|
|
| 75 |
- </object>
|
|
| 76 |
- <packing>
|
|
| 77 |
- <property name="expand">False</property>
|
|
| 78 |
- <property name="fill">False</property>
|
|
| 79 |
- <property name="position">0</property>
|
|
| 80 |
- </packing>
|
|
| 81 |
- </child>
|
|
| 68 |
+ <property name="margin_left">12</property>
|
|
| 69 |
+ <property name="wrap">True</property>
|
|
| 70 |
+ <property name="selectable">True</property>
|
|
| 71 |
+ <property name="xalign">0</property>
|
|
| 82 | 72 |
</object>
|
| 83 |
- <packing>
|
|
| 84 |
- <property name="expand">False</property>
|
|
| 85 |
- <property name="fill">True</property>
|
|
| 86 |
- <property name="pack_type">end</property>
|
|
| 87 |
- <property name="position">2</property>
|
|
| 88 |
- </packing>
|
|
| 89 | 73 |
</child>
|
| 90 |
- <child>
|
|
| 91 |
- <object class="GtkFrame" id="frame2">
|
|
| 74 |
+ <child type="label">
|
|
| 75 |
+ <object class="GtkLabel">
|
|
| 92 | 76 |
<property name="visible">True</property>
|
| 93 | 77 |
<property name="can_focus">False</property>
|
| 94 |
- <property name="border_width">3</property>
|
|
| 95 |
- <property name="label_xalign">0</property>
|
|
| 96 |
- <property name="shadow_type">none</property>
|
|
| 97 |
- <child>
|
|
| 98 |
- <object class="GtkLabel" id="feature_desc_label">
|
|
| 99 |
- <property name="visible">True</property>
|
|
| 100 |
- <property name="can_focus">False</property>
|
|
| 101 |
- <property name="margin_left">12</property>
|
|
| 102 |
- <property name="wrap">True</property>
|
|
| 103 |
- <property name="selectable">True</property>
|
|
| 104 |
- <property name="xalign">0</property>
|
|
| 105 |
- </object>
|
|
| 106 |
- </child>
|
|
| 107 |
- <child type="label">
|
|
| 108 |
- <object class="GtkLabel" id="label2">
|
|
| 109 |
- <property name="visible">True</property>
|
|
| 110 |
- <property name="can_focus">False</property>
|
|
| 111 |
- <property name="label" translatable="yes"><b>Description</b></property>
|
|
| 112 |
- <property name="use_markup">True</property>
|
|
| 113 |
- </object>
|
|
| 114 |
- </child>
|
|
| 78 |
+ <property name="label" translatable="yes"><b>Description</b></property>
|
|
| 79 |
+ <property name="use_markup">True</property>
|
|
| 115 | 80 |
</object>
|
| 116 |
- <packing>
|
|
| 117 |
- <property name="expand">False</property>
|
|
| 118 |
- <property name="fill">True</property>
|
|
| 119 |
- <property name="position">3</property>
|
|
| 120 |
- </packing>
|
|
| 121 | 81 |
</child>
|
| 122 | 82 |
</object>
|
| 83 |
+ <packing>
|
|
| 84 |
+ <property name="expand">False</property>
|
|
| 85 |
+ <property name="fill">True</property>
|
|
| 86 |
+ <property name="position">2</property>
|
|
| 87 |
+ </packing>
|
|
| 123 | 88 |
</child>
|
| 124 | 89 |
</object>
|
| 125 | 90 |
</interface>
|
| 1 | 1 |
# Copyright (C) 2003-2005 Vincent Hanquez <tab AT snarc.org>
|
| 2 |
+# Copyright (C) 2005 Alex Podaras <bigpod AT gmail.com>
|
|
| 3 |
+# Stéphan Kochen <stephan AT kochen.nl>
|
|
| 4 |
+# Alex Mauer <hawke AT hawkesnest.net>
|
|
| 2 | 5 |
# Copyright (C) 2003-2014 Yann Leboulanger <asterix AT lagaule.org>
|
| 3 |
-# Copyright (C) 2005 Alex Mauer <hawke AT hawkesnest.net>
|
|
| 4 | 6 |
# Copyright (C) 2005-2006 Dimitur Kirov <dkirov AT gmail.com>
|
| 5 | 7 |
# Travis Shirk <travis AT pobox.com>
|
| 6 | 8 |
# Copyright (C) 2005-2008 Nikos Kouremenos <kourem AT gmail.com>
|
| 9 |
+# Copyright (C) 2006 Junglecow J <junglecow AT gmail.com>
|
|
| 10 |
+# Copyright (C) 2006-2007 Travis Shirk <travis AT pobox.com>
|
|
| 11 |
+# Stefan Bethge <stefan AT lanpartei.de>
|
|
| 7 | 12 |
# Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
|
| 8 |
-# Copyright (C) 2007 Lukas Petrovicky <lukas AT petrovicky.net>
|
|
| 13 |
+# Copyright (C) 2007 James Newton <redshodan AT gmail.com>
|
|
| 14 |
+# Lukas Petrovicky <lukas AT petrovicky.net>
|
|
| 9 | 15 |
# Copyright (C) 2007-2008 Brendan Taylor <whateley AT gmail.com>
|
| 10 | 16 |
# Julien Pivotto <roidelapluie AT gmail.com>
|
| 11 | 17 |
# Stephan Erb <steve-e AT h3c.de>
|
| 12 |
-# Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
|
| 13 |
-# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
|
|
| 18 |
+# Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
|
| 19 |
+# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
|
|
| 14 | 20 |
#
|
| 15 | 21 |
# This file is part of Gajim.
|
| 16 | 22 |
#
|
| ... | ... | @@ -57,3 +63,5 @@ from gajim.gtk.server_info import ServerInfoDialog |
| 57 | 63 |
from gajim.gtk.pep_config import ManagePEPServicesWindow
|
| 58 | 64 |
from gajim.gtk.bookmarks import ManageBookmarksWindow
|
| 59 | 65 |
from gajim.gtk.profile import ProfileWindow
|
| 66 |
+from gajim.gtk.features import FeaturesDialog
|
|
| 67 |
+from gajim.gtk.account_wizard import AccountCreationWizard
|
| 1 |
+# This file is part of Gajim.
|
|
| 2 |
+#
|
|
| 3 |
+# Gajim is free software; you can redistribute it and/or modify
|
|
| 4 |
+# it under the terms of the GNU General Public License as published
|
|
| 5 |
+# by the Free Software Foundation; version 3 only.
|
|
| 6 |
+#
|
|
| 7 |
+# Gajim is distributed in the hope that it will be useful,
|
|
| 8 |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
| 9 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
| 10 |
+# GNU General Public License for more details.
|
|
| 11 |
+#
|
|
| 12 |
+# You should have received a copy of the GNU General Public License
|
|
| 13 |
+# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
|
| 14 |
+ |
|
| 15 |
+import os
|
|
| 16 |
+ |
|
| 17 |
+from gi.repository import Gtk
|
|
| 18 |
+from gi.repository import Gdk
|
|
| 19 |
+from gi.repository import GLib
|
|
| 20 |
+ |
|
| 21 |
+from gajim.common import app
|
|
| 22 |
+from gajim.common import ged
|
|
| 23 |
+from gajim.common import configpaths
|
|
| 24 |
+from gajim.common import helpers
|
|
| 25 |
+from gajim.common import connection
|
|
| 26 |
+from gajim.common.modules import dataforms
|
|
| 27 |
+from gajim.gtk.util import get_builder
|
|
| 28 |
+from gajim.gtk import ErrorDialog
|
|
| 29 |
+from gajim import gtkgui_helpers
|
|
| 30 |
+from gajim import dataforms_widget
|
|
| 31 |
+from gajim import config
|
|
| 32 |
+from gajim import gui_menu_builder
|
|
| 33 |
+ |
|
| 34 |
+ |
|
| 35 |
+class AccountCreationWizard:
|
|
| 36 |
+ def __init__(self):
|
|
| 37 |
+ self.xml = get_builder('account_creation_wizard_window.ui')
|
|
| 38 |
+ self.window = self.xml.get_object('account_creation_wizard_window')
|
|
| 39 |
+ active_window = app.app.get_active_window()
|
|
| 40 |
+ self.window.set_transient_for(active_window)
|
|
| 41 |
+ |
|
| 42 |
+ # Connect events from comboboxtext_entry
|
|
| 43 |
+ server_comboboxtext = self.xml.get_object('server_comboboxtext')
|
|
| 44 |
+ entry = self.xml.get_object('server_comboboxtext_entry')
|
|
| 45 |
+ entry.connect('key_press_event',
|
|
| 46 |
+ self.on_entry_key_press_event, server_comboboxtext)
|
|
| 47 |
+ |
|
| 48 |
+ server_comboboxtext1 = self.xml.get_object('server_comboboxtext1')
|
|
| 49 |
+ |
|
| 50 |
+ self.update_proxy_list()
|
|
| 51 |
+ |
|
| 52 |
+ # parse servers.xml
|
|
| 53 |
+ servers_xml = os.path.join(
|
|
| 54 |
+ configpaths.get('DATA'), 'other', 'servers.xml')
|
|
| 55 |
+ servers = gtkgui_helpers.parse_server_xml(servers_xml)
|
|
| 56 |
+ servers_model = self.xml.get_object('server_liststore')
|
|
| 57 |
+ for server in servers:
|
|
| 58 |
+ servers_model.append((server,))
|
|
| 59 |
+ |
|
| 60 |
+ server_comboboxtext.set_model(servers_model)
|
|
| 61 |
+ server_comboboxtext1.set_model(servers_model)
|
|
| 62 |
+ |
|
| 63 |
+ # Generic widgets
|
|
| 64 |
+ self.notebook = self.xml.get_object('notebook')
|
|
| 65 |
+ self.cancel_button = self.xml.get_object('cancel_button')
|
|
| 66 |
+ self.back_button = self.xml.get_object('back_button')
|
|
| 67 |
+ self.forward_button = self.xml.get_object('forward_button')
|
|
| 68 |
+ self.finish_button = self.xml.get_object('finish_button')
|
|
| 69 |
+ self.advanced_button = self.xml.get_object('advanced_button')
|
|
| 70 |
+ self.finish_label = self.xml.get_object('finish_label')
|
|
| 71 |
+ self.go_online_checkbutton = self.xml.get_object(
|
|
| 72 |
+ 'go_online_checkbutton')
|
|
| 73 |
+ self.show_vcard_checkbutton = self.xml.get_object(
|
|
| 74 |
+ 'show_vcard_checkbutton')
|
|
| 75 |
+ self.progressbar = self.xml.get_object('progressbar')
|
|
| 76 |
+ |
|
| 77 |
+ # some vars
|
|
| 78 |
+ self.update_progressbar_timeout_id = None
|
|
| 79 |
+ |
|
| 80 |
+ self.notebook.set_current_page(0)
|
|
| 81 |
+ self.xml.connect_signals(self)
|
|
| 82 |
+ self.window.show_all()
|
|
| 83 |
+ app.ged.register_event_handler(
|
|
| 84 |
+ 'new-account-connected', ged.GUI1,
|
|
| 85 |
+ self._nec_new_acc_connected)
|
|
| 86 |
+ app.ged.register_event_handler(
|
|
| 87 |
+ 'new-account-not-connected', ged.GUI1,
|
|
| 88 |
+ self._nec_new_acc_not_connected)
|
|
| 89 |
+ app.ged.register_event_handler(
|
|
| 90 |
+ 'account-created', ged.GUI1,
|
|
| 91 |
+ self._nec_acc_is_ok)
|
|
| 92 |
+ app.ged.register_event_handler(
|
|
| 93 |
+ 'account-not-created', ged.GUI1,
|
|
| 94 |
+ self._nec_acc_is_not_ok)
|
|
| 95 |
+ |
|
| 96 |
+ def on_wizard_window_destroy(self, widget):
|
|
| 97 |
+ page = self.notebook.get_current_page()
|
|
| 98 |
+ if page in (4, 5) and self.account in app.connections:
|
|
| 99 |
+ # connection instance is saved in app.connections and we canceled
|
|
| 100 |
+ # the addition of the account
|
|
| 101 |
+ del app.connections[self.account]
|
|
| 102 |
+ if self.account in app.config.get_per('accounts'):
|
|
| 103 |
+ app.config.del_per('accounts', self.account)
|
|
| 104 |
+ app.ged.remove_event_handler(
|
|
| 105 |
+ 'new-account-connected', ged.GUI1,
|
|
| 106 |
+ self._nec_new_acc_connected)
|
|
| 107 |
+ app.ged.remove_event_handler(
|
|
| 108 |
+ 'new-account-not-connected', ged.GUI1,
|
|
| 109 |
+ self._nec_new_acc_not_connected)
|
|
| 110 |
+ app.ged.remove_event_handler(
|
|
| 111 |
+ 'account-created', ged.GUI1,
|
|
| 112 |
+ self._nec_acc_is_ok)
|
|
| 113 |
+ app.ged.remove_event_handler(
|
|
| 114 |
+ 'account-not-created', ged.GUI1,
|
|
| 115 |
+ self._nec_acc_is_not_ok)
|
|
| 116 |
+ del app.interface.instances['account_creation_wizard']
|
|
| 117 |
+ |
|
| 118 |
+ def on_save_password_checkbutton_toggled(self, widget):
|
|
| 119 |
+ self.xml.get_object('password_entry').grab_focus()
|
|
| 120 |
+ |
|
| 121 |
+ def on_cancel_button_clicked(self, widget):
|
|
| 122 |
+ self.window.destroy()
|
|
| 123 |
+ |
|
| 124 |
+ def on_back_button_clicked(self, widget):
|
|
| 125 |
+ cur_page = self.notebook.get_current_page()
|
|
| 126 |
+ self.forward_button.set_sensitive(True)
|
|
| 127 |
+ if cur_page in (1, 2):
|
|
| 128 |
+ self.notebook.set_current_page(0)
|
|
| 129 |
+ self.back_button.set_sensitive(False)
|
|
| 130 |
+ elif cur_page == 3:
|
|
| 131 |
+ self.xml.get_object('form_vbox').remove(self.data_form_widget)
|
|
| 132 |
+ self.notebook.set_current_page(2) # show server page
|
|
| 133 |
+ elif cur_page == 4:
|
|
| 134 |
+ if self.account in app.connections:
|
|
| 135 |
+ del app.connections[self.account]
|
|
| 136 |
+ if self.account in app.config.get_per('accounts'):
|
|
| 137 |
+ app.config.del_per('accounts', self.account)
|
|
| 138 |
+ self.notebook.set_current_page(2)
|
|
| 139 |
+ self.xml.get_object('form_vbox').remove(self.data_form_widget)
|
|
| 140 |
+ elif cur_page == 6: # finish page
|
|
| 141 |
+ self.forward_button.show()
|
|
| 142 |
+ if self.modify:
|
|
| 143 |
+ self.notebook.set_current_page(1) # Go to parameters page
|
|
| 144 |
+ else:
|
|
| 145 |
+ self.notebook.set_current_page(2) # Go to server page
|
|
| 146 |
+ |
|
| 147 |
+ def on_anonymous_checkbutton1_toggled(self, widget):
|
|
| 148 |
+ active = widget.get_active()
|
|
| 149 |
+ self.xml.get_object('username_entry').set_sensitive(not active)
|
|
| 150 |
+ self.xml.get_object('password_entry').set_sensitive(not active)
|
|
| 151 |
+ self.xml.get_object('save_password_checkbutton').set_sensitive(
|
|
| 152 |
+ not active)
|
|
| 153 |
+ |
|
| 154 |
+ def show_finish_page(self):
|
|
| 155 |
+ self.cancel_button.hide()
|
|
| 156 |
+ self.back_button.hide()
|
|
| 157 |
+ self.forward_button.hide()
|
|
| 158 |
+ if self.modify:
|
|
| 159 |
+ finish_text = '<big><b>%s</b></big>\n\n%s' % (
|
|
| 160 |
+ _('Account has been added successfully'),
|
|
| 161 |
+ _('You can set advanced account options by pressing the '
|
|
| 162 |
+ 'Advanced button, or later by choosing the Accounts menu item '
|
|
| 163 |
+ 'under the Edit menu from the main window.'))
|
|
| 164 |
+ else:
|
|
| 165 |
+ finish_text = '<big><b>%s</b></big>\n\n%s' % (
|
|
| 166 |
+ _('Your new account has been created successfully'),
|
|
| 167 |
+ _('You can set advanced account options by pressing the '
|
|
| 168 |
+ 'Advanced button, or later by choosing the Accounts menu item '
|
|
| 169 |
+ 'under the Edit menu from the main window.'))
|
|
| 170 |
+ self.finish_label.set_markup(finish_text)
|
|
| 171 |
+ self.finish_button.show()
|
|
| 172 |
+ self.finish_button.set_property('has-default', True)
|
|
| 173 |
+ self.advanced_button.show()
|
|
| 174 |
+ self.go_online_checkbutton.show()
|
|
| 175 |
+ img = self.xml.get_object('finish_image')
|
|
| 176 |
+ if self.modify:
|
|
| 177 |
+ img.set_from_icon_name(Gtk.STOCK_APPLY, Gtk.IconSize.DIALOG)
|
|
| 178 |
+ else:
|
|
| 179 |
+ path_to_file = gtkgui_helpers.get_icon_path('org.gajim.Gajim', 48)
|
|
| 180 |
+ img.set_from_file(path_to_file)
|
|
| 181 |
+ self.show_vcard_checkbutton.set_active(not self.modify)
|
|
| 182 |
+ self.notebook.set_current_page(6) # show finish page
|
|
| 183 |
+ |
|
| 184 |
+ def on_forward_button_clicked(self, widget):
|
|
| 185 |
+ cur_page = self.notebook.get_current_page()
|
|
| 186 |
+ |
|
| 187 |
+ if cur_page == 0:
|
|
| 188 |
+ widget = self.xml.get_object('use_existing_account_radiobutton')
|
|
| 189 |
+ if widget.get_active():
|
|
| 190 |
+ self.modify = True
|
|
| 191 |
+ self.notebook.set_current_page(1)
|
|
| 192 |
+ else:
|
|
| 193 |
+ self.modify = False
|
|
| 194 |
+ self.notebook.set_current_page(2)
|
|
| 195 |
+ self.back_button.set_sensitive(True)
|
|
| 196 |
+ return
|
|
| 197 |
+ |
|
| 198 |
+ elif cur_page == 1:
|
|
| 199 |
+ # We are adding an existing account
|
|
| 200 |
+ anonymous = self.xml.get_object('anonymous_checkbutton1').\
|
|
| 201 |
+ get_active()
|
|
| 202 |
+ username = self.xml.get_object('username_entry').get_text().strip()
|
|
| 203 |
+ if not username and not anonymous:
|
|
| 204 |
+ pritext = _('Invalid username')
|
|
| 205 |
+ sectext = _(
|
|
| 206 |
+ 'You must provide a username to configure this account.')
|
|
| 207 |
+ ErrorDialog(pritext, sectext)
|
|
| 208 |
+ return
|
|
| 209 |
+ server = self.xml.get_object('server_comboboxtext_entry').\
|
|
| 210 |
+ get_text().strip()
|
|
| 211 |
+ savepass = self.xml.get_object('save_password_checkbutton').\
|
|
| 212 |
+ get_active()
|
|
| 213 |
+ password = self.xml.get_object('password_entry').get_text()
|
|
| 214 |
+ |
|
| 215 |
+ if anonymous:
|
|
| 216 |
+ jid = ''
|
|
| 217 |
+ else:
|
|
| 218 |
+ jid = username + '@'
|
|
| 219 |
+ jid += server
|
|
| 220 |
+ # check if jid is conform to RFC and stringprep it
|
|
| 221 |
+ try:
|
|
| 222 |
+ jid = helpers.parse_jid(jid)
|
|
| 223 |
+ except helpers.InvalidFormat as s:
|
|
| 224 |
+ pritext = _('Invalid JID')
|
|
| 225 |
+ ErrorDialog(pritext, str(s))
|
|
| 226 |
+ return
|
|
| 227 |
+ |
|
| 228 |
+ self.account = server
|
|
| 229 |
+ i = 1
|
|
| 230 |
+ while self.account in app.config.get_per('accounts'):
|
|
| 231 |
+ self.account = server + str(i)
|
|
| 232 |
+ i += 1
|
|
| 233 |
+ |
|
| 234 |
+ username, server = app.get_name_and_server_from_jid(jid)
|
|
| 235 |
+ if self.xml.get_object('anonymous_checkbutton1').get_active():
|
|
| 236 |
+ self.save_account('', server, False, '', anonymous=True)
|
|
| 237 |
+ else:
|
|
| 238 |
+ self.save_account(username, server, savepass, password)
|
|
| 239 |
+ self.show_finish_page()
|
|
| 240 |
+ elif cur_page == 2:
|
|
| 241 |
+ # We are creating a new account
|
|
| 242 |
+ server = self.xml.get_object('server_comboboxtext_entry1').\
|
|
| 243 |
+ get_text()
|
|
| 244 |
+ |
|
| 245 |
+ if not server:
|
|
| 246 |
+ ErrorDialog(
|
|
| 247 |
+ _('Invalid server'),
|
|
| 248 |
+ _('Please provide a server on which you want to register.'))
|
|
| 249 |
+ return
|
|
| 250 |
+ self.account = server
|
|
| 251 |
+ i = 1
|
|
| 252 |
+ while self.account in app.config.get_per('accounts'):
|
|
| 253 |
+ self.account = server + str(i)
|
|
| 254 |
+ i += 1
|
|
| 255 |
+ |
|
| 256 |
+ config = self.get_config('', server, '', '')
|
|
| 257 |
+ # Get advanced options
|
|
| 258 |
+ proxies_combobox = self.xml.get_object('proxies_combobox')
|
|
| 259 |
+ active = proxies_combobox.get_active()
|
|
| 260 |
+ proxy = proxies_combobox.get_model()[active][0]
|
|
| 261 |
+ if proxy == _('None'):
|
|
| 262 |
+ proxy = ''
|
|
| 263 |
+ config['proxy'] = proxy
|
|
| 264 |
+ |
|
| 265 |
+ config['use_custom_host'] = self.xml.get_object(
|
|
| 266 |
+ 'custom_host_port_checkbutton').get_active()
|
|
| 267 |
+ custom_port = self.xml.get_object('custom_port_entry').get_text()
|
|
| 268 |
+ try:
|
|
| 269 |
+ custom_port = int(custom_port)
|
|
| 270 |
+ except Exception:
|
|
| 271 |
+ ErrorDialog(
|
|
| 272 |
+ _('Invalid entry'),
|
|
| 273 |
+ _('Custom port must be a port number.'))
|
|
| 274 |
+ return
|
|
| 275 |
+ config['custom_port'] = custom_port
|
|
| 276 |
+ config['custom_host'] = self.xml.get_object(
|
|
| 277 |
+ 'custom_host_entry').get_text()
|
|
| 278 |
+ |
|
| 279 |
+ if self.xml.get_object('anonymous_checkbutton2').get_active():
|
|
| 280 |
+ self.modify = True
|
|
| 281 |
+ self.save_account('', server, False, '', anonymous=True)
|
|
| 282 |
+ self.show_finish_page()
|
|
| 283 |
+ else:
|
|
| 284 |
+ self.notebook.set_current_page(5) # show creating page
|
|
| 285 |
+ self.back_button.hide()
|
|
| 286 |
+ self.forward_button.hide()
|
|
| 287 |
+ self.update_progressbar_timeout_id = GLib.timeout_add(
|
|
| 288 |
+ 100, self.update_progressbar)
|
|
| 289 |
+ # Get form from serveur
|
|
| 290 |
+ con = connection.Connection(self.account)
|
|
| 291 |
+ app.connections[self.account] = con
|
|
| 292 |
+ con.new_account(self.account, config)
|
|
| 293 |
+ elif cur_page == 3:
|
|
| 294 |
+ checked = self.xml.get_object('ssl_checkbutton').get_active()
|
|
| 295 |
+ if checked:
|
|
| 296 |
+ hostname = app.connections[self.account].new_account_info[
|
|
| 297 |
+ 'hostname']
|
|
| 298 |
+ # Check if cert is already in file
|
|
| 299 |
+ certs = ''
|
|
| 300 |
+ my_ca_certs = configpaths.get('MY_CACERTS')
|
|
| 301 |
+ if os.path.isfile(my_ca_certs):
|
|
| 302 |
+ with open(my_ca_certs) as f:
|
|
| 303 |
+ certs = f.read()
|
|
| 304 |
+ if self.ssl_cert in certs:
|
|
| 305 |
+ ErrorDialog(
|
|
| 306 |
+ _('Certificate Already in File'),
|
|
| 307 |
+ _('This certificate is already in file %s, so it\'s '
|
|
| 308 |
+ 'not added again.') % my_ca_certs)
|
|
| 309 |
+ else:
|
|
| 310 |
+ with open(my_ca_certs, 'a') as f:
|
|
| 311 |
+ f.write(hostname + '\n')
|
|
| 312 |
+ f.write(self.ssl_cert + '\n\n')
|
|
| 313 |
+ app.connections[self.account].new_account_info[
|
|
| 314 |
+ 'ssl_fingerprint_sha1'] = self.ssl_fingerprint_sha1
|
|
| 315 |
+ app.connections[self.account].new_account_info[
|
|
| 316 |
+ 'ssl_fingerprint_sha256'] = self.ssl_fingerprint_sha256
|
|
| 317 |
+ self.notebook.set_current_page(4) # show fom page
|
|
| 318 |
+ elif cur_page == 4:
|
|
| 319 |
+ if self.is_form:
|
|
| 320 |
+ form = self.data_form_widget.data_form
|
|
| 321 |
+ else:
|
|
| 322 |
+ form = self.data_form_widget.get_infos()
|
|
| 323 |
+ app.connections[self.account].send_new_account_infos(
|
|
| 324 |
+ form, self.is_form)
|
|
| 325 |
+ self.xml.get_object('form_vbox').remove(self.data_form_widget)
|
|
| 326 |
+ self.xml.get_object('progressbar_label').set_markup(
|
|
| 327 |
+ '<b>Account is being created</b>\n\nPlease wait…')
|
|
| 328 |
+ self.notebook.set_current_page(5) # show creating page
|
|
| 329 |
+ self.back_button.hide()
|
|
| 330 |
+ self.forward_button.hide()
|
|
| 331 |
+ self.update_progressbar_timeout_id = GLib.timeout_add(
|
|
| 332 |
+ 100, self.update_progressbar)
|
|
| 333 |
+ |
|
| 334 |
+ def update_proxy_list(self):
|
|
| 335 |
+ proxies_combobox = self.xml.get_object('proxies_combobox')
|
|
| 336 |
+ model = Gtk.ListStore(str)
|
|
| 337 |
+ proxies_combobox.set_model(model)
|
|
| 338 |
+ proxies = app.config.get_per('proxies')
|
|
| 339 |
+ proxies.insert(0, _('None'))
|
|
| 340 |
+ for i in range(len(proxies)):
|
|
| 341 |
+ model.append([proxies[i]])
|
|
| 342 |
+ proxies_combobox.set_active(0)
|
|
| 343 |
+ |
|
| 344 |
+ def on_manage_proxies_button_clicked(self, widget):
|
|
| 345 |
+ if 'manage_proxies' in app.interface.instances:
|
|
| 346 |
+ app.interface.instances['manage_proxies'].window.present()
|
|
| 347 |
+ else:
|
|
| 348 |
+ app.interface.instances['manage_proxies'] = \
|
|
| 349 |
+ config.ManageProxiesWindow()
|
|
| 350 |
+ |
|
| 351 |
+ def on_custom_host_port_checkbutton_toggled(self, widget):
|
|
| 352 |
+ self.xml.get_object('custom_host_hbox').set_sensitive(
|
|
| 353 |
+ widget.get_active())
|
|
| 354 |
+ |
|
| 355 |
+ def update_progressbar(self):
|
|
| 356 |
+ self.progressbar.pulse()
|
|
| 357 |
+ return True # loop forever
|
|
| 358 |
+ |
|
| 359 |
+ def _nec_new_acc_connected(self, obj):
|
|
| 360 |
+ """
|
|
| 361 |
+ Connection to server succeded, present the form to the user
|
|
| 362 |
+ """
|
|
| 363 |
+ # We receive events from all accounts from GED
|
|
| 364 |
+ if obj.conn.name != self.account:
|
|
| 365 |
+ return
|
|
| 366 |
+ if self.update_progressbar_timeout_id is not None:
|
|
| 367 |
+ GLib.source_remove(self.update_progressbar_timeout_id)
|
|
| 368 |
+ self.back_button.show()
|
|
| 369 |
+ self.forward_button.show()
|
|
| 370 |
+ self.is_form = obj.is_form
|
|
| 371 |
+ empty_config = True
|
|
| 372 |
+ if obj.is_form:
|
|
| 373 |
+ dataform = dataforms.ExtendForm(node=obj.config)
|
|
| 374 |
+ self.data_form_widget = dataforms_widget.DataFormWidget()
|
|
| 375 |
+ self.data_form_widget.selectable = True
|
|
| 376 |
+ self.data_form_widget.set_data_form(dataform)
|
|
| 377 |
+ empty_config = False
|
|
| 378 |
+ else:
|
|
| 379 |
+ self.data_form_widget = config.FakeDataForm(
|
|
| 380 |
+ obj.config, selectable=True)
|
|
| 381 |
+ for field in obj.config:
|
|
| 382 |
+ if field in ('key', 'instructions', 'x', 'registered'):
|
|
| 383 |
+ continue
|
|
| 384 |
+ empty_config = False
|
|
| 385 |
+ break
|
|
| 386 |
+ self.data_form_widget.show_all()
|
|
| 387 |
+ self.xml.get_object('form_vbox').pack_start(
|
|
| 388 |
+ self.data_form_widget, True, True, 0)
|
|
| 389 |
+ if empty_config:
|
|
| 390 |
+ self.forward_button.set_sensitive(False)
|
|
| 391 |
+ self.notebook.set_current_page(4) # show form page
|
|
| 392 |
+ return
|
|
| 393 |
+ self.ssl_fingerprint_sha1 = obj.ssl_fingerprint_sha1
|
|
| 394 |
+ self.ssl_fingerprint_sha256 = obj.ssl_fingerprint_sha256
|
|
| 395 |
+ self.ssl_cert = obj.ssl_cert
|
|
| 396 |
+ if obj.ssl_msg:
|
|
| 397 |
+ # An SSL warning occured, show it
|
|
| 398 |
+ hostname = app.connections[self.account].new_account_info[
|
|
| 399 |
+ 'hostname']
|
|
| 400 |
+ self.xml.get_object('ssl_label').set_markup(_(
|
|
| 401 |
+ '<b>Security Warning</b>'
|
|
| 402 |
+ '\n\nThe authenticity of the %(hostname)s SSL certificate could'
|
|
| 403 |
+ ' be invalid.\nSSL Error: %(error)s\n'
|
|
| 404 |
+ 'Do you still want to connect to this server?') % {
|
|
| 405 |
+ 'hostname': hostname, 'error': obj.ssl_msg})
|
|
| 406 |
+ if obj.errnum in (18, 27):
|
|
| 407 |
+ text = _(
|
|
| 408 |
+ 'Add this certificate to the list of trusted '
|
|
| 409 |
+ 'certificates.\nSHA-1 fingerprint of the certificate:\n'
|
|
| 410 |
+ '%(sha1)s\nSHA-256 fingerprint of the certificate:\n'
|
|
| 411 |
+ '%(sha256)s') % {'sha1': obj.ssl_fingerprint_sha1,
|
|
| 412 |
+ 'sha256': obj.ssl_fingerprint_sha256}
|
|
| 413 |
+ self.xml.get_object('ssl_checkbutton').set_label(text)
|
|
| 414 |
+ else:
|
|
| 415 |
+ self.xml.get_object('ssl_checkbutton').set_no_show_all(True)
|
|
| 416 |
+ self.xml.get_object('ssl_checkbutton').hide()
|
|
| 417 |
+ self.notebook.set_current_page(3) # show SSL page
|
|
| 418 |
+ else:
|
|
| 419 |
+ self.notebook.set_current_page(4) # show form page
|
|
| 420 |
+ |
|
| 421 |
+ def _nec_new_acc_not_connected(self, obj):
|
|
| 422 |
+ """
|
|
| 423 |
+ Account creation failed: connection to server failed
|
|
| 424 |
+ """
|
|
| 425 |
+ # We receive events from all accounts from GED
|
|
| 426 |
+ if obj.conn.name != self.account:
|
|
| 427 |
+ return
|
|
| 428 |
+ if self.account not in app.connections:
|
|
| 429 |
+ return
|
|
| 430 |
+ if self.update_progressbar_timeout_id is not None:
|
|
| 431 |
+ GLib.source_remove(self.update_progressbar_timeout_id)
|
|
| 432 |
+ del app.connections[self.account]
|
|
| 433 |
+ if self.account in app.config.get_per('accounts'):
|
|
| 434 |
+ app.config.del_per('accounts', self.account)
|
|
| 435 |
+ self.back_button.show()
|
|
| 436 |
+ self.cancel_button.show()
|
|
| 437 |
+ self.go_online_checkbutton.hide()
|
|
| 438 |
+ self.show_vcard_checkbutton.hide()
|
|
| 439 |
+ img = self.xml.get_object('finish_image')
|
|
| 440 |
+ img.set_from_icon_name("dialog-error", Gtk.IconSize.DIALOG)
|
|
| 441 |
+ finish_text = '<big><b>%s</b></big>\n\n%s' % (
|
|
| 442 |
+ _('An error occurred during account creation'), obj.reason)
|
|
| 443 |
+ self.finish_label.set_markup(finish_text)
|
|
| 444 |
+ self.notebook.set_current_page(6) # show finish page
|
|
| 445 |
+ |
|
| 446 |
+ def _nec_acc_is_ok(self, obj):
|
|
| 447 |
+ """
|
|
| 448 |
+ Account creation succeeded
|
|
| 449 |
+ """
|
|
| 450 |
+ # We receive events from all accounts from GED
|
|
| 451 |
+ if obj.conn.name != self.account:
|
|
| 452 |
+ return
|
|
| 453 |
+ self.create_vars(obj.account_info)
|
|
| 454 |
+ self.show_finish_page()
|
|
| 455 |
+ |
|
| 456 |
+ if self.update_progressbar_timeout_id is not None:
|
|
| 457 |
+ GLib.source_remove(self.update_progressbar_timeout_id)
|
|
| 458 |
+ |
|
| 459 |
+ def _nec_acc_is_not_ok(self, obj):
|
|
| 460 |
+ """
|
|
| 461 |
+ Account creation failed
|
|
| 462 |
+ """
|
|
| 463 |
+ # We receive events from all accounts from GED
|
|
| 464 |
+ if obj.conn.name != self.account:
|
|
| 465 |
+ return
|
|
| 466 |
+ self.back_button.show()
|
|
| 467 |
+ self.cancel_button.show()
|
|
| 468 |
+ self.go_online_checkbutton.hide()
|
|
| 469 |
+ self.show_vcard_checkbutton.hide()
|
|
| 470 |
+ del app.connections[self.account]
|
|
| 471 |
+ if self.account in app.config.get_per('accounts'):
|
|
| 472 |
+ app.config.del_per('accounts', self.account)
|
|
| 473 |
+ img = self.xml.get_object('finish_image')
|
|
| 474 |
+ img.set_from_icon_name("dialog-error", Gtk.IconSize.DIALOG)
|
|
| 475 |
+ finish_text = '<big><b>%s</b></big>\n\n%s' % (_(
|
|
| 476 |
+ 'An error occurred during account creation'), obj.reason)
|
|
| 477 |
+ self.finish_label.set_markup(finish_text)
|
|
| 478 |
+ self.notebook.set_current_page(6) # show finish page
|
|
| 479 |
+ |
|
| 480 |
+ if self.update_progressbar_timeout_id is not None:
|
|
| 481 |
+ GLib.source_remove(self.update_progressbar_timeout_id)
|
|
| 482 |
+ |
|
| 483 |
+ def on_advanced_button_clicked(self, widget):
|
|
| 484 |
+ from gajim.accounts_window import AccountsWindow
|
|
| 485 |
+ if 'accounts' in app.interface.instances:
|
|
| 486 |
+ app.interface.instances['accounts'].present()
|
|
| 487 |
+ else:
|
|
| 488 |
+ app.interface.instances['accounts'] = AccountsWindow()
|
|
| 489 |
+ app.interface.instances['accounts'].select_account(self.account)
|
|
| 490 |
+ self.window.destroy()
|
|
| 491 |
+ |
|
| 492 |
+ def on_finish_button_clicked(self, widget):
|
|
| 493 |
+ go_online = self.xml.get_object('go_online_checkbutton').get_active()
|
|
| 494 |
+ show_vcard = self.xml.get_object('show_vcard_checkbutton').get_active()
|
|
| 495 |
+ self.window.destroy()
|
|
| 496 |
+ if show_vcard:
|
|
| 497 |
+ app.interface.show_vcard_when_connect.append(self.account)
|
|
| 498 |
+ if go_online:
|
|
| 499 |
+ app.interface.roster.send_status(self.account, 'online', '')
|
|
| 500 |
+ |
|
| 501 |
+ def on_username_entry_key_press_event(self, widget, event):
|
|
| 502 |
+ # Check for pressed @ and jump to combobox if found
|
|
| 503 |
+ if event.keyval == Gdk.KEY_at:
|
|
| 504 |
+ entry = self.xml.get_object('server_comboboxtext_entry')
|
|
| 505 |
+ entry.grab_focus()
|
|
| 506 |
+ entry.set_position(-1)
|
|
| 507 |
+ return True
|
|
| 508 |
+ |
|
| 509 |
+ def on_entry_key_press_event(self, widget, event, combobox):
|
|
| 510 |
+ # If backspace is pressed in empty field, return to the nick entry field
|
|
| 511 |
+ backspace = event.keyval == Gdk.KEY_BackSpace
|
|
| 512 |
+ empty = len(combobox.get_active_text()) == 0
|
|
| 513 |
+ if backspace and empty and self.modify:
|
|
| 514 |
+ username_entry = self.xml.get_object('username_entry')
|
|
| 515 |
+ username_entry.grab_focus()
|
|
| 516 |
+ username_entry.set_position(-1)
|
|
| 517 |
+ return True
|
|
| 518 |
+ |
|
| 519 |
+ def get_config(self, login, server, savepass, password, anonymous=False):
|
|
| 520 |
+ config = {}
|
|
| 521 |
+ config['name'] = login
|
|
| 522 |
+ config['account_label'] = '%s@%s' % (login, server)
|
|
| 523 |
+ config['hostname'] = server
|
|
| 524 |
+ config['savepass'] = savepass
|
|
| 525 |
+ config['password'] = password
|
|
| 526 |
+ config['anonymous_auth'] = anonymous
|
|
| 527 |
+ config['priority'] = 5
|
|
| 528 |
+ config['autoconnect'] = True
|
|
| 529 |
+ config['no_log_for'] = ''
|
|
| 530 |
+ config['sync_with_global_status'] = True
|
|
| 531 |
+ config['proxy'] = ''
|
|
| 532 |
+ config['use_custom_host'] = False
|
|
| 533 |
+ config['custom_port'] = 0
|
|
| 534 |
+ config['custom_host'] = ''
|
|
| 535 |
+ config['keyname'] = ''
|
|
| 536 |
+ config['keyid'] = ''
|
|
| 537 |
+ return config
|
|
| 538 |
+ |
|
| 539 |
+ def save_account(self, login, server, savepass, password, anonymous=False):
|
|
| 540 |
+ if self.account in app.connections:
|
|
| 541 |
+ ErrorDialog(
|
|
| 542 |
+ _('Account name is in use'),
|
|
| 543 |
+ _('You already have an account using this name.'))
|
|
| 544 |
+ return
|
|
| 545 |
+ con = connection.Connection(self.account)
|
|
| 546 |
+ con.password = password
|
|
| 547 |
+ |
|
| 548 |
+ config = self.get_config(login, server, savepass, password, anonymous)
|
|
| 549 |
+ |
|
| 550 |
+ if not self.modify:
|
|
| 551 |
+ con.new_account(self.account, config)
|
|
| 552 |
+ return
|
|
| 553 |
+ app.connections[self.account] = con
|
|
| 554 |
+ self.create_vars(config)
|
|
| 555 |
+ |
|
| 556 |
+ def create_vars(self, config):
|
|
| 557 |
+ app.config.add_per('accounts', self.account)
|
|
| 558 |
+ |
|
| 559 |
+ if not config['savepass']:
|
|
| 560 |
+ config['password'] = ''
|
|
| 561 |
+ |
|
| 562 |
+ for opt in config:
|
|
| 563 |
+ app.config.set_per('accounts', self.account, opt, config[opt])
|
|
| 564 |
+ |
|
| 565 |
+ # update variables
|
|
| 566 |
+ app.interface.instances[self.account] = {
|
|
| 567 |
+ 'infos': {}, 'disco': {},
|
|
| 568 |
+ 'gc_config': {}, 'search': {}, 'online_dialog': {},
|
|
| 569 |
+ 'sub_request': {}}
|
|
| 570 |
+ app.interface.minimized_controls[self.account] = {}
|
|
| 571 |
+ app.connections[self.account].connected = 0
|
|
| 572 |
+ app.connections[self.account].keepalives = app.config.get_per(
|
|
| 573 |
+ 'accounts', self.account, 'keep_alive_every_foo_secs')
|
|
| 574 |
+ app.groups[self.account] = {}
|
|
| 575 |
+ app.contacts.add_account(self.account)
|
|
| 576 |
+ app.gc_connected[self.account] = {}
|
|
| 577 |
+ app.automatic_rooms[self.account] = {}
|
|
| 578 |
+ app.newly_added[self.account] = []
|
|
| 579 |
+ app.to_be_removed[self.account] = []
|
|
| 580 |
+ app.nicks[self.account] = config['name']
|
|
| 581 |
+ app.block_signed_in_notifications[self.account] = True
|
|
| 582 |
+ app.sleeper_state[self.account] = 'off'
|
|
| 583 |
+ app.encrypted_chats[self.account] = []
|
|
| 584 |
+ app.last_message_time[self.account] = {}
|
|
| 585 |
+ app.status_before_autoaway[self.account] = ''
|
|
| 586 |
+ app.transport_avatar[self.account] = {}
|
|
| 587 |
+ app.gajim_optional_features[self.account] = []
|
|
| 588 |
+ app.caps_hash[self.account] = ''
|
|
| 589 |
+ helpers.update_optional_features(self.account)
|
|
| 590 |
+ # action must be added before account window is updated
|
|
| 591 |
+ app.app.add_account_actions(self.account)
|
|
| 592 |
+ # refresh accounts window
|
|
| 593 |
+ if 'accounts' in app.interface.instances:
|
|
| 594 |
+ app.interface.instances['accounts'].add_account(self.account)
|
|
| 595 |
+ # refresh roster
|
|
| 596 |
+ if len(app.connections) >= 2:
|
|
| 597 |
+ # Do not merge accounts if only one exists
|
|
| 598 |
+ app.interface.roster.regroup = app.config.get('mergeaccounts')
|
|
| 599 |
+ else:
|
|
| 600 |
+ app.interface.roster.regroup = False
|
|
| 601 |
+ app.interface.roster.setup_and_draw_roster()
|
|
| 602 |
+ gui_menu_builder.build_accounts_menu()
|
| 1 |
-# -*- coding:utf-8 -*-
|
|
| 2 |
-## src/features_window.py
|
|
| 3 |
-##
|
|
| 4 |
-## Copyright (C) 2007 Jean-Marie Traissard <jim AT lapin.org>
|
|
| 5 |
-## Julien Pivotto <roidelapluie AT gmail.com>
|
|
| 6 |
-## Stefan Bethge <stefan AT lanpartei.de>
|
|
| 7 |
-## Stephan Erb <steve-e AT h3c.de>
|
|
| 8 |
-## Copyright (C) 2007-2014 Yann Leboulanger <asterix AT lagaule.org>
|
|
| 9 |
-## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
|
| 10 |
-##
|
|
| 11 |
-## This file is part of Gajim.
|
|
| 12 |
-##
|
|
| 13 |
-## Gajim is free software; you can redistribute it and/or modify
|
|
| 14 |
-## it under the terms of the GNU General Public License as published
|
|
| 15 |
-## by the Free Software Foundation; version 3 only.
|
|
| 16 |
-##
|
|
| 17 |
-## Gajim is distributed in the hope that it will be useful,
|
|
| 18 |
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
| 19 |
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
| 20 |
-## GNU General Public License for more details.
|
|
| 21 |
-##
|
|
| 22 |
-## You should have received a copy of the GNU General Public License
|
|
| 23 |
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
|
| 24 |
-##
|
|
| 1 |
+# Copyright (C) 2007 Jean-Marie Traissard <jim AT lapin.org>
|
|
| 2 |
+# Julien Pivotto <roidelapluie AT gmail.com>
|
|
| 3 |
+# Stefan Bethge <stefan AT lanpartei.de>
|
|
| 4 |
+# Stephan Erb <steve-e AT h3c.de>
|
|
| 5 |
+# Copyright (C) 2007-2014 Yann Leboulanger <asterix AT lagaule.org>
|
|
| 6 |
+# Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
|
| 7 |
+#
|
|
| 8 |
+# This file is part of Gajim.
|
|
| 9 |
+#
|
|
| 10 |
+# Gajim is free software; you can redistribute it and/or modify
|
|
| 11 |
+# it under the terms of the GNU General Public License as published
|
|
| 12 |
+# by the Free Software Foundation; version 3 only.
|
|
| 13 |
+#
|
|
| 14 |
+# Gajim is distributed in the hope that it will be useful,
|
|
| 15 |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
| 16 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
| 17 |
+# GNU General Public License for more details.
|
|
| 18 |
+#
|
|
| 19 |
+# You should have received a copy of the GNU General Public License
|
|
| 20 |
+# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
|
| 25 | 21 |
|
| 26 | 22 |
import os
|
| 23 |
+ |
|
| 27 | 24 |
import gi
|
| 28 | 25 |
from gi.repository import Gtk, Gdk
|
| 29 |
-from gajim import gtkgui_helpers
|
|
| 30 | 26 |
|
| 31 | 27 |
from gajim.common import app
|
| 32 | 28 |
from gajim.common.i18n import Q_
|
| 29 |
+from gajim.gtk.util import get_builder
|
|
| 33 | 30 |
|
| 34 |
-class FeaturesWindow:
|
|
| 35 |
- """
|
|
| 36 |
- Class for features window
|
|
| 37 |
- """
|
|
| 38 | 31 |
|
| 32 |
+class FeaturesDialog(Gtk.Dialog):
|
|
| 39 | 33 |
def __init__(self):
|
| 40 |
- self.xml = gtkgui_helpers.get_gtk_builder('features_window.ui')
|
|
| 41 |
- self.window = self.xml.get_object('features_window')
|
|
| 42 |
- self.window.set_transient_for(app.interface.roster.window)
|
|
| 43 |
- treeview = self.xml.get_object('features_treeview')
|
|
| 44 |
- self.desc_label = self.xml.get_object('feature_desc_label')
|
|
| 34 |
+ flags = Gtk.DialogFlags.DESTROY_WITH_PARENT
|
|
| 35 |
+ super().__init__(_('Features'), None, flags)
|
|
| 36 |
+ |
|
| 37 |
+ self.connect('key-press-event', self.on_key_press_event)
|
|
| 38 |
+ self.set_transient_for(app.interface.roster.window)
|
|
| 39 |
+ |
|
| 40 |
+ self.builder = get_builder('features_window.ui')
|
|
| 41 |
+ content = self.get_content_area()
|
|
| 42 |
+ content.add(self.builder.get_object('features_box'))
|
|
| 43 |
+ |
|
| 44 |
+ treeview = self.builder.get_object('features_treeview')
|
|
| 45 |
+ self.desc_label = self.builder.get_object('feature_desc_label')
|
|
| 45 | 46 |
|
| 46 | 47 |
# {name: (available_function, unix_text, windows_text)}
|
| 47 | 48 |
self.features = {
|
| 48 |
- _('Bonjour / Zeroconf'): (self.zeroconf_available,
|
|
| 49 |
+ _('Bonjour / Zeroconf'): (
|
|
| 50 |
+ self.zeroconf_available,
|
|
| 49 | 51 |
_('Serverless chatting with autodetected clients in a local network.'),
|
| 50 | 52 |
_('Requires python-dbus.'),
|
| 51 | 53 |
_('Requires pybonjour and bonjour SDK running (%(url)s)') % {'url': 'https://developer.apple.com/opensource/).'}),
|
| 52 |
- _('Command line'): (self.dbus_available,
|
|
| 54 |
+ _('Command line'): (
|
|
| 55 |
+ self.dbus_available,
|
|
| 53 | 56 |
_('A script to control Gajim via commandline.'),
|
| 54 | 57 |
_('Requires python-dbus.'),
|
| 55 | 58 |
_('Feature not available under Windows.')),
|
| 56 |
- _('OpenPGP message encryption'): (self.gpg_available,
|
|
| 59 |
+ _('OpenPGP message encryption'): (
|
|
| 60 |
+ self.gpg_available,
|
|
| 57 | 61 |
_('Ability to encrypting chat messages with OpenPGP.'),
|
| 58 | 62 |
_('Requires gpg and python-gnupg (%(url)s).') % {'url': 'https://bitbucket.org/vinay.sajip/python-gnupg'},
|
| 59 | 63 |
_('Requires gpg.exe in PATH.')),
|
| 60 |
- _('Password encryption'): (self.some_keyring_available,
|
|
| 64 |
+ _('Password encryption'): (
|
|
| 65 |
+ self.some_keyring_available,
|
|
| 61 | 66 |
_('Passwords can be stored securely and not just in plaintext.'),
|
| 62 | 67 |
_('Requires libsecret and a provider (such as GNOME Keyring and KSecretService).'),
|
| 63 | 68 |
_('On Windows the Windows Credential Vault is used.')),
|
| 64 |
- _('Spell Checker'): (self.speller_available,
|
|
| 69 |
+ _('Spell Checker'): (
|
|
| 70 |
+ self.speller_available,
|
|
| 65 | 71 |
_('Spellchecking of composed messages.'),
|
| 66 | 72 |
_('Requires Gspell'),
|
| 67 | 73 |
_('Requires Gspell')),
|
| 68 |
- _('Automatic status'): (self.idle_available,
|
|
| 74 |
+ _('Automatic status'): (
|
|
| 75 |
+ self.idle_available,
|
|
| 69 | 76 |
_('Ability to measure idle time, in order to set auto status.'),
|
| 70 | 77 |
_('Requires libxss library.'),
|
| 71 | 78 |
_('Requires python2.5.')),
|
| 72 |
- _('RST Generator'): (self.docutils_available,
|
|
| 79 |
+ _('RST Generator'): (
|
|
| 80 |
+ self.docutils_available,
|
|
| 73 | 81 |
_('Generate XHTML output from RST code (see http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html).'),
|
| 74 | 82 |
_('Requires python-docutils.'),
|
| 75 | 83 |
_('Requires python-docutils.')),
|
| 76 |
- _('Audio / Video'): (self.farstream_available,
|
|
| 84 |
+ _('Audio / Video'): (
|
|
| 85 |
+ self.farstream_available,
|
|
| 77 | 86 |
_('Ability to start audio and video chat.'),
|
| 78 | 87 |
_('Requires gir1.2-farstream-0.2, gir1.2-gstreamer-1.0, gstreamer1.0-libav and gstreamer1.0-plugins-ugly.'),
|
| 79 | 88 |
_('Feature not available under Windows.')),
|
| 80 |
- _('UPnP-IGD'): (self.gupnp_igd_available,
|
|
| 89 |
+ _('UPnP-IGD'): (
|
|
| 90 |
+ self.gupnp_igd_available,
|
|
| 81 | 91 |
_('Ability to request your router to forward port for file transfer.'),
|
| 82 | 92 |
_('Requires gir1.2-gupnpigd-1.0.'),
|
| 83 | 93 |
_('Feature not available under Windows.')),
|
| ... | ... | @@ -108,16 +118,15 @@ class FeaturesWindow: |
| 108 | 118 |
|
| 109 | 119 |
self.model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
| 110 | 120 |
|
| 111 |
- self.xml.connect_signals(self)
|
|
| 112 |
- self.window.show_all()
|
|
| 113 |
- self.xml.get_object('close_button').grab_focus()
|
|
| 121 |
+ self.builder.connect_signals(self)
|
|
| 122 |
+ self.show_all()
|
|
| 114 | 123 |
|
| 115 | 124 |
def on_key_press_event(self, widget, event):
|
| 116 | 125 |
if event.keyval == Gdk.KEY_Escape:
|
| 117 |
- self.window.destroy()
|
|
| 126 |
+ self.destroy()
|
|
| 118 | 127 |
|
| 119 | 128 |
def on_close_button_clicked(self, widget):
|
| 120 |
- self.window.destroy()
|
|
| 129 |
+ self.destroy()
|
|
| 121 | 130 |
|
| 122 | 131 |
def on_features_treeview_cursor_changed(self, widget):
|
| 123 | 132 |
selection = widget.get_selection()
|
| ... | ... | @@ -70,6 +70,7 @@ from gajim.gtk import SingleMessageWindow |
| 70 | 70 |
from gajim.gtk import AddNewContactWindow
|
| 71 | 71 |
from gajim.gtk import ManagePEPServicesWindow
|
| 72 | 72 |
from gajim.gtk import ManageBookmarksWindow
|
| 73 |
+from gajim.gtk import AccountCreationWizard
|
|
| 73 | 74 |
|
| 74 | 75 |
from gajim.common.const import AvatarSize
|
| 75 | 76 |
|
| ... | ... | @@ -5881,7 +5882,7 @@ class RosterWindow: |
| 5881 | 5882 |
# if we have no account configured or only Local account but not enabled
|
| 5882 | 5883 |
def _open_wizard():
|
| 5883 | 5884 |
app.interface.instances['account_creation_wizard'] = \
|
| 5884 |
- config.AccountCreationWizardWindow()
|
|
| 5885 |
+ AccountCreationWizard()
|
|
| 5885 | 5886 |
# Open wizard only after roster is created, so we can make it
|
| 5886 | 5887 |
# transient for the roster window
|
| 5887 | 5888 |
GLib.idle_add(_open_wizard)
|