Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
c3437464
by Philipp Hörist at 2019-04-20T11:18:25Z
-
e495617d
by Philipp Hörist at 2019-04-20T12:19:22Z
-
e34886ae
by Philipp Hörist at 2019-04-20T12:58:22Z
7 changed files:
- gajim/common/const.py
- gajim/data/style/gajim.css
- gajim/gtk/accounts.py
- gajim/gtk/const.py
- gajim/options_dialog.py → gajim/gtk/settings.py
- gajim/gtk/util.py
- gajim/gtk/xml_console.py
Changes:
| ... | ... | @@ -3,36 +3,9 @@ from collections import namedtuple |
| 3 | 3 |
|
| 4 | 4 |
from gajim.common.i18n import _
|
| 5 | 5 |
|
| 6 |
-Option = namedtuple('Option', 'kind label type value name callback data desc enabledif props')
|
|
| 7 |
-Option.__new__.__defaults__ = (None,) * len(Option._fields) # type: ignore
|
|
| 8 |
- |
|
| 9 | 6 |
EncryptionData = namedtuple('EncryptionData', 'additional_data')
|
| 10 | 7 |
EncryptionData.__new__.__defaults__ = (None,) # type: ignore
|
| 11 | 8 |
|
| 12 |
-@unique
|
|
| 13 |
-class OptionKind(IntEnum):
|
|
| 14 |
- ENTRY = 0
|
|
| 15 |
- SWITCH = 1
|
|
| 16 |
- SPIN = 2
|
|
| 17 |
- ACTION = 3
|
|
| 18 |
- LOGIN = 4
|
|
| 19 |
- DIALOG = 5
|
|
| 20 |
- CALLBACK = 6
|
|
| 21 |
- PROXY = 7
|
|
| 22 |
- HOSTNAME = 8
|
|
| 23 |
- PRIORITY = 9
|
|
| 24 |
- FILECHOOSER = 10
|
|
| 25 |
- CHANGEPASSWORD = 11
|
|
| 26 |
- |
|
| 27 |
- |
|
| 28 |
-@unique
|
|
| 29 |
-class OptionType(IntEnum):
|
|
| 30 |
- ACCOUNT_CONFIG = 0
|
|
| 31 |
- CONFIG = 1
|
|
| 32 |
- VALUE = 2
|
|
| 33 |
- ACTION = 3
|
|
| 34 |
- DIALOG = 4
|
|
| 35 |
- |
|
| 36 | 9 |
|
| 37 | 10 |
class AvatarSize(IntEnum):
|
| 38 | 11 |
TAB = 16
|
| ... | ... | @@ -83,17 +83,17 @@ popover#EmoticonPopover { padding: 5px; background-color: @theme_unfocused_base_ |
| 83 | 83 |
#FeaturesInfoGrid > list > label { padding:10px; color: @insensitive_fg_color; font-weight: bold; }
|
| 84 | 84 |
#FeaturesInfoGrid > list > row.activatable:active { box-shadow: none; }
|
| 85 | 85 |
|
| 86 |
-/* OptionsBox */
|
|
| 87 |
-#OptionsBox > row { border-bottom: 1px solid; border-color: @theme_unfocused_bg_color; }
|
|
| 88 |
-#OptionsBox > row:last-child { border-bottom: 0px}
|
|
| 89 |
-#OptionsBox > row.activatable:active { box-shadow: none; }
|
|
| 90 |
-#OptionsBox > row { padding: 10px 20px 10px 10px; }
|
|
| 91 |
-#OptionsBox > row:not(.activatable) label { color: @insensitive_fg_color }
|
|
| 92 |
- |
|
| 93 |
-/* GenericOption */
|
|
| 86 |
+/* SettingsBox */
|
|
| 87 |
+#SettingsBox > row { border-bottom: 1px solid; border-color: @theme_unfocused_bg_color; }
|
|
| 88 |
+#SettingsBox > row:last-child { border-bottom: 0px}
|
|
| 89 |
+#SettingsBox > row.activatable:active { box-shadow: none; }
|
|
| 90 |
+#SettingsBox > row { padding: 10px 20px 10px 10px; }
|
|
| 91 |
+#SettingsBox > row:not(.activatable) label { color: @insensitive_fg_color }
|
|
| 92 |
+ |
|
| 93 |
+/* GenericSetting */
|
|
| 94 | 94 |
#SubDescription { color: @insensitive_fg_color;}
|
| 95 |
-#GenericOptionBox { margin-left: 30px; }
|
|
| 96 |
-#GenericOptionBox > label { padding-right: 3px; }
|
|
| 95 |
+#GenericSettingBox { margin-left: 30px; }
|
|
| 96 |
+#GenericSettingBox > label { padding-right: 3px; }
|
|
| 97 | 97 |
|
| 98 | 98 |
/* Generic Popover Menu with Buttons */
|
| 99 | 99 |
.PopoverButtonListbox { padding-left: 0px; padding-right: 0px; }
|
| ... | ... | @@ -25,16 +25,12 @@ from gajim.common import ged |
| 25 | 25 |
from gajim.common.i18n import _
|
| 26 | 26 |
from gajim.common.connection import Connection
|
| 27 | 27 |
from gajim.common.zeroconf.connection_zeroconf import ConnectionZeroconf
|
| 28 |
-from gajim.common.const import Option
|
|
| 29 |
-from gajim.common.const import OptionKind
|
|
| 30 |
-from gajim.common.const import OptionType
|
|
| 31 | 28 |
|
| 32 | 29 |
from gajim import gui_menu_builder
|
| 33 | 30 |
from gajim.dialogs import PassphraseDialog
|
| 34 | 31 |
|
| 35 |
-from gajim.options_dialog import OptionsDialog
|
|
| 36 |
-from gajim.options_dialog import OptionsBox
|
|
| 37 |
- |
|
| 32 |
+from gajim.gtk.settings import SettingsDialog
|
|
| 33 |
+from gajim.gtk.settings import SettingsBox
|
|
| 38 | 34 |
from gajim.gtk.dialogs import ConfirmationDialog
|
| 39 | 35 |
from gajim.gtk.dialogs import ConfirmationDialogDoubleRadio
|
| 40 | 36 |
from gajim.gtk.dialogs import ErrorDialog
|
| ... | ... | @@ -43,6 +39,9 @@ from gajim.gtk.dialogs import DialogButton |
| 43 | 39 |
from gajim.gtk.dialogs import NewConfirmationDialog
|
| 44 | 40 |
from gajim.gtk.util import get_icon_name
|
| 45 | 41 |
from gajim.gtk.util import get_builder
|
| 42 |
+from gajim.gtk.const import Setting
|
|
| 43 |
+from gajim.gtk.const import SettingKind
|
|
| 44 |
+from gajim.gtk.const import SettingType
|
|
| 46 | 45 |
|
| 47 | 46 |
|
| 48 | 47 |
class AccountsWindow(Gtk.ApplicationWindow):
|
| ... | ... | @@ -67,7 +66,7 @@ class AccountsWindow(Gtk.ApplicationWindow): |
| 67 | 66 |
accounts = app.config.get_per('accounts')
|
| 68 | 67 |
accounts.sort()
|
| 69 | 68 |
for account in accounts:
|
| 70 |
- self.need_relogin[account] = self.get_relogin_options(account)
|
|
| 69 |
+ self.need_relogin[account] = self.get_relogin_settings(account)
|
|
| 71 | 70 |
account_item = Account(account, self)
|
| 72 | 71 |
self._ui.account_list.add(account_item)
|
| 73 | 72 |
account_item.set_activatable()
|
| ... | ... | @@ -135,14 +134,14 @@ class AccountsWindow(Gtk.ApplicationWindow): |
| 135 | 134 |
page = self._ui.stack.get_child_by_name('connection')
|
| 136 | 135 |
if page is None:
|
| 137 | 136 |
return
|
| 138 |
- page.listbox.get_option('proxy').update_values()
|
|
| 137 |
+ page.listbox.get_setting('proxy').update_values()
|
|
| 139 | 138 |
|
| 140 | 139 |
def check_relogin(self):
|
| 141 | 140 |
for account in self.need_relogin:
|
| 142 |
- options = self.get_relogin_options(account)
|
|
| 141 |
+ settings = self.get_relogin_settings(account)
|
|
| 143 | 142 |
active = app.config.get_per('accounts', account, 'active')
|
| 144 |
- if options != self.need_relogin[account]:
|
|
| 145 |
- self.need_relogin[account] = options
|
|
| 143 |
+ if settings != self.need_relogin[account]:
|
|
| 144 |
+ self.need_relogin[account] = settings
|
|
| 146 | 145 |
if active:
|
| 147 | 146 |
self.relog(account)
|
| 148 | 147 |
break
|
| ... | ... | @@ -180,17 +179,17 @@ class AccountsWindow(Gtk.ApplicationWindow): |
| 180 | 179 |
on_response_yes=lambda *args: relog(account))
|
| 181 | 180 |
|
| 182 | 181 |
@staticmethod
|
| 183 |
- def get_relogin_options(account):
|
|
| 182 |
+ def get_relogin_settings(account):
|
|
| 184 | 183 |
if account == app.ZEROCONF_ACC_NAME:
|
| 185 |
- options = ['zeroconf_first_name', 'zeroconf_last_name',
|
|
| 186 |
- 'zeroconf_jabber_id', 'zeroconf_email']
|
|
| 184 |
+ settings = ['zeroconf_first_name', 'zeroconf_last_name',
|
|
| 185 |
+ 'zeroconf_jabber_id', 'zeroconf_email']
|
|
| 187 | 186 |
else:
|
| 188 |
- options = ['client_cert', 'proxy', 'resource',
|
|
| 189 |
- 'use_custom_host', 'custom_host', 'custom_port']
|
|
| 187 |
+ settings = ['client_cert', 'proxy', 'resource',
|
|
| 188 |
+ 'use_custom_host', 'custom_host', 'custom_port']
|
|
| 190 | 189 |
|
| 191 | 190 |
values = []
|
| 192 |
- for option in options:
|
|
| 193 |
- values.append(app.config.get_per('accounts', account, option))
|
|
| 191 |
+ for setting in settings:
|
|
| 192 |
+ values.append(app.config.get_per('accounts', account, setting))
|
|
| 194 | 193 |
return values
|
| 195 | 194 |
|
| 196 | 195 |
def on_remove_account(self, button, account):
|
| ... | ... | @@ -248,7 +247,7 @@ class AccountsWindow(Gtk.ApplicationWindow): |
| 248 | 247 |
account_item.set_activatable()
|
| 249 | 248 |
self._ui.account_list.show_all()
|
| 250 | 249 |
self._ui.stack.show_all()
|
| 251 |
- self.need_relogin[account] = self.get_relogin_options(account)
|
|
| 250 |
+ self.need_relogin[account] = self.get_relogin_settings(account)
|
|
| 252 | 251 |
|
| 253 | 252 |
def select_account(self, account):
|
| 254 | 253 |
for row in self._ui.account_list.get_children():
|
| ... | ... | @@ -365,7 +364,7 @@ class Preferences(Gtk.Box): |
| 365 | 364 |
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL,
|
| 366 | 365 |
spacing=12)
|
| 367 | 366 |
|
| 368 |
- self.options = PreferencesPage()
|
|
| 367 |
+ self.settings = PreferencesPage()
|
|
| 369 | 368 |
self.parent = parent
|
| 370 | 369 |
self.account = None
|
| 371 | 370 |
|
| ... | ... | @@ -383,8 +382,8 @@ class Preferences(Gtk.Box): |
| 383 | 382 |
pass
|
| 384 | 383 |
|
| 385 | 384 |
def on_row_activated(self):
|
| 386 |
- self.options.update_states()
|
|
| 387 |
- self.parent.set_page(self.options, 'pref')
|
|
| 385 |
+ self.settings.update_states()
|
|
| 386 |
+ self.parent.set_page(self.settings, 'pref')
|
|
| 388 | 387 |
|
| 389 | 388 |
def update(self):
|
| 390 | 389 |
pass
|
| ... | ... | @@ -396,9 +395,9 @@ class Account(Gtk.Box): |
| 396 | 395 |
spacing=12)
|
| 397 | 396 |
self.account = account
|
| 398 | 397 |
if account == app.ZEROCONF_ACC_NAME:
|
| 399 |
- self.options = ZeroConfPage(account, parent)
|
|
| 398 |
+ self.settings = ZeroConfPage(account, parent)
|
|
| 400 | 399 |
else:
|
| 401 |
- self.options = AccountPage(account, parent)
|
|
| 400 |
+ self.settings = AccountPage(account, parent)
|
|
| 402 | 401 |
self.parent = parent
|
| 403 | 402 |
|
| 404 | 403 |
self.label = Gtk.Label(label=app.get_account_label(account))
|
| ... | ... | @@ -421,8 +420,8 @@ class Account(Gtk.Box): |
| 421 | 420 |
_('Please check if Avahi or Bonjour is installed.'))
|
| 422 | 421 |
|
| 423 | 422 |
def on_row_activated(self):
|
| 424 |
- self.options.update_states()
|
|
| 425 |
- self.parent.set_page(self.options, 'account')
|
|
| 423 |
+ self.settings.update_states()
|
|
| 424 |
+ self.parent.set_page(self.settings, 'account')
|
|
| 426 | 425 |
|
| 427 | 426 |
def update(self):
|
| 428 | 427 |
self.label.set_text(app.get_account_label(self.account))
|
| ... | ... | @@ -434,8 +433,8 @@ class Account(Gtk.Box): |
| 434 | 433 |
self.image.set_from_icon_name(icon, Gtk.IconSize.MENU)
|
| 435 | 434 |
|
| 436 | 435 |
|
| 437 |
-class GenericOptionPage(Gtk.Box):
|
|
| 438 |
- def __init__(self, account, parent, options):
|
|
| 436 |
+class GenericSettingPage(Gtk.Box):
|
|
| 437 |
+ def __init__(self, account, parent, settings):
|
|
| 439 | 438 |
Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL, spacing=12)
|
| 440 | 439 |
self.account = account
|
| 441 | 440 |
self.parent = parent
|
| ... | ... | @@ -447,13 +446,13 @@ class GenericOptionPage(Gtk.Box): |
| 447 | 446 |
if not isinstance(self, (AccountPage, PreferencesPage, ZeroConfPage)):
|
| 448 | 447 |
self.pack_start(button, False, True, 0)
|
| 449 | 448 |
|
| 450 |
- self.listbox = OptionsBox(account)
|
|
| 449 |
+ self.listbox = SettingsBox(account)
|
|
| 451 | 450 |
self.listbox.set_selection_mode(Gtk.SelectionMode.NONE)
|
| 452 | 451 |
self.listbox.set_vexpand(False)
|
| 453 | 452 |
self.listbox.set_valign(Gtk.Align.END)
|
| 454 | 453 |
|
| 455 |
- for option in options:
|
|
| 456 |
- self.listbox.add_option(option)
|
|
| 454 |
+ for setting in settings:
|
|
| 455 |
+ self.listbox.add_setting(setting)
|
|
| 457 | 456 |
self.listbox.update_states()
|
| 458 | 457 |
|
| 459 | 458 |
self.pack_end(self.listbox, True, True, 0)
|
| ... | ... | @@ -471,7 +470,7 @@ class GenericOptionPage(Gtk.Box): |
| 471 | 470 |
self.listbox.update_states()
|
| 472 | 471 |
|
| 473 | 472 |
def on_row_activated(self, listbox, row):
|
| 474 |
- row.get_child().on_row_activated()
|
|
| 473 |
+ row.on_row_activated()
|
|
| 475 | 474 |
|
| 476 | 475 |
def set_entry_text(self, toggle, update=False):
|
| 477 | 476 |
account_label = app.get_account_label(self.account)
|
| ... | ... | @@ -495,9 +494,9 @@ class GenericOptionPage(Gtk.Box): |
| 495 | 494 |
def update(self):
|
| 496 | 495 |
pass
|
| 497 | 496 |
|
| 498 |
- def set_page(self, options, name):
|
|
| 499 |
- options.update_states()
|
|
| 500 |
- self.get_toplevel().set_page(options, name)
|
|
| 497 |
+ def set_page(self, settings, name):
|
|
| 498 |
+ settings.update_states()
|
|
| 499 |
+ self.get_toplevel().set_page(settings, name)
|
|
| 501 | 500 |
|
| 502 | 501 |
def _add_top_buttons(self, parent):
|
| 503 | 502 |
# This adds the Account enable switch and the back button
|
| ... | ... | @@ -560,18 +559,18 @@ class GenericOptionPage(Gtk.Box): |
| 560 | 559 |
app.config.set_per('accounts', account, 'active', state)
|
| 561 | 560 |
|
| 562 | 561 |
|
| 563 |
-class PreferencesPage(GenericOptionPage):
|
|
| 562 |
+class PreferencesPage(GenericSettingPage):
|
|
| 564 | 563 |
def __init__(self):
|
| 565 | 564 |
|
| 566 |
- options = [
|
|
| 567 |
- Option(OptionKind.SWITCH, _('Merge Accounts'),
|
|
| 568 |
- OptionType.ACTION, 'merge'),
|
|
| 565 |
+ settings = [
|
|
| 566 |
+ Setting(SettingKind.SWITCH, _('Merge Accounts'),
|
|
| 567 |
+ SettingType.ACTION, 'merge'),
|
|
| 569 | 568 |
]
|
| 570 | 569 |
|
| 571 |
- GenericOptionPage.__init__(self, None, None, options)
|
|
| 570 |
+ GenericSettingPage.__init__(self, None, None, settings)
|
|
| 572 | 571 |
|
| 573 | 572 |
|
| 574 |
-class AccountPage(GenericOptionPage):
|
|
| 573 |
+class AccountPage(GenericSettingPage):
|
|
| 575 | 574 |
def __init__(self, account, parent=None):
|
| 576 | 575 |
|
| 577 | 576 |
general = partial(
|
| ... | ... | @@ -579,152 +578,150 @@ class AccountPage(GenericOptionPage): |
| 579 | 578 |
connection = partial(
|
| 580 | 579 |
self.set_page, ConnectionPage(account, self), 'connection')
|
| 581 | 580 |
|
| 582 |
- options = [
|
|
| 583 |
- Option(OptionKind.ENTRY, _('Label'),
|
|
| 584 |
- OptionType.ACCOUNT_CONFIG, 'account_label',
|
|
| 585 |
- callback=self._on_account_name_change),
|
|
| 581 |
+ settings = [
|
|
| 582 |
+ Setting(SettingKind.ENTRY, _('Label'),
|
|
| 583 |
+ SettingType.ACCOUNT_CONFIG, 'account_label',
|
|
| 584 |
+ callback=self._on_account_name_change),
|
|
| 586 | 585 |
|
| 587 |
- Option(OptionKind.LOGIN, _('Login'), OptionType.DIALOG,
|
|
| 588 |
- props={'dialog': LoginDialog}),
|
|
| 586 |
+ Setting(SettingKind.LOGIN, _('Login'), SettingType.DIALOG,
|
|
| 587 |
+ props={'dialog': LoginDialog}),
|
|
| 589 | 588 |
|
| 590 |
- Option(OptionKind.ACTION, _('Profile'), OptionType.ACTION,
|
|
| 591 |
- '-profile', props={'action_args': account}),
|
|
| 589 |
+ Setting(SettingKind.ACTION, _('Profile'), SettingType.ACTION,
|
|
| 590 |
+ '-profile', props={'action_args': account}),
|
|
| 592 | 591 |
|
| 593 |
- Option(OptionKind.CALLBACK, _('General'),
|
|
| 594 |
- name='general', props={'callback': general}),
|
|
| 592 |
+ Setting(SettingKind.CALLBACK, _('General'),
|
|
| 593 |
+ name='general', props={'callback': general}),
|
|
| 595 | 594 |
|
| 596 |
- Option(OptionKind.CALLBACK, _('Connection'),
|
|
| 597 |
- name='connection', props={'callback': connection}),
|
|
| 595 |
+ Setting(SettingKind.CALLBACK, _('Connection'),
|
|
| 596 |
+ name='connection', props={'callback': connection}),
|
|
| 598 | 597 |
|
| 599 |
- Option(OptionKind.ACTION, _('Import Contacts'), OptionType.ACTION,
|
|
| 600 |
- '-import-contacts', props={'action_args': account}),
|
|
| 598 |
+ Setting(SettingKind.ACTION, _('Import Contacts'), SettingType.ACTION,
|
|
| 599 |
+ '-import-contacts', props={'action_args': account}),
|
|
| 601 | 600 |
|
| 602 |
- Option(OptionKind.DIALOG, _('Client Certificate'),
|
|
| 603 |
- OptionType.DIALOG, props={'dialog': CertificateDialog}),
|
|
| 601 |
+ Setting(SettingKind.DIALOG, _('Client Certificate'),
|
|
| 602 |
+ SettingType.DIALOG, props={'dialog': CertificateDialog}),
|
|
| 604 | 603 |
]
|
| 605 | 604 |
|
| 606 |
- GenericOptionPage.__init__(self, account, parent, options)
|
|
| 605 |
+ GenericSettingPage.__init__(self, account, parent, settings)
|
|
| 607 | 606 |
self._add_top_buttons(parent)
|
| 608 | 607 |
|
| 609 | 608 |
def _on_account_name_change(self, account_name, *args):
|
| 610 | 609 |
self.parent.update_accounts()
|
| 611 | 610 |
|
| 612 | 611 |
|
| 613 |
-class GeneralPage(GenericOptionPage):
|
|
| 612 |
+class GeneralPage(GenericSettingPage):
|
|
| 614 | 613 |
def __init__(self, account, parent=None):
|
| 615 | 614 |
|
| 616 |
- options = [
|
|
| 617 |
- Option(OptionKind.SWITCH, _('Connect on startup'),
|
|
| 618 |
- OptionType.ACCOUNT_CONFIG, 'autoconnect'),
|
|
| 615 |
+ settings = [
|
|
| 616 |
+ Setting(SettingKind.SWITCH, _('Connect on startup'),
|
|
| 617 |
+ SettingType.ACCOUNT_CONFIG, 'autoconnect'),
|
|
| 619 | 618 |
|
| 620 |
- Option(OptionKind.SWITCH, _('Reconnect when connection is lost'),
|
|
| 621 |
- OptionType.ACCOUNT_CONFIG, 'autoreconnect'),
|
|
| 619 |
+ Setting(SettingKind.SWITCH, _('Reconnect when connection is lost'),
|
|
| 620 |
+ SettingType.ACCOUNT_CONFIG, 'autoreconnect'),
|
|
| 622 | 621 |
|
| 623 |
- Option(OptionKind.SWITCH, _('Save conversations for all contacts'),
|
|
| 624 |
- OptionType.ACCOUNT_CONFIG, 'no_log_for',
|
|
| 625 |
- desc=_('Store conversations on the harddrive')),
|
|
| 622 |
+ Setting(SettingKind.SWITCH, _('Save conversations for all contacts'),
|
|
| 623 |
+ SettingType.ACCOUNT_CONFIG, 'no_log_for',
|
|
| 624 |
+ desc=_('Store conversations on the harddrive')),
|
|
| 626 | 625 |
|
| 627 |
- Option(OptionKind.SWITCH, _('Server Message Archive'),
|
|
| 628 |
- OptionType.ACCOUNT_CONFIG, 'sync_logs_with_server',
|
|
| 629 |
- desc=_('Messages get stored on the server.\n'
|
|
| 630 |
- 'The archive is used to sync messages\n'
|
|
| 631 |
- 'between multiple devices.\n'
|
|
| 632 |
- 'XEP-0313')),
|
|
| 626 |
+ Setting(SettingKind.SWITCH, _('Server Message Archive'),
|
|
| 627 |
+ SettingType.ACCOUNT_CONFIG, 'sync_logs_with_server',
|
|
| 628 |
+ desc=_('Messages get stored on the server. '
|
|
| 629 |
+ 'The archive is used to sync messages '
|
|
| 630 |
+ 'between multiple devices. (XEP-0313)')),
|
|
| 633 | 631 |
|
| 634 |
- Option(OptionKind.SWITCH, _('Global Status'),
|
|
| 635 |
- OptionType.ACCOUNT_CONFIG, 'sync_with_global_status',
|
|
| 636 |
- desc=_('Synchronise the status of all accounts')),
|
|
| 632 |
+ Setting(SettingKind.SWITCH, _('Global Status'),
|
|
| 633 |
+ SettingType.ACCOUNT_CONFIG, 'sync_with_global_status',
|
|
| 634 |
+ desc=_('Synchronise the status of all accounts')),
|
|
| 637 | 635 |
|
| 638 |
- Option(OptionKind.SWITCH, _('Message Carbons'),
|
|
| 639 |
- OptionType.ACCOUNT_CONFIG, 'enable_message_carbons',
|
|
| 640 |
- desc=_('All your other online devices get copies\n'
|
|
| 641 |
- 'of sent and received messages.\n'
|
|
| 642 |
- 'XEP-0280')),
|
|
| 636 |
+ Setting(SettingKind.SWITCH, _('Message Carbons'),
|
|
| 637 |
+ SettingType.ACCOUNT_CONFIG, 'enable_message_carbons',
|
|
| 638 |
+ desc=_('All your other online devices get copies '
|
|
| 639 |
+ 'of sent and received messages. XEP-0280')),
|
|
| 643 | 640 |
|
| 644 |
- Option(OptionKind.SWITCH, _('Use file transfer proxies'),
|
|
| 645 |
- OptionType.ACCOUNT_CONFIG, 'use_ft_proxies'),
|
|
| 641 |
+ Setting(SettingKind.SWITCH, _('Use file transfer proxies'),
|
|
| 642 |
+ SettingType.ACCOUNT_CONFIG, 'use_ft_proxies'),
|
|
| 646 | 643 |
]
|
| 647 |
- GenericOptionPage.__init__(self, account, parent, options)
|
|
| 644 |
+ GenericSettingPage.__init__(self, account, parent, settings)
|
|
| 648 | 645 |
|
| 649 | 646 |
|
| 650 |
-class ConnectionPage(GenericOptionPage):
|
|
| 647 |
+class ConnectionPage(GenericSettingPage):
|
|
| 651 | 648 |
def __init__(self, account, parent=None):
|
| 652 | 649 |
|
| 653 |
- options = [
|
|
| 654 |
- Option(OptionKind.SWITCH, 'HTTP_PROXY',
|
|
| 655 |
- OptionType.ACCOUNT_CONFIG, 'use_env_http_proxy',
|
|
| 656 |
- desc=_('Use environment variable')),
|
|
| 650 |
+ settings = [
|
|
| 651 |
+ Setting(SettingKind.SWITCH, 'HTTP_PROXY',
|
|
| 652 |
+ SettingType.ACCOUNT_CONFIG, 'use_env_http_proxy',
|
|
| 653 |
+ desc=_('Use environment variable')),
|
|
| 657 | 654 |
|
| 658 |
- Option(OptionKind.PROXY, _('Proxy'),
|
|
| 659 |
- OptionType.ACCOUNT_CONFIG, 'proxy', name='proxy'),
|
|
| 655 |
+ Setting(SettingKind.PROXY, _('Proxy'),
|
|
| 656 |
+ SettingType.ACCOUNT_CONFIG, 'proxy', name='proxy'),
|
|
| 660 | 657 |
|
| 661 |
- Option(OptionKind.SWITCH, _('Warn on insecure connection'),
|
|
| 662 |
- OptionType.ACCOUNT_CONFIG,
|
|
| 663 |
- 'warn_when_insecure_ssl_connection'),
|
|
| 658 |
+ Setting(SettingKind.SWITCH, _('Warn on insecure connection'),
|
|
| 659 |
+ SettingType.ACCOUNT_CONFIG,
|
|
| 660 |
+ 'warn_when_insecure_ssl_connection'),
|
|
| 664 | 661 |
|
| 665 |
- Option(OptionKind.SWITCH, _('Send keep-alive packets'),
|
|
| 666 |
- OptionType.ACCOUNT_CONFIG, 'keep_alives_enabled'),
|
|
| 662 |
+ Setting(SettingKind.SWITCH, _('Send keep-alive packets'),
|
|
| 663 |
+ SettingType.ACCOUNT_CONFIG, 'keep_alives_enabled'),
|
|
| 667 | 664 |
|
| 668 |
- Option(OptionKind.HOSTNAME, _('Hostname'), OptionType.DIALOG,
|
|
| 669 |
- desc=_('Manually set the hostname for the server'),
|
|
| 670 |
- props={'dialog': CutstomHostnameDialog}),
|
|
| 665 |
+ Setting(SettingKind.HOSTNAME, _('Hostname'), SettingType.DIALOG,
|
|
| 666 |
+ desc=_('Manually set the hostname for the server'),
|
|
| 667 |
+ props={'dialog': CutstomHostnameDialog}),
|
|
| 671 | 668 |
|
| 672 |
- Option(OptionKind.ENTRY, _('Resource'),
|
|
| 673 |
- OptionType.ACCOUNT_CONFIG, 'resource'),
|
|
| 669 |
+ Setting(SettingKind.ENTRY, _('Resource'),
|
|
| 670 |
+ SettingType.ACCOUNT_CONFIG, 'resource'),
|
|
| 674 | 671 |
|
| 675 |
- Option(OptionKind.PRIORITY, _('Priority'),
|
|
| 676 |
- OptionType.DIALOG, props={'dialog': PriorityDialog}),
|
|
| 672 |
+ Setting(SettingKind.PRIORITY, _('Priority'),
|
|
| 673 |
+ SettingType.DIALOG, props={'dialog': PriorityDialog}),
|
|
| 677 | 674 |
]
|
| 678 | 675 |
|
| 679 |
- GenericOptionPage.__init__(self, account, parent, options)
|
|
| 676 |
+ GenericSettingPage.__init__(self, account, parent, settings)
|
|
| 680 | 677 |
|
| 681 | 678 |
|
| 682 |
-class ZeroConfPage(GenericOptionPage):
|
|
| 679 |
+class ZeroConfPage(GenericSettingPage):
|
|
| 683 | 680 |
def __init__(self, account, parent=None):
|
| 684 | 681 |
|
| 685 |
- options = [
|
|
| 686 |
- Option(OptionKind.DIALOG, _('Profile'),
|
|
| 687 |
- OptionType.DIALOG, props={'dialog': ZeroconfProfileDialog}),
|
|
| 682 |
+ settings = [
|
|
| 683 |
+ Setting(SettingKind.DIALOG, _('Profile'),
|
|
| 684 |
+ SettingType.DIALOG, props={'dialog': ZeroconfProfileDialog}),
|
|
| 688 | 685 |
|
| 689 |
- Option(OptionKind.SWITCH, _('Connect on startup'),
|
|
| 690 |
- OptionType.ACCOUNT_CONFIG, 'autoconnect',
|
|
| 691 |
- desc=_('Use environment variable')),
|
|
| 686 |
+ Setting(SettingKind.SWITCH, _('Connect on startup'),
|
|
| 687 |
+ SettingType.ACCOUNT_CONFIG, 'autoconnect',
|
|
| 688 |
+ desc=_('Use environment variable')),
|
|
| 692 | 689 |
|
| 693 |
- Option(OptionKind.SWITCH, _('Save conversations for all contacts'),
|
|
| 694 |
- OptionType.ACCOUNT_CONFIG, 'no_log_for',
|
|
| 695 |
- desc=_('Store conversations on the harddrive')),
|
|
| 690 |
+ Setting(SettingKind.SWITCH, _('Save conversations for all contacts'),
|
|
| 691 |
+ SettingType.ACCOUNT_CONFIG, 'no_log_for',
|
|
| 692 |
+ desc=_('Store conversations on the harddrive')),
|
|
| 696 | 693 |
|
| 697 |
- Option(OptionKind.SWITCH, _('Global Status'),
|
|
| 698 |
- OptionType.ACCOUNT_CONFIG, 'sync_with_global_status',
|
|
| 699 |
- desc=_('Synchronize the status of all accounts')),
|
|
| 694 |
+ Setting(SettingKind.SWITCH, _('Global Status'),
|
|
| 695 |
+ SettingType.ACCOUNT_CONFIG, 'sync_with_global_status',
|
|
| 696 |
+ desc=_('Synchronize the status of all accounts')),
|
|
| 700 | 697 |
]
|
| 701 | 698 |
|
| 702 |
- GenericOptionPage.__init__(self, account, parent, options)
|
|
| 699 |
+ GenericSettingPage.__init__(self, account, parent, settings)
|
|
| 703 | 700 |
self._add_top_buttons(None)
|
| 704 | 701 |
|
| 705 | 702 |
|
| 706 |
-class ZeroconfProfileDialog(OptionsDialog):
|
|
| 703 |
+class ZeroconfProfileDialog(SettingsDialog):
|
|
| 707 | 704 |
def __init__(self, account, parent):
|
| 708 | 705 |
|
| 709 |
- options = [
|
|
| 710 |
- Option(OptionKind.ENTRY, _('First Name'),
|
|
| 711 |
- OptionType.ACCOUNT_CONFIG, 'zeroconf_first_name'),
|
|
| 706 |
+ settings = [
|
|
| 707 |
+ Setting(SettingKind.ENTRY, _('First Name'),
|
|
| 708 |
+ SettingType.ACCOUNT_CONFIG, 'zeroconf_first_name'),
|
|
| 712 | 709 |
|
| 713 |
- Option(OptionKind.ENTRY, _('Last Name'),
|
|
| 714 |
- OptionType.ACCOUNT_CONFIG, 'zeroconf_last_name'),
|
|
| 710 |
+ Setting(SettingKind.ENTRY, _('Last Name'),
|
|
| 711 |
+ SettingType.ACCOUNT_CONFIG, 'zeroconf_last_name'),
|
|
| 715 | 712 |
|
| 716 |
- Option(OptionKind.ENTRY, _('Jabber ID'),
|
|
| 717 |
- OptionType.ACCOUNT_CONFIG, 'zeroconf_jabber_id'),
|
|
| 713 |
+ Setting(SettingKind.ENTRY, _('Jabber ID'),
|
|
| 714 |
+ SettingType.ACCOUNT_CONFIG, 'zeroconf_jabber_id'),
|
|
| 718 | 715 |
|
| 719 |
- Option(OptionKind.ENTRY, _('Email'),
|
|
| 720 |
- OptionType.ACCOUNT_CONFIG, 'zeroconf_email'),
|
|
| 716 |
+ Setting(SettingKind.ENTRY, _('Email'),
|
|
| 717 |
+ SettingType.ACCOUNT_CONFIG, 'zeroconf_email'),
|
|
| 721 | 718 |
]
|
| 722 | 719 |
|
| 723 |
- OptionsDialog.__init__(self, parent, _('Profile'),
|
|
| 724 |
- Gtk.DialogFlags.MODAL, options, account)
|
|
| 720 |
+ SettingsDialog.__init__(self, parent, _('Profile'),
|
|
| 721 |
+ Gtk.DialogFlags.MODAL, settings, account)
|
|
| 725 | 722 |
|
| 726 | 723 |
|
| 727 |
-class PriorityDialog(OptionsDialog):
|
|
| 724 |
+class PriorityDialog(SettingsDialog):
|
|
| 728 | 725 |
def __init__(self, account, parent):
|
| 729 | 726 |
|
| 730 | 727 |
neg_priority = app.config.get('enable_negative_priority')
|
| ... | ... | @@ -733,18 +730,18 @@ class PriorityDialog(OptionsDialog): |
| 733 | 730 |
else:
|
| 734 | 731 |
range_ = (0, 127)
|
| 735 | 732 |
|
| 736 |
- options = [
|
|
| 737 |
- Option(OptionKind.SWITCH, _('Adjust to status'),
|
|
| 738 |
- OptionType.ACCOUNT_CONFIG, 'adjust_priority_with_status',
|
|
| 739 |
- 'adjust'),
|
|
| 733 |
+ settings = [
|
|
| 734 |
+ Setting(SettingKind.SWITCH, _('Adjust to status'),
|
|
| 735 |
+ SettingType.ACCOUNT_CONFIG, 'adjust_priority_with_status',
|
|
| 736 |
+ 'adjust'),
|
|
| 740 | 737 |
|
| 741 |
- Option(OptionKind.SPIN, _('Priority'),
|
|
| 742 |
- OptionType.ACCOUNT_CONFIG, 'priority',
|
|
| 743 |
- enabledif=('adjust', False), props={'range_': range_}),
|
|
| 738 |
+ Setting(SettingKind.SPIN, _('Priority'),
|
|
| 739 |
+ SettingType.ACCOUNT_CONFIG, 'priority',
|
|
| 740 |
+ enabledif=('adjust', False), props={'range_': range_}),
|
|
| 744 | 741 |
]
|
| 745 | 742 |
|
| 746 |
- OptionsDialog.__init__(self, parent, _('Priority'),
|
|
| 747 |
- Gtk.DialogFlags.MODAL, options, account)
|
|
| 743 |
+ SettingsDialog.__init__(self, parent, _('Priority'),
|
|
| 744 |
+ Gtk.DialogFlags.MODAL, settings, account)
|
|
| 748 | 745 |
|
| 749 | 746 |
self.connect('destroy', self.on_destroy)
|
| 750 | 747 |
|
| ... | ... | @@ -757,60 +754,60 @@ class PriorityDialog(OptionsDialog): |
| 757 | 754 |
app.connections[self.account].change_status(show, status)
|
| 758 | 755 |
|
| 759 | 756 |
|
| 760 |
-class CutstomHostnameDialog(OptionsDialog):
|
|
| 757 |
+class CutstomHostnameDialog(SettingsDialog):
|
|
| 761 | 758 |
def __init__(self, account, parent):
|
| 762 | 759 |
|
| 763 |
- options = [
|
|
| 764 |
- Option(OptionKind.SWITCH, _('Enable'),
|
|
| 765 |
- OptionType.ACCOUNT_CONFIG, 'use_custom_host', name='custom'),
|
|
| 760 |
+ settings = [
|
|
| 761 |
+ Setting(SettingKind.SWITCH, _('Enable'),
|
|
| 762 |
+ SettingType.ACCOUNT_CONFIG, 'use_custom_host', name='custom'),
|
|
| 766 | 763 |
|
| 767 |
- Option(OptionKind.ENTRY, _('Hostname'),
|
|
| 768 |
- OptionType.ACCOUNT_CONFIG, 'custom_host',
|
|
| 769 |
- enabledif=('custom', True)),
|
|
| 764 |
+ Setting(SettingKind.ENTRY, _('Hostname'),
|
|
| 765 |
+ SettingType.ACCOUNT_CONFIG, 'custom_host',
|
|
| 766 |
+ enabledif=('custom', True)),
|
|
| 770 | 767 |
|
| 771 |
- Option(OptionKind.ENTRY, _('Port'),
|
|
| 772 |
- OptionType.ACCOUNT_CONFIG, 'custom_port',
|
|
| 773 |
- enabledif=('custom', True)),
|
|
| 768 |
+ Setting(SettingKind.ENTRY, _('Port'),
|
|
| 769 |
+ SettingType.ACCOUNT_CONFIG, 'custom_port',
|
|
| 770 |
+ enabledif=('custom', True)),
|
|
| 774 | 771 |
]
|
| 775 | 772 |
|
| 776 |
- OptionsDialog.__init__(self, parent, _('Connection Options'),
|
|
| 777 |
- Gtk.DialogFlags.MODAL, options, account)
|
|
| 773 |
+ SettingsDialog.__init__(self, parent, _('Connection Settings'),
|
|
| 774 |
+ Gtk.DialogFlags.MODAL, settings, account)
|
|
| 778 | 775 |
|
| 779 | 776 |
|
| 780 |
-class CertificateDialog(OptionsDialog):
|
|
| 777 |
+class CertificateDialog(SettingsDialog):
|
|
| 781 | 778 |
def __init__(self, account, parent):
|
| 782 | 779 |
|
| 783 |
- options = [
|
|
| 784 |
- Option(OptionKind.FILECHOOSER, _('Client Certificate'),
|
|
| 785 |
- OptionType.ACCOUNT_CONFIG, 'client_cert',
|
|
| 786 |
- props={'filefilter': (_('PKCS12 Files'), '*.p12')}),
|
|
| 780 |
+ Settings = [
|
|
| 781 |
+ Setting(SettingKind.FILECHOOSER, _('Client Certificate'),
|
|
| 782 |
+ SettingType.ACCOUNT_CONFIG, 'client_cert',
|
|
| 783 |
+ props={'filefilter': (_('PKCS12 Files'), '*.p12')}),
|
|
| 787 | 784 |
|
| 788 |
- Option(OptionKind.SWITCH, _('Encrypted Certificate'),
|
|
| 789 |
- OptionType.ACCOUNT_CONFIG, 'client_cert_encrypted'),
|
|
| 785 |
+ Setting(SettingKind.SWITCH, _('Encrypted Certificate'),
|
|
| 786 |
+ SettingType.ACCOUNT_CONFIG, 'client_cert_encrypted'),
|
|
| 790 | 787 |
]
|
| 791 | 788 |
|
| 792 |
- OptionsDialog.__init__(self, parent, _('Certificate Options'),
|
|
| 793 |
- Gtk.DialogFlags.MODAL, options, account)
|
|
| 789 |
+ SettingsDialog.__init__(self, parent, _('Certificate Settings'),
|
|
| 790 |
+ Gtk.DialogFlags.MODAL, Settings, account)
|
|
| 794 | 791 |
|
| 795 | 792 |
|
| 796 |
-class LoginDialog(OptionsDialog):
|
|
| 793 |
+class LoginDialog(SettingsDialog):
|
|
| 797 | 794 |
def __init__(self, account, parent):
|
| 798 | 795 |
|
| 799 |
- options = [
|
|
| 800 |
- Option(OptionKind.ENTRY, _('Password'),
|
|
| 801 |
- OptionType.ACCOUNT_CONFIG, 'password', name='password',
|
|
| 802 |
- enabledif=('savepass', True)),
|
|
| 796 |
+ settings = [
|
|
| 797 |
+ Setting(SettingKind.ENTRY, _('Password'),
|
|
| 798 |
+ SettingType.ACCOUNT_CONFIG, 'password', name='password',
|
|
| 799 |
+ enabledif=('savepass', True)),
|
|
| 803 | 800 |
|
| 804 |
- Option(OptionKind.SWITCH, _('Save Password'),
|
|
| 805 |
- OptionType.ACCOUNT_CONFIG, 'savepass', name='savepass'),
|
|
| 801 |
+ Setting(SettingKind.SWITCH, _('Save Password'),
|
|
| 802 |
+ SettingType.ACCOUNT_CONFIG, 'savepass', name='savepass'),
|
|
| 806 | 803 |
|
| 807 |
- Option(OptionKind.CHANGEPASSWORD, _('Change Password'),
|
|
| 808 |
- OptionType.DIALOG, callback=self.on_password_change,
|
|
| 809 |
- props={'dialog': None}),
|
|
| 804 |
+ Setting(SettingKind.CHANGEPASSWORD, _('Change Password'),
|
|
| 805 |
+ SettingType.DIALOG, callback=self.on_password_change,
|
|
| 806 |
+ props={'dialog': None}),
|
|
| 810 | 807 |
]
|
| 811 | 808 |
|
| 812 |
- OptionsDialog.__init__(self, parent, _('Login Options'),
|
|
| 813 |
- Gtk.DialogFlags.MODAL, options, account)
|
|
| 809 |
+ SettingsDialog.__init__(self, parent, _('Login Settings'),
|
|
| 810 |
+ Gtk.DialogFlags.MODAL, settings, account)
|
|
| 814 | 811 |
|
| 815 | 812 |
self.connect('destroy', self.on_destroy)
|
| 816 | 813 |
|
| ... | ... | @@ -21,6 +21,9 @@ from enum import unique |
| 21 | 21 |
|
| 22 | 22 |
Filter = namedtuple('Filter', 'name pattern default')
|
| 23 | 23 |
|
| 24 |
+Setting = namedtuple('Setting', 'kind label type value name callback data desc enabledif props')
|
|
| 25 |
+Setting.__new__.__defaults__ = (None,) * len(Setting._fields) # type: ignore
|
|
| 26 |
+ |
|
| 24 | 27 |
@unique
|
| 25 | 28 |
class Theme(IntEnum):
|
| 26 | 29 |
NOT_DARK = 0
|
| ... | ... | @@ -36,3 +39,29 @@ class GajimIconSet(Enum): |
| 36 | 39 |
JABBERBULB = 'jabberbulb'
|
| 37 | 40 |
SUN = 'sun'
|
| 38 | 41 |
WROOP = 'wroop'
|
| 42 |
+ |
|
| 43 |
+ |
|
| 44 |
+@unique
|
|
| 45 |
+class SettingKind(IntEnum):
|
|
| 46 |
+ ENTRY = 0
|
|
| 47 |
+ SWITCH = 1
|
|
| 48 |
+ SPIN = 2
|
|
| 49 |
+ ACTION = 3
|
|
| 50 |
+ LOGIN = 4
|
|
| 51 |
+ DIALOG = 5
|
|
| 52 |
+ CALLBACK = 6
|
|
| 53 |
+ PROXY = 7
|
|
| 54 |
+ HOSTNAME = 8
|
|
| 55 |
+ PRIORITY = 9
|
|
| 56 |
+ FILECHOOSER = 10
|
|
| 57 |
+ CHANGEPASSWORD = 11
|
|
| 58 |
+ COMBO = 12
|
|
| 59 |
+ |
|
| 60 |
+ |
|
| 61 |
+@unique
|
|
| 62 |
+class SettingType(IntEnum):
|
|
| 63 |
+ ACCOUNT_CONFIG = 0
|
|
| 64 |
+ CONFIG = 1
|
|
| 65 |
+ VALUE = 2
|
|
| 66 |
+ ACTION = 3
|
|
| 67 |
+ DIALOG = 4
|
| 1 |
-from gi.repository import Gtk, GLib, Gdk, GObject
|
|
| 1 |
+# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
|
|
| 2 |
+#
|
|
| 3 |
+# This file is part of Gajim.
|
|
| 4 |
+#
|
|
| 5 |
+# Gajim is free software; you can redistribute it and/or modify
|
|
| 6 |
+# it under the terms of the GNU General Public License as published
|
|
| 7 |
+# by the Free Software Foundation; version 3 only.
|
|
| 8 |
+#
|
|
| 9 |
+# Gajim is distributed in the hope that it will be useful,
|
|
| 10 |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
| 11 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
| 12 |
+# GNU General Public License for more details.
|
|
| 13 |
+#
|
|
| 14 |
+# You should have received a copy of the GNU General Public License
|
|
| 15 |
+# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
|
| 16 |
+ |
|
| 17 |
+from gi.repository import Gtk
|
|
| 18 |
+from gi.repository import GLib
|
|
| 19 |
+from gi.repository import Gdk
|
|
| 20 |
+from gi.repository import GObject
|
|
| 21 |
+from gi.repository import Pango
|
|
| 22 |
+ |
|
| 2 | 23 |
from gajim.common import app
|
| 3 | 24 |
from gajim.common import passwords
|
| 4 | 25 |
from gajim.common.i18n import _
|
| 5 |
-from gajim import gtkgui_helpers
|
|
| 6 |
-from gajim.common.const import OptionKind, OptionType
|
|
| 26 |
+ |
|
| 7 | 27 |
from gajim.common.exceptions import GajimGeneralException
|
| 28 |
+ |
|
| 29 |
+from gajim import gtkgui_helpers
|
|
| 30 |
+ |
|
| 8 | 31 |
from gajim.gtk.dialogs import ChangePasswordDialog
|
| 9 | 32 |
from gajim.gtk.util import get_image_button
|
| 33 |
+from gajim.gtk.util import MaxWidthComboBoxText
|
|
| 34 |
+from gajim.gtk.const import SettingKind
|
|
| 35 |
+from gajim.gtk.const import SettingType
|
|
| 10 | 36 |
|
| 11 | 37 |
|
| 12 |
-class OptionsDialog(Gtk.ApplicationWindow):
|
|
| 13 |
- def __init__(self, parent, title, flags, options, account,
|
|
| 38 |
+class SettingsDialog(Gtk.ApplicationWindow):
|
|
| 39 |
+ def __init__(self, parent, title, flags, settings, account,
|
|
| 14 | 40 |
extend=None):
|
| 15 | 41 |
Gtk.ApplicationWindow.__init__(self)
|
| 16 | 42 |
self.set_application(app.app)
|
| ... | ... | @@ -26,12 +52,12 @@ class OptionsDialog(Gtk.ApplicationWindow): |
| 26 | 52 |
elif flags == Gtk.DialogFlags.DESTROY_WITH_PARENT:
|
| 27 | 53 |
self.set_destroy_with_parent(True)
|
| 28 | 54 |
|
| 29 |
- self.listbox = OptionsBox(account, extend)
|
|
| 55 |
+ self.listbox = SettingsBox(account, extend)
|
|
| 30 | 56 |
self.listbox.set_hexpand(True)
|
| 31 | 57 |
self.listbox.set_selection_mode(Gtk.SelectionMode.NONE)
|
| 32 | 58 |
|
| 33 |
- for option in options:
|
|
| 34 |
- self.listbox.add_option(option)
|
|
| 59 |
+ for setting in settings:
|
|
| 60 |
+ self.listbox.add_setting(setting)
|
|
| 35 | 61 |
self.listbox.update_states()
|
| 36 | 62 |
|
| 37 | 63 |
self.add(self.listbox)
|
| ... | ... | @@ -46,78 +72,82 @@ class OptionsDialog(Gtk.ApplicationWindow): |
| 46 | 72 |
|
| 47 | 73 |
@staticmethod
|
| 48 | 74 |
def on_row_activated(listbox, row):
|
| 49 |
- row.get_child().on_row_activated()
|
|
| 75 |
+ row.on_row_activated()
|
|
| 50 | 76 |
|
| 51 |
- def get_option(self, name):
|
|
| 52 |
- return self.listbox.get_option(name)
|
|
| 77 |
+ def get_setting(self, name):
|
|
| 78 |
+ return self.listbox.get_setting(name)
|
|
| 53 | 79 |
|
| 54 | 80 |
|
| 55 |
-class OptionsBox(Gtk.ListBox):
|
|
| 81 |
+class SettingsBox(Gtk.ListBox):
|
|
| 56 | 82 |
def __init__(self, account, extend=None):
|
| 57 | 83 |
Gtk.ListBox.__init__(self)
|
| 58 |
- self.set_name('OptionsBox')
|
|
| 84 |
+ self.set_name('SettingsBox')
|
|
| 59 | 85 |
self.account = account
|
| 60 |
- self.named_options = {}
|
|
| 86 |
+ self.named_settings = {}
|
|
| 61 | 87 |
|
| 62 | 88 |
self.map = {
|
| 63 |
- OptionKind.SWITCH: SwitchOption,
|
|
| 64 |
- OptionKind.SPIN: SpinOption,
|
|
| 65 |
- OptionKind.DIALOG: DialogOption,
|
|
| 66 |
- OptionKind.ENTRY: EntryOption,
|
|
| 67 |
- OptionKind.ACTION: ActionOption,
|
|
| 68 |
- OptionKind.LOGIN: LoginOption,
|
|
| 69 |
- OptionKind.FILECHOOSER: FileChooserOption,
|
|
| 70 |
- OptionKind.CALLBACK: CallbackOption,
|
|
| 71 |
- OptionKind.PROXY: ProxyComboOption,
|
|
| 72 |
- OptionKind.PRIORITY: PriorityOption,
|
|
| 73 |
- OptionKind.HOSTNAME: CutstomHostnameOption,
|
|
| 74 |
- OptionKind.CHANGEPASSWORD: ChangePasswordOption,
|
|
| 89 |
+ SettingKind.SWITCH: SwitchSetting,
|
|
| 90 |
+ SettingKind.SPIN: SpinSetting,
|
|
| 91 |
+ SettingKind.DIALOG: DialogSetting,
|
|
| 92 |
+ SettingKind.ENTRY: EntrySetting,
|
|
| 93 |
+ SettingKind.ACTION: ActionSetting,
|
|
| 94 |
+ SettingKind.LOGIN: LoginSetting,
|
|
| 95 |
+ SettingKind.FILECHOOSER: FileChooserSetting,
|
|
| 96 |
+ SettingKind.CALLBACK: CallbackSetting,
|
|
| 97 |
+ SettingKind.PROXY: ProxyComboSetting,
|
|
| 98 |
+ SettingKind.PRIORITY: PrioritySetting,
|
|
| 99 |
+ SettingKind.HOSTNAME: CutstomHostnameSetting,
|
|
| 100 |
+ SettingKind.CHANGEPASSWORD: ChangePasswordSetting,
|
|
| 101 |
+ SettingKind.COMBO: ComboSetting,
|
|
| 75 | 102 |
}
|
| 76 | 103 |
|
| 77 | 104 |
if extend is not None:
|
| 78 |
- for option, callback in extend:
|
|
| 79 |
- self.map[option] = callback
|
|
| 80 |
- |
|
| 81 |
- def add_option(self, option):
|
|
| 82 |
- if option.props is not None:
|
|
| 83 |
- listitem = self.map[option.kind](
|
|
| 84 |
- self.account, *option[1:-1], **option.props)
|
|
| 85 |
- else:
|
|
| 86 |
- listitem = self.map[option.kind](self.account, *option[1:-1])
|
|
| 87 |
- listitem.connect('notify::option-value', self.on_option_changed)
|
|
| 88 |
- if option.name is not None:
|
|
| 89 |
- self.named_options[option.name] = listitem
|
|
| 105 |
+ for setting, callback in extend:
|
|
| 106 |
+ self.map[setting] = callback
|
|
| 107 |
+ |
|
| 108 |
+ def add_setting(self, setting):
|
|
| 109 |
+ if not isinstance(setting, Gtk.ListBoxRow):
|
|
| 110 |
+ if setting.props is not None:
|
|
| 111 |
+ listitem = self.map[setting.kind](
|
|
| 112 |
+ self.account, *setting[1:-1], **setting.props)
|
|
| 113 |
+ else:
|
|
| 114 |
+ listitem = self.map[setting.kind](self.account, *setting[1:-1])
|
|
| 115 |
+ listitem.connect('notify::setting-value', self.on_setting_changed)
|
|
| 116 |
+ if setting.name is not None:
|
|
| 117 |
+ self.named_settings[setting.name] = listitem
|
|
| 90 | 118 |
self.add(listitem)
|
| 91 | 119 |
|
| 92 |
- def get_option(self, name):
|
|
| 93 |
- return self.named_options[name]
|
|
| 120 |
+ def get_setting(self, name):
|
|
| 121 |
+ return self.named_settings[name]
|
|
| 94 | 122 |
|
| 95 | 123 |
def update_states(self):
|
| 96 | 124 |
values = []
|
| 97 | 125 |
values.append((None, None))
|
| 98 | 126 |
for row in self.get_children():
|
| 99 |
- name = row.get_child().name
|
|
| 127 |
+ name = row.name
|
|
| 100 | 128 |
if name is None:
|
| 101 | 129 |
continue
|
| 102 |
- value = row.get_child().get_property('option-value')
|
|
| 130 |
+ value = row.get_property('setting-value')
|
|
| 103 | 131 |
values.append((name, value))
|
| 104 | 132 |
|
| 105 | 133 |
for name, value in values:
|
| 106 | 134 |
for row in self.get_children():
|
| 107 |
- row.get_child().set_activatable(name, value)
|
|
| 135 |
+ row.update_activatable(name, value)
|
|
| 108 | 136 |
|
| 109 |
- def on_option_changed(self, widget, *args):
|
|
| 110 |
- value = widget.get_property('option-value')
|
|
| 137 |
+ def on_setting_changed(self, widget, *args):
|
|
| 138 |
+ value = widget.get_property('setting-value')
|
|
| 111 | 139 |
for row in self.get_children():
|
| 112 |
- row.get_child().set_activatable(widget.name, value)
|
|
| 140 |
+ row.update_activatable(widget.name, value)
|
|
| 113 | 141 |
|
| 114 | 142 |
|
| 115 |
-class GenericOption(Gtk.Grid):
|
|
| 143 |
+class GenericSetting(Gtk.ListBoxRow):
|
|
| 116 | 144 |
def __init__(self, account, label, type_, value,
|
| 117 | 145 |
name, callback, data, desc, enabledif):
|
| 118 |
- Gtk.Grid.__init__(self)
|
|
| 119 |
- self.set_column_spacing(12)
|
|
| 120 |
- self.set_size_request(-1, 25)
|
|
| 146 |
+ Gtk.ListBoxRow.__init__(self)
|
|
| 147 |
+ self._grid = Gtk.Grid()
|
|
| 148 |
+ self._grid.set_size_request(-1, 30)
|
|
| 149 |
+ self._grid.set_column_spacing(12)
|
|
| 150 |
+ |
|
| 121 | 151 |
self.callback = callback
|
| 122 | 152 |
self.type_ = type_
|
| 123 | 153 |
self.value = value
|
| ... | ... | @@ -126,18 +156,18 @@ class GenericOption(Gtk.Grid): |
| 126 | 156 |
self.account = account
|
| 127 | 157 |
self.name = name
|
| 128 | 158 |
self.enabledif = enabledif
|
| 129 |
- self.option_value = self.get_value()
|
|
| 159 |
+ self.setting_value = self.get_value()
|
|
| 130 | 160 |
|
| 131 | 161 |
description_box = Gtk.Box(
|
| 132 | 162 |
orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
| 133 | 163 |
description_box.set_valign(Gtk.Align.CENTER)
|
| 134 | 164 |
|
| 135 |
- optiontext = Gtk.Label(label=label)
|
|
| 136 |
- optiontext.set_hexpand(True)
|
|
| 137 |
- optiontext.set_halign(Gtk.Align.START)
|
|
| 138 |
- optiontext.set_valign(Gtk.Align.CENTER)
|
|
| 139 |
- optiontext.set_vexpand(True)
|
|
| 140 |
- description_box.add(optiontext)
|
|
| 165 |
+ settingtext = Gtk.Label(label=label)
|
|
| 166 |
+ settingtext.set_hexpand(True)
|
|
| 167 |
+ settingtext.set_halign(Gtk.Align.START)
|
|
| 168 |
+ settingtext.set_valign(Gtk.Align.CENTER)
|
|
| 169 |
+ settingtext.set_vexpand(True)
|
|
| 170 |
+ description_box.add(settingtext)
|
|
| 141 | 171 |
|
| 142 | 172 |
if desc is not None:
|
| 143 | 173 |
description = Gtk.Label(label=desc)
|
| ... | ... | @@ -145,24 +175,29 @@ class GenericOption(Gtk.Grid): |
| 145 | 175 |
description.set_hexpand(True)
|
| 146 | 176 |
description.set_halign(Gtk.Align.START)
|
| 147 | 177 |
description.set_valign(Gtk.Align.CENTER)
|
| 178 |
+ description.set_xalign(0)
|
|
| 179 |
+ description.set_line_wrap(True)
|
|
| 180 |
+ description.set_line_wrap_mode(Pango.WrapMode.WORD)
|
|
| 181 |
+ description.set_max_width_chars(40)
|
|
| 148 | 182 |
description_box.add(description)
|
| 149 | 183 |
|
| 150 |
- self.add(description_box)
|
|
| 184 |
+ self._grid.add(description_box)
|
|
| 151 | 185 |
|
| 152 |
- self.option_box = Gtk.Box(spacing=6)
|
|
| 153 |
- self.option_box.set_size_request(200, -1)
|
|
| 154 |
- self.option_box.set_valign(Gtk.Align.CENTER)
|
|
| 155 |
- self.option_box.set_name('GenericOptionBox')
|
|
| 156 |
- self.add(self.option_box)
|
|
| 186 |
+ self.setting_box = Gtk.Box(spacing=6)
|
|
| 187 |
+ self.setting_box.set_size_request(200, -1)
|
|
| 188 |
+ self.setting_box.set_valign(Gtk.Align.CENTER)
|
|
| 189 |
+ self.setting_box.set_name('GenericSettingBox')
|
|
| 190 |
+ self._grid.add(self.setting_box)
|
|
| 191 |
+ self.add(self._grid)
|
|
| 157 | 192 |
|
| 158 | 193 |
def do_get_property(self, prop):
|
| 159 |
- if prop.name == 'option-value':
|
|
| 160 |
- return self.option_value
|
|
| 194 |
+ if prop.name == 'setting-value':
|
|
| 195 |
+ return self.setting_value
|
|
| 161 | 196 |
raise AttributeError('unknown property %s' % prop.name)
|
| 162 | 197 |
|
| 163 | 198 |
def do_set_property(self, prop, value):
|
| 164 |
- if prop.name == 'option-value':
|
|
| 165 |
- self.option_value = value
|
|
| 199 |
+ if prop.name == 'setting-value':
|
|
| 200 |
+ self.setting_value = value
|
|
| 166 | 201 |
else:
|
| 167 | 202 |
raise AttributeError('unknown property %s' % prop.name)
|
| 168 | 203 |
|
| ... | ... | @@ -173,13 +208,13 @@ class GenericOption(Gtk.Grid): |
| 173 | 208 |
def __get_value(type_, value, account):
|
| 174 | 209 |
if value is None:
|
| 175 | 210 |
return
|
| 176 |
- if type_ == OptionType.VALUE:
|
|
| 211 |
+ if type_ == SettingType.VALUE:
|
|
| 177 | 212 |
return value
|
| 178 | 213 |
|
| 179 |
- if type_ == OptionType.CONFIG:
|
|
| 214 |
+ if type_ == SettingType.CONFIG:
|
|
| 180 | 215 |
return app.config.get(value)
|
| 181 | 216 |
|
| 182 |
- if type_ == OptionType.ACCOUNT_CONFIG:
|
|
| 217 |
+ if type_ == SettingType.ACCOUNT_CONFIG:
|
|
| 183 | 218 |
if value == 'password':
|
| 184 | 219 |
return passwords.get_password(account)
|
| 185 | 220 |
if value == 'no_log_for':
|
| ... | ... | @@ -188,17 +223,17 @@ class GenericOption(Gtk.Grid): |
| 188 | 223 |
return account not in no_log
|
| 189 | 224 |
return app.config.get_per('accounts', account, value)
|
| 190 | 225 |
|
| 191 |
- if type_ == OptionType.ACTION:
|
|
| 226 |
+ if type_ == SettingType.ACTION:
|
|
| 192 | 227 |
if value.startswith('-'):
|
| 193 | 228 |
return account + value
|
| 194 | 229 |
return value
|
| 195 | 230 |
|
| 196 |
- raise ValueError('Wrong OptionType?')
|
|
| 231 |
+ raise ValueError('Wrong SettingType?')
|
|
| 197 | 232 |
|
| 198 | 233 |
def set_value(self, state):
|
| 199 |
- if self.type_ == OptionType.CONFIG:
|
|
| 234 |
+ if self.type_ == SettingType.CONFIG:
|
|
| 200 | 235 |
app.config.set(self.value, state)
|
| 201 |
- if self.type_ == OptionType.ACCOUNT_CONFIG:
|
|
| 236 |
+ if self.type_ == SettingType.ACCOUNT_CONFIG:
|
|
| 202 | 237 |
if self.value == 'password':
|
| 203 | 238 |
passwords.save_password(self.account, state)
|
| 204 | 239 |
if self.value == 'no_log_for':
|
| ... | ... | @@ -209,7 +244,7 @@ class GenericOption(Gtk.Grid): |
| 209 | 244 |
if self.callback is not None:
|
| 210 | 245 |
self.callback(state, self.data)
|
| 211 | 246 |
|
| 212 |
- self.set_property('option-value', state)
|
|
| 247 |
+ self.set_property('setting-value', state)
|
|
| 213 | 248 |
|
| 214 | 249 |
@staticmethod
|
| 215 | 250 |
def set_no_log_for(account, state):
|
| ... | ... | @@ -223,36 +258,36 @@ class GenericOption(Gtk.Grid): |
| 223 | 258 |
def on_row_activated(self):
|
| 224 | 259 |
raise NotImplementedError
|
| 225 | 260 |
|
| 226 |
- def set_activatable(self, name, value):
|
|
| 261 |
+ def update_activatable(self, name, value):
|
|
| 227 | 262 |
if self.enabledif is None or self.enabledif[0] != name:
|
| 228 | 263 |
return
|
| 229 | 264 |
activatable = (name, value) == self.enabledif
|
| 230 |
- self.get_parent().set_activatable(activatable)
|
|
| 265 |
+ self.set_activatable(activatable)
|
|
| 231 | 266 |
self.set_sensitive(activatable)
|
| 232 | 267 |
|
| 233 | 268 |
|
| 234 |
-class SwitchOption(GenericOption):
|
|
| 269 |
+class SwitchSetting(GenericSetting):
|
|
| 235 | 270 |
|
| 236 | 271 |
__gproperties__ = {
|
| 237 |
- "option-value": (bool, 'Switch Value', '', False,
|
|
| 272 |
+ "setting-value": (bool, 'Switch Value', '', False,
|
|
| 238 | 273 |
GObject.ParamFlags.READWRITE),}
|
| 239 | 274 |
|
| 240 | 275 |
def __init__(self, *args):
|
| 241 |
- GenericOption.__init__(self, *args)
|
|
| 276 |
+ GenericSetting.__init__(self, *args)
|
|
| 242 | 277 |
|
| 243 | 278 |
self.switch = Gtk.Switch()
|
| 244 |
- if self.type_ == OptionType.ACTION:
|
|
| 245 |
- self.switch.set_action_name('app.%s' % self.option_value)
|
|
| 246 |
- state = app.app.get_action_state(self.option_value)
|
|
| 279 |
+ if self.type_ == SettingType.ACTION:
|
|
| 280 |
+ self.switch.set_action_name('app.%s' % self.setting_value)
|
|
| 281 |
+ state = app.app.get_action_state(self.setting_value)
|
|
| 247 | 282 |
self.switch.set_active(state.get_boolean())
|
| 248 | 283 |
else:
|
| 249 |
- self.switch.set_active(self.option_value)
|
|
| 284 |
+ self.switch.set_active(self.setting_value)
|
|
| 250 | 285 |
self.switch.connect('notify::active', self.on_switch)
|
| 251 | 286 |
self.switch.set_hexpand(True)
|
| 252 | 287 |
self.switch.set_halign(Gtk.Align.END)
|
| 253 | 288 |
self.switch.set_valign(Gtk.Align.CENTER)
|
| 254 | 289 |
|
| 255 |
- self.option_box.add(self.switch)
|
|
| 290 |
+ self.setting_box.add(self.switch)
|
|
| 256 | 291 |
|
| 257 | 292 |
self.show_all()
|
| 258 | 293 |
|
| ... | ... | @@ -265,17 +300,17 @@ class SwitchOption(GenericOption): |
| 265 | 300 |
self.set_value(value)
|
| 266 | 301 |
|
| 267 | 302 |
|
| 268 |
-class EntryOption(GenericOption):
|
|
| 303 |
+class EntrySetting(GenericSetting):
|
|
| 269 | 304 |
|
| 270 | 305 |
__gproperties__ = {
|
| 271 |
- "option-value": (str, 'Entry Value', '', '',
|
|
| 306 |
+ "setting-value": (str, 'Entry Value', '', '',
|
|
| 272 | 307 |
GObject.ParamFlags.READWRITE),}
|
| 273 | 308 |
|
| 274 | 309 |
def __init__(self, *args):
|
| 275 |
- GenericOption.__init__(self, *args)
|
|
| 310 |
+ GenericSetting.__init__(self, *args)
|
|
| 276 | 311 |
|
| 277 | 312 |
self.entry = Gtk.Entry()
|
| 278 |
- self.entry.set_text(str(self.option_value))
|
|
| 313 |
+ self.entry.set_text(str(self.setting_value))
|
|
| 279 | 314 |
self.entry.connect('notify::text', self.on_text_change)
|
| 280 | 315 |
self.entry.set_valign(Gtk.Align.CENTER)
|
| 281 | 316 |
self.entry.set_alignment(1)
|
| ... | ... | @@ -284,7 +319,7 @@ class EntryOption(GenericOption): |
| 284 | 319 |
self.entry.set_invisible_char('*')
|
| 285 | 320 |
self.entry.set_visibility(False)
|
| 286 | 321 |
|
| 287 |
- self.option_box.pack_end(self.entry, True, True, 0)
|
|
| 322 |
+ self.setting_box.pack_end(self.entry, True, True, 0)
|
|
| 288 | 323 |
|
| 289 | 324 |
self.show_all()
|
| 290 | 325 |
|
| ... | ... | @@ -296,20 +331,20 @@ class EntryOption(GenericOption): |
| 296 | 331 |
self.entry.grab_focus()
|
| 297 | 332 |
|
| 298 | 333 |
|
| 299 |
-class DialogOption(GenericOption):
|
|
| 334 |
+class DialogSetting(GenericSetting):
|
|
| 300 | 335 |
|
| 301 | 336 |
__gproperties__ = {
|
| 302 |
- "option-value": (str, 'Dummy', '', '',
|
|
| 337 |
+ "setting-value": (str, 'Dummy', '', '',
|
|
| 303 | 338 |
GObject.ParamFlags.READWRITE),}
|
| 304 | 339 |
|
| 305 | 340 |
def __init__(self, *args, dialog):
|
| 306 |
- GenericOption.__init__(self, *args)
|
|
| 341 |
+ GenericSetting.__init__(self, *args)
|
|
| 307 | 342 |
self.dialog = dialog
|
| 308 | 343 |
|
| 309 |
- self.option_value = Gtk.Label()
|
|
| 310 |
- self.option_value.set_text(self.get_option_value())
|
|
| 311 |
- self.option_value.set_halign(Gtk.Align.END)
|
|
| 312 |
- self.option_box.pack_start(self.option_value, True, True, 0)
|
|
| 344 |
+ self.setting_value = Gtk.Label()
|
|
| 345 |
+ self.setting_value.set_text(self.get_setting_value())
|
|
| 346 |
+ self.setting_value.set_halign(Gtk.Align.END)
|
|
| 347 |
+ self.setting_box.pack_start(self.setting_value, True, True, 0)
|
|
| 313 | 348 |
|
| 314 | 349 |
self.show_all()
|
| 315 | 350 |
|
| ... | ... | @@ -319,38 +354,43 @@ class DialogOption(GenericOption): |
| 319 | 354 |
dialog.connect('destroy', self.on_destroy)
|
| 320 | 355 |
|
| 321 | 356 |
def on_destroy(self, *args):
|
| 322 |
- self.option_value.set_text(self.get_option_value())
|
|
| 357 |
+ self.setting_value.set_text(self.get_setting_value())
|
|
| 323 | 358 |
|
| 324 |
- def get_option_value(self):
|
|
| 325 |
- self.option_value.hide()
|
|
| 359 |
+ def get_setting_value(self):
|
|
| 360 |
+ self.setting_value.hide()
|
|
| 326 | 361 |
return ''
|
| 327 | 362 |
|
| 328 | 363 |
def on_row_activated(self):
|
| 329 | 364 |
self.show_dialog(self.get_toplevel())
|
| 330 | 365 |
|
| 331 | 366 |
|
| 332 |
-class SpinOption(GenericOption):
|
|
| 367 |
+class SpinSetting(GenericSetting):
|
|
| 333 | 368 |
|
| 334 | 369 |
__gproperties__ = {
|
| 335 |
- "option-value": (int, 'Priority', '', -128, 127, 0,
|
|
| 370 |
+ "setting-value": (int, 'Priority', '', -128, 127, 0,
|
|
| 336 | 371 |
GObject.ParamFlags.READWRITE),}
|
| 337 | 372 |
|
| 338 | 373 |
def __init__(self, *args, range_):
|
| 339 |
- GenericOption.__init__(self, *args)
|
|
| 374 |
+ GenericSetting.__init__(self, *args)
|
|
| 340 | 375 |
|
| 341 | 376 |
lower, upper = range_
|
| 342 |
- adjustment = Gtk.Adjustment(0, lower, upper, 1, 10, 0)
|
|
| 377 |
+ adjustment = Gtk.Adjustment(value=0,
|
|
| 378 |
+ lower=lower,
|
|
| 379 |
+ upper=upper,
|
|
| 380 |
+ step_increment=1,
|
|
| 381 |
+ page_increment=10,
|
|
| 382 |
+ page_size=0)
|
|
| 343 | 383 |
|
| 344 | 384 |
self.spin = Gtk.SpinButton()
|
| 345 | 385 |
self.spin.set_adjustment(adjustment)
|
| 346 | 386 |
self.spin.set_numeric(True)
|
| 347 | 387 |
self.spin.set_update_policy(Gtk.SpinButtonUpdatePolicy.IF_VALID)
|
| 348 |
- self.spin.set_value(self.option_value)
|
|
| 388 |
+ self.spin.set_value(self.setting_value)
|
|
| 349 | 389 |
self.spin.set_halign(Gtk.Align.END)
|
| 350 | 390 |
self.spin.set_valign(Gtk.Align.CENTER)
|
| 351 | 391 |
self.spin.connect('notify::value', self.on_value_change)
|
| 352 | 392 |
|
| 353 |
- self.option_box.pack_start(self.spin, True, True, 0)
|
|
| 393 |
+ self.setting_box.pack_start(self.spin, True, True, 0)
|
|
| 354 | 394 |
|
| 355 | 395 |
self.show_all()
|
| 356 | 396 |
|
| ... | ... | @@ -362,14 +402,14 @@ class SpinOption(GenericOption): |
| 362 | 402 |
self.set_value(value)
|
| 363 | 403 |
|
| 364 | 404 |
|
| 365 |
-class FileChooserOption(GenericOption):
|
|
| 405 |
+class FileChooserSetting(GenericSetting):
|
|
| 366 | 406 |
|
| 367 | 407 |
__gproperties__ = {
|
| 368 |
- "option-value": (str, 'Certificate Path', '', '',
|
|
| 408 |
+ "setting-value": (str, 'Certificate Path', '', '',
|
|
| 369 | 409 |
GObject.ParamFlags.READWRITE),}
|
| 370 | 410 |
|
| 371 | 411 |
def __init__(self, *args, filefilter):
|
| 372 |
- GenericOption.__init__(self, *args)
|
|
| 412 |
+ GenericSetting.__init__(self, *args)
|
|
| 373 | 413 |
|
| 374 | 414 |
button = Gtk.FileChooserButton(title=self.label,
|
| 375 | 415 |
action=Gtk.FileChooserAction.OPEN)
|
| ... | ... | @@ -393,15 +433,15 @@ class FileChooserOption(GenericOption): |
| 393 | 433 |
filter_.add_pattern('*')
|
| 394 | 434 |
button.add_filter(filter_)
|
| 395 | 435 |
|
| 396 |
- if self.option_value:
|
|
| 397 |
- button.set_filename(self.option_value)
|
|
| 436 |
+ if self.setting_value:
|
|
| 437 |
+ button.set_filename(self.setting_value)
|
|
| 398 | 438 |
button.connect('selection-changed', self.on_select)
|
| 399 | 439 |
|
| 400 | 440 |
clear_button = get_image_button(
|
| 401 | 441 |
'edit-clear-all-symbolic', _('Clear File'))
|
| 402 | 442 |
clear_button.connect('clicked', lambda *args: button.unselect_all())
|
| 403 |
- self.option_box.pack_start(button, True, True, 0)
|
|
| 404 |
- self.option_box.pack_start(clear_button, False, False, 0)
|
|
| 443 |
+ self.setting_box.pack_start(button, True, True, 0)
|
|
| 444 |
+ self.setting_box.pack_start(clear_button, False, False, 0)
|
|
| 405 | 445 |
|
| 406 | 446 |
self.show_all()
|
| 407 | 447 |
|
| ... | ... | @@ -412,14 +452,14 @@ class FileChooserOption(GenericOption): |
| 412 | 452 |
pass
|
| 413 | 453 |
|
| 414 | 454 |
|
| 415 |
-class CallbackOption(GenericOption):
|
|
| 455 |
+class CallbackSetting(GenericSetting):
|
|
| 416 | 456 |
|
| 417 | 457 |
__gproperties__ = {
|
| 418 |
- "option-value": (str, 'Dummy', '', '',
|
|
| 458 |
+ "setting-value": (str, 'Dummy', '', '',
|
|
| 419 | 459 |
GObject.ParamFlags.READWRITE),}
|
| 420 | 460 |
|
| 421 | 461 |
def __init__(self, *args, callback):
|
| 422 |
- GenericOption.__init__(self, *args)
|
|
| 462 |
+ GenericSetting.__init__(self, *args)
|
|
| 423 | 463 |
self.callback = callback
|
| 424 | 464 |
self.show_all()
|
| 425 | 465 |
|
| ... | ... | @@ -427,15 +467,15 @@ class CallbackOption(GenericOption): |
| 427 | 467 |
self.callback()
|
| 428 | 468 |
|
| 429 | 469 |
|
| 430 |
-class ActionOption(GenericOption):
|
|
| 470 |
+class ActionSetting(GenericSetting):
|
|
| 431 | 471 |
|
| 432 | 472 |
__gproperties__ = {
|
| 433 |
- "option-value": (str, 'Dummy', '', '',
|
|
| 473 |
+ "setting-value": (str, 'Dummy', '', '',
|
|
| 434 | 474 |
GObject.ParamFlags.READWRITE),}
|
| 435 | 475 |
|
| 436 | 476 |
def __init__(self, *args, action_args):
|
| 437 |
- GenericOption.__init__(self, *args)
|
|
| 438 |
- self.action = gtkgui_helpers.get_action(self.option_value)
|
|
| 477 |
+ GenericSetting.__init__(self, *args)
|
|
| 478 |
+ self.action = gtkgui_helpers.get_action(self.setting_value)
|
|
| 439 | 479 |
self.variant = GLib.Variant.new_string(action_args)
|
| 440 | 480 |
self.on_enable()
|
| 441 | 481 |
|
| ... | ... | @@ -449,32 +489,65 @@ class ActionOption(GenericOption): |
| 449 | 489 |
self.action.activate(self.variant)
|
| 450 | 490 |
|
| 451 | 491 |
|
| 452 |
-class LoginOption(DialogOption):
|
|
| 492 |
+class LoginSetting(DialogSetting):
|
|
| 453 | 493 |
def __init__(self, *args, **kwargs):
|
| 454 |
- DialogOption.__init__(self, *args, **kwargs)
|
|
| 455 |
- self.option_value.set_selectable(True)
|
|
| 494 |
+ DialogSetting.__init__(self, *args, **kwargs)
|
|
| 495 |
+ self.setting_value.set_selectable(True)
|
|
| 456 | 496 |
|
| 457 |
- def get_option_value(self):
|
|
| 497 |
+ def get_setting_value(self):
|
|
| 458 | 498 |
jid = app.get_jid_from_account(self.account)
|
| 459 | 499 |
return jid
|
| 460 | 500 |
|
| 461 |
- def set_activatable(self, name, value):
|
|
| 462 |
- DialogOption.set_activatable(self, name, value)
|
|
| 501 |
+ def update_activatable(self, name, value):
|
|
| 502 |
+ super().update_activatable(name, value)
|
|
| 463 | 503 |
anonym = app.config.get_per('accounts', self.account, 'anonymous_auth')
|
| 464 |
- self.get_parent().set_activatable(not anonym)
|
|
| 504 |
+ self.set_activatable(not anonym)
|
|
| 505 |
+ |
|
| 506 |
+ |
|
| 507 |
+class ComboSetting(GenericSetting):
|
|
| 508 |
+ |
|
| 509 |
+ __gproperties__ = {
|
|
| 510 |
+ "setting-value": (str, 'Proxy', '', '',
|
|
| 511 |
+ GObject.ParamFlags.READWRITE),}
|
|
| 512 |
+ |
|
| 513 |
+ def __init__(self, *args, combo_items):
|
|
| 514 |
+ GenericSetting.__init__(self, *args)
|
|
| 515 |
+ |
|
| 516 |
+ self.combo = MaxWidthComboBoxText()
|
|
| 517 |
+ self.combo.set_valign(Gtk.Align.CENTER)
|
|
| 518 |
+ text_renderer = self.combo.get_cells()[0]
|
|
| 519 |
+ text_renderer.set_property('ellipsize', Pango.EllipsizeMode.END)
|
|
| 520 |
+ for index, value in enumerate(combo_items):
|
|
| 521 |
+ if isinstance(value, tuple):
|
|
| 522 |
+ value, label = value
|
|
| 523 |
+ self.combo.append(value, _(label))
|
|
| 524 |
+ else:
|
|
| 525 |
+ self.combo.append(value, value)
|
|
| 526 |
+ if value == self.setting_value or index == 0:
|
|
| 527 |
+ self.combo.set_active(index)
|
|
| 528 |
+ |
|
| 529 |
+ self.combo.connect('changed', self.on_value_change)
|
|
| 530 |
+ |
|
| 531 |
+ self.setting_box.pack_start(self.combo, True, True, 0)
|
|
| 532 |
+ self.show_all()
|
|
| 533 |
+ |
|
| 534 |
+ def on_value_change(self, combo):
|
|
| 535 |
+ self.set_value(combo.get_active_id())
|
|
| 465 | 536 |
|
| 466 | 537 |
|
| 467 |
-class ProxyComboOption(GenericOption):
|
|
| 538 |
+class ProxyComboSetting(GenericSetting):
|
|
| 468 | 539 |
|
| 469 | 540 |
__gproperties__ = {
|
| 470 |
- "option-value": (str, 'Proxy', '', '',
|
|
| 541 |
+ "setting-value": (str, 'Proxy', '', '',
|
|
| 471 | 542 |
GObject.ParamFlags.READWRITE),}
|
| 472 | 543 |
|
| 473 | 544 |
def __init__(self, *args):
|
| 474 |
- GenericOption.__init__(self, *args)
|
|
| 545 |
+ GenericSetting.__init__(self, *args)
|
|
| 475 | 546 |
|
| 476 |
- self.combo = Gtk.ComboBoxText()
|
|
| 547 |
+ self.combo = MaxWidthComboBoxText()
|
|
| 477 | 548 |
self.combo.set_valign(Gtk.Align.CENTER)
|
| 549 |
+ text_renderer = self.combo.get_cells()[0]
|
|
| 550 |
+ text_renderer.set_property('ellipsize', Pango.EllipsizeMode.END)
|
|
| 478 | 551 |
|
| 479 | 552 |
self._signal_id = None
|
| 480 | 553 |
self.update_values()
|
| ... | ... | @@ -484,8 +557,8 @@ class ProxyComboOption(GenericOption): |
| 484 | 557 |
button.set_action_name('app.manage-proxies')
|
| 485 | 558 |
button.set_valign(Gtk.Align.CENTER)
|
| 486 | 559 |
|
| 487 |
- self.option_box.pack_start(self.combo, True, True, 0)
|
|
| 488 |
- self.option_box.pack_start(button, False, True, 0)
|
|
| 560 |
+ self.setting_box.pack_start(self.combo, True, True, 0)
|
|
| 561 |
+ self.setting_box.pack_start(button, False, True, 0)
|
|
| 489 | 562 |
self.show_all()
|
| 490 | 563 |
|
| 491 | 564 |
def _block_signal(self, state):
|
| ... | ... | @@ -505,7 +578,7 @@ class ProxyComboOption(GenericOption): |
| 505 | 578 |
self.combo.remove_all()
|
| 506 | 579 |
for index, value in enumerate(proxies):
|
| 507 | 580 |
self.combo.insert_text(-1, value)
|
| 508 |
- if value == self.option_value or index == 0:
|
|
| 581 |
+ if value == self.setting_value or index == 0:
|
|
| 509 | 582 |
self.combo.set_active(index)
|
| 510 | 583 |
self._block_signal(False)
|
| 511 | 584 |
|
| ... | ... | @@ -519,11 +592,11 @@ class ProxyComboOption(GenericOption): |
| 519 | 592 |
pass
|
| 520 | 593 |
|
| 521 | 594 |
|
| 522 |
-class PriorityOption(DialogOption):
|
|
| 595 |
+class PrioritySetting(DialogSetting):
|
|
| 523 | 596 |
def __init__(self, *args, **kwargs):
|
| 524 |
- DialogOption.__init__(self, *args, **kwargs)
|
|
| 597 |
+ DialogSetting.__init__(self, *args, **kwargs)
|
|
| 525 | 598 |
|
| 526 |
- def get_option_value(self):
|
|
| 599 |
+ def get_setting_value(self):
|
|
| 527 | 600 |
adjust = app.config.get_per(
|
| 528 | 601 |
'accounts', self.account, 'adjust_priority_with_status')
|
| 529 | 602 |
if adjust:
|
| ... | ... | @@ -533,18 +606,18 @@ class PriorityOption(DialogOption): |
| 533 | 606 |
return str(priority)
|
| 534 | 607 |
|
| 535 | 608 |
|
| 536 |
-class CutstomHostnameOption(DialogOption):
|
|
| 609 |
+class CutstomHostnameSetting(DialogSetting):
|
|
| 537 | 610 |
def __init__(self, *args, **kwargs):
|
| 538 |
- DialogOption.__init__(self, *args, **kwargs)
|
|
| 611 |
+ DialogSetting.__init__(self, *args, **kwargs)
|
|
| 539 | 612 |
|
| 540 |
- def get_option_value(self):
|
|
| 613 |
+ def get_setting_value(self):
|
|
| 541 | 614 |
custom = app.config.get_per('accounts', self.account, 'use_custom_host')
|
| 542 | 615 |
return _('On') if custom else _('Off')
|
| 543 | 616 |
|
| 544 | 617 |
|
| 545 |
-class ChangePasswordOption(DialogOption):
|
|
| 618 |
+class ChangePasswordSetting(DialogSetting):
|
|
| 546 | 619 |
def __init__(self, *args, **kwargs):
|
| 547 |
- DialogOption.__init__(self, *args, **kwargs)
|
|
| 620 |
+ DialogSetting.__init__(self, *args, **kwargs)
|
|
| 548 | 621 |
|
| 549 | 622 |
def show_dialog(self, parent):
|
| 550 | 623 |
try:
|
| ... | ... | @@ -557,9 +630,9 @@ class ChangePasswordOption(DialogOption): |
| 557 | 630 |
def on_changed(self, new_password):
|
| 558 | 631 |
self.set_value(new_password)
|
| 559 | 632 |
|
| 560 |
- def set_activatable(self, name, value):
|
|
| 633 |
+ def update_activatable(self, name, value):
|
|
| 561 | 634 |
activatable = False
|
| 562 | 635 |
if self.account in app.connections:
|
| 563 | 636 |
con = app.connections[self.account]
|
| 564 | 637 |
activatable = con.connected >= 2 and con.register_supported
|
| 565 |
- self.get_parent().set_activatable(activatable)
|
|
| 638 |
+ self.set_activatable(activatable)
|
| ... | ... | @@ -623,3 +623,21 @@ class MultiLineLabel(Gtk.Label): |
| 623 | 623 |
self.set_line_wrap(True)
|
| 624 | 624 |
self.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
|
| 625 | 625 |
self.set_single_line_mode(False)
|
| 626 |
+ |
|
| 627 |
+ |
|
| 628 |
+class MaxWidthComboBoxText(Gtk.ComboBoxText):
|
|
| 629 |
+ def __init__(self, *args, **kwargs):
|
|
| 630 |
+ Gtk.ComboBoxText.__init__(self, *args, **kwargs)
|
|
| 631 |
+ self._max_width = 100
|
|
| 632 |
+ |
|
| 633 |
+ def set_max_size(self, size):
|
|
| 634 |
+ self._max_width = size
|
|
| 635 |
+ |
|
| 636 |
+ def do_get_preferred_width(self):
|
|
| 637 |
+ minimum_width, natural_width = Gtk.ComboBoxText.do_get_preferred_width(self)
|
|
| 638 |
+ |
|
| 639 |
+ if natural_width > self._max_width:
|
|
| 640 |
+ natural_width = self._max_width
|
|
| 641 |
+ if minimum_width > self._max_width:
|
|
| 642 |
+ minimum_width = self._max_width
|
|
| 643 |
+ return minimum_width, natural_width
|
| ... | ... | @@ -22,17 +22,16 @@ from gi.repository import GLib |
| 22 | 22 |
from gajim.common import app
|
| 23 | 23 |
from gajim.common import ged
|
| 24 | 24 |
from gajim.common.i18n import _
|
| 25 |
-from gajim.common.const import Option
|
|
| 26 |
-from gajim.common.const import OptionKind
|
|
| 27 |
-from gajim.common.const import OptionType
|
|
| 28 | 25 |
from gajim.common.const import StyleAttr
|
| 29 | 26 |
|
| 30 | 27 |
from gajim.gtk import util
|
| 31 | 28 |
from gajim.gtk.util import get_builder
|
| 32 | 29 |
from gajim.gtk.util import get_image_button
|
| 33 | 30 |
from gajim.gtk.dialogs import ErrorDialog
|
| 34 |
- |
|
| 35 |
-from gajim.options_dialog import OptionsDialog
|
|
| 31 |
+from gajim.gtk.settings import SettingsDialog
|
|
| 32 |
+from gajim.gtk.const import Setting
|
|
| 33 |
+from gajim.gtk.const import SettingKind
|
|
| 34 |
+from gajim.gtk.const import SettingType
|
|
| 36 | 35 |
|
| 37 | 36 |
|
| 38 | 37 |
UNDECLARED = 'http://www.gajim.org/xmlns/undeclared'
|
| ... | ... | @@ -191,31 +190,31 @@ class XMLConsoleWindow(Gtk.Window): |
| 191 | 190 |
self.filter_dialog.present()
|
| 192 | 191 |
return
|
| 193 | 192 |
options = [
|
| 194 |
- Option(OptionKind.SWITCH, 'Presence',
|
|
| 195 |
- OptionType.VALUE, self.presence,
|
|
| 196 |
- callback=self.on_option, data='presence'),
|
|
| 193 |
+ Setting(SettingKind.SWITCH, 'Presence',
|
|
| 194 |
+ SettingType.VALUE, self.presence,
|
|
| 195 |
+ callback=self.on_option, data='presence'),
|
|
| 197 | 196 |
|
| 198 |
- Option(OptionKind.SWITCH, 'Message',
|
|
| 199 |
- OptionType.VALUE, self.message,
|
|
| 200 |
- callback=self.on_option, data='message'),
|
|
| 197 |
+ Setting(SettingKind.SWITCH, 'Message',
|
|
| 198 |
+ SettingType.VALUE, self.message,
|
|
| 199 |
+ callback=self.on_option, data='message'),
|
|
| 201 | 200 |
|
| 202 |
- Option(OptionKind.SWITCH, 'Iq', OptionType.VALUE, self.iq,
|
|
| 203 |
- callback=self.on_option, data='iq'),
|
|
| 201 |
+ Setting(SettingKind.SWITCH, 'Iq', SettingType.VALUE, self.iq,
|
|
| 202 |
+ callback=self.on_option, data='iq'),
|
|
| 204 | 203 |
|
| 205 |
- Option(OptionKind.SWITCH, 'Stream\nManagement',
|
|
| 206 |
- OptionType.VALUE, self.stream,
|
|
| 207 |
- callback=self.on_option, data='stream'),
|
|
| 204 |
+ Setting(SettingKind.SWITCH, 'Stream\nManagement',
|
|
| 205 |
+ SettingType.VALUE, self.stream,
|
|
| 206 |
+ callback=self.on_option, data='stream'),
|
|
| 208 | 207 |
|
| 209 |
- Option(OptionKind.SWITCH, 'In', OptionType.VALUE, self.incoming,
|
|
| 210 |
- callback=self.on_option, data='incoming'),
|
|
| 208 |
+ Setting(SettingKind.SWITCH, 'In', SettingType.VALUE, self.incoming,
|
|
| 209 |
+ callback=self.on_option, data='incoming'),
|
|
| 211 | 210 |
|
| 212 |
- Option(OptionKind.SWITCH, 'Out', OptionType.VALUE, self.outgoing,
|
|
| 213 |
- callback=self.on_option, data='outgoing'),
|
|
| 211 |
+ Setting(SettingKind.SWITCH, 'Out', SettingType.VALUE, self.outgoing,
|
|
| 212 |
+ callback=self.on_option, data='outgoing'),
|
|
| 214 | 213 |
]
|
| 215 | 214 |
|
| 216 |
- self.filter_dialog = OptionsDialog(self, 'Filter',
|
|
| 217 |
- Gtk.DialogFlags.DESTROY_WITH_PARENT,
|
|
| 218 |
- options, self.account)
|
|
| 215 |
+ self.filter_dialog = SettingsDialog(self, 'Filter',
|
|
| 216 |
+ Gtk.DialogFlags.DESTROY_WITH_PARENT,
|
|
| 217 |
+ options, self.account)
|
|
| 219 | 218 |
self.filter_dialog.connect('destroy', self.on_filter_destroyed)
|
| 220 | 219 |
|
| 221 | 220 |
def on_filter_destroyed(self, win):
|