diff --git a/data/gui/advanced_configuration_window.ui b/data/gui/advanced_configuration_window.ui index db5b1e9cb968514024806d4ca7b4495b6c00397f..52df66599d40ac2a0eaa0b25b1cfa313c001391b 100644 --- a/data/gui/advanced_configuration_window.ui +++ b/data/gui/advanced_configuration_window.ui @@ -1,24 +1,25 @@ -<?xml version="1.0"?> +<?xml version="1.0" encoding="UTF-8"?> <interface> <requires lib="gtk+" version="2.16"/> - <!-- interface-naming-policy toplevel-contextual --> <object class="GtkWindow" id="advanced_configuration_window"> + <property name="can_focus">False</property> <property name="border_width">6</property> <property name="title" translatable="yes">Advanced Configuration Editor</property> <property name="role">ace</property> <property name="default_width">650</property> <property name="default_height">540</property> <property name="type_hint">dialog</property> - <signal name="destroy" handler="on_advanced_configuration_window_destroy"/> + <signal name="destroy" handler="on_advanced_configuration_window_destroy" swapped="no"/> <child> <object class="GtkVBox" id="vbox70"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">6</property> - <property name="orientation">vertical</property> <property name="spacing">6</property> <child> <object class="GtkTable" id="table26"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="n_rows">2</property> <property name="n_columns">2</property> <property name="column_spacing">12</property> @@ -26,6 +27,7 @@ <child> <object class="GtkLabel" id="label248"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">Filter:</property> </object> @@ -38,7 +40,7 @@ <object class="GtkEntry" id="advanced_entry"> <property name="visible">True</property> <property name="can_focus">True</property> - <signal name="changed" handler="on_advanced_entry_changed"/> + <signal name="changed" handler="on_advanced_entry_changed" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -51,14 +53,16 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="hscrollbar_policy">never</property> - <property name="vscrollbar_policy">automatic</property> <property name="shadow_type">in</property> <child> <object class="GtkTreeView" id="advanced_treeview"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="rules_hint">True</property> - <signal name="row_activated" handler="on_advanced_treeview_row_activated"/> + <signal name="row-activated" handler="on_advanced_treeview_row_activated" swapped="no"/> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection1"/> + </child> </object> </child> </object> @@ -71,23 +75,28 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkFrame" id="frame36"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">3</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment90"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">6</property> <property name="left_padding">12</property> <child> <object class="GtkLabel" id="advanced_desc_label"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="wrap">True</property> </object> @@ -97,6 +106,7 @@ <child type="label"> <object class="GtkLabel" id="label357"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes"><b>Description</b></property> <property name="use_markup">True</property> </object> @@ -104,11 +114,13 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkLabel" id="restart_label"> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes"><b>NOTE:</b> You should restart Gajim for some settings to take effect</property> <property name="use_markup">True</property> @@ -123,27 +135,50 @@ <child> <object class="GtkHButtonBox" id="hbuttonbox18"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="reset_button"> + <property name="label" translatable="yes">_Reset to default</property> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="image">image1</property> + <property name="use_underline">True</property> + <signal name="clicked" handler="on_reset_button_clicked" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> <child> <object class="GtkButton" id="advanced_close_button"> <property name="label">gtk-close</property> + <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="can_default">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_stock">True</property> - <signal name="clicked" handler="on_advanced_close_button_clicked"/> + <signal name="clicked" handler="on_advanced_close_button_clicked" swapped="no"/> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">0</property> + <property name="position">1</property> </packing> </child> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">3</property> </packing> @@ -151,4 +186,9 @@ </object> </child> </object> + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-undo</property> + </object> </interface> diff --git a/plugins/dbus_plugin/plugin.py b/plugins/dbus_plugin/plugin.py index 3a583a7cfab66f7afdcd9e41e0d76a71b8244f7d..95d3b17602061d04be9799a999938e756a166060 100644 --- a/plugins/dbus_plugin/plugin.py +++ b/plugins/dbus_plugin/plugin.py @@ -501,7 +501,7 @@ if dbus_support.supported: for node in path: key += node + '#' key += name - prefs_dict[DBUS_STRING(key)] = DBUS_STRING(value[1]) + prefs_dict[DBUS_STRING(key)] = DBUS_STRING(value) gajim.config.foreach(get_prefs) return prefs_dict diff --git a/src/advanced_configuration_window.py b/src/advanced_configuration_window.py index ab43f82b0ab56924c77200e2d2a1028638eb6c08..5481d2aaa05e0251ba6ae6d02a81b5e545980e56 100644 --- a/src/advanced_configuration_window.py +++ b/src/advanced_configuration_window.py @@ -81,6 +81,7 @@ class AdvancedConfigurationWindow(object): self.entry = self.xml.get_object('advanced_entry') self.desc_label = self.xml.get_object('advanced_desc_label') self.restart_label = self.xml.get_object('restart_label') + self.reset_button = self.xml.get_object('reset_button') # Format: # key = option name (root/subopt/opt separated by \n then) @@ -174,6 +175,13 @@ class AdvancedConfigurationWindow(object): else: #we talk about option description in advanced configuration editor self.desc_label.set_text(_('(None)')) + if len(opt_path) == 3 or (len(opt_path) == 1 and not \ + model.iter_has_child(iter_)): + self.reset_button.set_sensitive(True) + else: + self.reset_button.set_sensitive(False) + else: + self.reset_button.set_sensitive(False) def remember_option(self, option, oldval, newval): if option in self.changed_opts: @@ -195,7 +203,6 @@ class AdvancedConfigurationWindow(object): optname = optnamerow[0].decode('utf-8') keyrow = self.model[modelpath[:2]] key = keyrow[0].decode('utf-8') - gajim.config.get_desc_per(optname, key, option) self.remember_option(option + '\n' + key + '\n' + optname, modelrow[1], newval) gajim.config.set_per(optname, key, option, newval) @@ -244,6 +251,42 @@ class AdvancedConfigurationWindow(object): def on_advanced_configuration_window_destroy(self, widget): del gajim.interface.instances['advanced_config'] + def on_reset_button_clicked(self, widget): + model, iter_ = self.treeview.get_selection().get_selected() + # Check for GtkTreeIter + if iter_: + path = model.get_path(iter_) + opt_path = self.get_option_path(model, iter_) + if len(opt_path) == 1: + default = gajim.config.get_default(opt_path[0]) + elif len(opt_path) == 3: + default = gajim.config.get_default_per(opt_path[2], opt_path[0]) + + if model[iter_][C_TYPE] == self.types['boolean']: + if self.right_true_dict[default] == model[iter_][C_VALUE]: + return + modelpath = self.modelfilter.convert_path_to_child_path(path) + modelrow = self.model[modelpath] + option = modelrow[0].decode('utf-8') + if len(modelpath) > 1: + optnamerow = self.model[modelpath[0]] + optname = optnamerow[0].decode('utf-8') + keyrow = self.model[modelpath[:2]] + key = keyrow[0].decode('utf-8') + self.remember_option(option + '\n' + key + '\n' + optname, + modelrow[C_VALUE], default) + gajim.config.set_per(optname, key, option, default) + else: + self.remember_option(option, modelrow[C_VALUE], default) + gajim.config.set(option, default) + gajim.interface.save_config() + modelrow[C_VALUE] = self.right_true_dict[default] + self.check_for_restart() + else: + if str(default) == model[iter_][C_VALUE]: + return + self.on_config_edited(None, path, str(default)) + def on_advanced_close_button_clicked(self, widget): self.window.destroy() @@ -254,14 +297,18 @@ class AdvancedConfigurationWindow(object): newparent = self.model.append(parent, [name, '', '']) self.fill_model(item, newparent) else: # Leaf - type_ = self.types[option[OPT_TYPE][0]] + if len(item) == 1: + type_ = self.types[gajim.config.get_type(name)] + elif len(item) == 3: + type_ = self.types[gajim.config.get_type_per(item[0], + item[2])] if name == 'password': value = _('Hidden') else: if type_ == self.types['boolean']: - value = self.right_true_dict[option[OPT_VAL]] + value = self.right_true_dict[option] else: - value = option[OPT_VAL] + value = option self.model.append(parent, [name, value, type_]) def visible_func(self, model, treeiter): diff --git a/src/common/config.py b/src/common/config.py index 75d10e89b27ca06c6110bdef5cf1cd00c31b2231..35078e3af3961fef26b92ce69cd1b02d3b1c7211 100644 --- a/src/common/config.py +++ b/src/common/config.py @@ -65,7 +65,7 @@ class Config: DEFAULT_MAILAPP = 'mozilla-thunderbird -compose' DEFAULT_FILE_MANAGER = 'xffm' - __options = { + __options = ({ # name: [ type, default_value, help_string ] 'verbose': [ opt_bool, False, '', True ], 'autopopup': [ opt_bool, False ], @@ -301,7 +301,7 @@ class Config: 'show_affiliation_in_groupchat': [opt_bool, True, _('If True, Gajim will show affiliation of groupchat occupants by adding a colored square to the status icon')], 'global_proxy': [opt_str, '', _('Proxy used for all outgoing connections if the account does not have a specific proxy configured')], 'ignore_incoming_attention': [opt_bool, False, _('If True, Gajim will ignore incoming attention requestd ("wizz").')], - } + }, {}) __options_per_key = { 'accounts': ({ @@ -537,9 +537,9 @@ class Config: _('Tor'): ['socks5', 'localhost', 9050], } - def foreach(self, cb, data = None): - for opt in self.__options: - cb(data, opt, None, self.__options[opt]) + def foreach(self, cb, data=None): + for opt in self.__options[1]: + cb(data, opt, None, self.__options[1][opt]) for opt in self.__options_per_key: cb(data, opt, None, None) dict_ = self.__options_per_key[opt][1] @@ -553,7 +553,7 @@ class Config: Tree-like interface """ if node is None: - for child, option in self.__options.iteritems(): + for child, option in self.__options[1].iteritems(): yield (child, ), option for grandparent in self.__options_per_key: yield (grandparent, ), None @@ -609,35 +609,44 @@ class Config: return None def set(self, optname, value): - if optname not in self.__options: + if optname not in self.__options[1]: # raise RuntimeError, 'option %s does not exist' % optname return - opt = self.__options[optname] - value = self.is_valid(opt[OPT_TYPE], value) + value = self.is_valid(self.__options[0][optname][OPT_TYPE], value) if value is None: # raise RuntimeError, 'value of %s cannot be None' % optname return - opt[OPT_VAL] = value + self.__options[1][optname] = value - def get(self, optname = None): + def get(self, optname=None): if not optname: - return self.__options.keys() - if optname not in self.__options: + return self.__options[1].keys() + if optname not in self.__options[1]: + return None + return self.__options[1][optname] + + def get_default(self, optname): + if optname not in self.__options[0]: + return None + return self.__options[0][optname][OPT_VAL] + + def get_type(self, optname): + if optname not in self.__options[0]: return None - return self.__options[optname][OPT_VAL] + return self.__options[0][optname][OPT_TYPE][0] def get_desc(self, optname): - if optname not in self.__options: + if optname not in self.__options[0]: return None - if len(self.__options[optname]) > OPT_DESC: - return self.__options[optname][OPT_DESC] + if len(self.__options[0][optname]) > OPT_DESC: + return self.__options[0][optname][OPT_DESC] def get_restart(self, optname): - if optname not in self.__options: + if optname not in self.__options[0]: return None - if len(self.__options[optname]) > OPT_RESTART: - return self.__options[optname][OPT_RESTART] + if len(self.__options[0][optname]) > OPT_RESTART: + return self.__options[0][optname][OPT_RESTART] def add_per(self, typename, name): # per_group_of_option if typename not in self.__options_per_key: @@ -648,7 +657,9 @@ class Config: if name in opt[1]: # we already have added group name before return 'you already have added %s before' % name - opt[1][name] = copy.deepcopy(opt[0]) + opt[1][name] = {} + for o in opt[0]: + opt[1][name][o] = opt[0][o][OPT_VAL] def del_per(self, typename, name, subname = None): # per_group_of_option if typename not in self.__options_per_key: @@ -676,36 +687,50 @@ class Config: if subname not in obj: # raise RuntimeError, '%s is not a key of %s' % (subname, obj) return - subobj = obj[subname] - value = self.is_valid(subobj[OPT_TYPE], value) + typ = self.__options_per_key[optname][0][subname][OPT_TYPE] + value = self.is_valid(typ, value) if value is None: # raise RuntimeError, '%s of %s cannot be None' % optname return - subobj[OPT_VAL] = value + obj[subname] = value - def get_per(self, optname, key = None, subname = None): # per_group_of_option + def get_per(self, optname, key=None, subname=None): # per_group_of_option if optname not in self.__options_per_key: return None dict_ = self.__options_per_key[optname][1] if not key: return dict_.keys() if key not in dict_: - if optname in self.__options_per_key \ - and subname in self.__options_per_key[optname][0]: - return self.__options_per_key \ - [optname][0][subname][1] + if subname in self.__options_per_key[optname][0]: + return self.__options_per_key[optname][0][subname][1] return None obj = dict_[key] if not subname: return obj if subname not in obj: return None - return obj[subname][OPT_VAL] + return obj[subname] - def get_desc_per(self, optname, key = None, subname = None): + def get_default_per(self, optname, subname): if optname not in self.__options_per_key: return None - dict_ = self.__options_per_key[optname][1] + dict_ = self.__options_per_key[optname][0] + if subname not in dict_: + return None + return dict_[subname][OPT_VAL] + + def get_type_per(self, optname, subname): + if optname not in self.__options_per_key: + return None + dict_ = self.__options_per_key[optname][0] + if subname not in dict_: + return None + return dict_[subname][OPT_TYPE][0] + + def get_desc_per(self, optname, key=None, subname=None): + if optname not in self.__options_per_key: + return None + dict_ = self.__options_per_key[optname][0] if not key: return None if key not in dict_: @@ -719,10 +744,10 @@ class Config: return obj[subname][OPT_DESC] return None - def get_restart_per(self, optname, key = None, subname = None): + def get_restart_per(self, optname, key=None, subname=None): if optname not in self.__options_per_key: return False - dict_ = self.__options_per_key[optname][1] + dict_ = self.__options_per_key[optname][0] if not key: return False if key not in dict_: @@ -749,8 +774,13 @@ class Config: return (account not in no_log_for) and (jid not in no_log_for) + def _init_options(self): + for opt in self.__options[0]: + self.__options[1][opt] = self.__options[0][opt][OPT_VAL] + def __init__(self): #init default values + self._init_options() for event in self.soundevents_default: default = self.soundevents_default[event] self.add_per('soundevents', event) diff --git a/src/common/optparser.py b/src/common/optparser.py index f84b18a002782e97b139bd5901b393ed0649a3f4..fa270d748a861e29c7b6d93d9ecaa865782d8ec2 100644 --- a/src/common/optparser.py +++ b/src/common/optparser.py @@ -85,7 +85,6 @@ class OptionsParser: def write_line(self, fd, opt, parents, value): if value is None: return - value = value[1] # convert to utf8 before writing to file if needed if isinstance(value, unicode): value = value.encode('utf-8') diff --git a/src/remote_control.py b/src/remote_control.py index c9816693ee082578b6f1c1d3fd49cdbd84bd6091..25160eb4f8c9417a67e29370f528cce32bcf8abd 100644 --- a/src/remote_control.py +++ b/src/remote_control.py @@ -723,7 +723,7 @@ class SignalObject(dbus.service.Object): for node in path: key += node + '#' key += name - prefs_dict[DBUS_STRING(key)] = DBUS_STRING(value[1]) + prefs_dict[DBUS_STRING(key)] = DBUS_STRING(value) gajim.config.foreach(get_prefs) return prefs_dict