4 ## Copyright (C) 2005 Travis Shirk <travis AT pobox.com>
5 ## Vincent Hanquez <tab AT snarc.org>
6 ## Copyright (C) 2005-2010 Yann Leboulanger <asterix AT lagaule.org>
7 ## Copyright (C) 2005-2007 Nikos Kouremenos <kourem AT gmail.com>
8 ## Copyright (C) 2006 Dimitur Kirov <dkirov AT gmail.com>
9 ## Copyright (C) 2006-2007 Jean-Marie Traissard <jim AT lapin.org>
11 ## This file is part of Gajim.
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.
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.
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/>.
30 from common
import gajim
43 GTKGUI_GLADE
= 'manage_accounts_window.ui'
47 Call func at most *rate* times per second
51 def f(*args
, **kwargs
):
52 if timeout
[0] is not None:
53 gobject
.source_remove(timeout
[0])
58 timeout
[0] = gobject
.timeout_add(int(1000.0 / rate
), timeout_func
)
62 def tree_model_iter_children(model
, treeiter
):
63 it
= model
.iter_children(treeiter
)
66 it
= model
.iter_next(it
)
68 def tree_model_pre_order(model
, treeiter
):
70 for childiter
in tree_model_iter_children(model
, treeiter
):
71 for it
in tree_model_pre_order(model
, childiter
):
75 class AdvancedConfigurationWindow(object):
77 self
.xml
= gtkgui_helpers
.get_gtk_builder('advanced_configuration_window.ui')
78 self
.window
= self
.xml
.get_object('advanced_configuration_window')
79 self
.window
.set_transient_for(
80 gajim
.interface
.instances
['preferences'].window
)
81 self
.entry
= self
.xml
.get_object('advanced_entry')
82 self
.desc_label
= self
.xml
.get_object('advanced_desc_label')
83 self
.restart_label
= self
.xml
.get_object('restart_label')
86 # key = option name (root/subopt/opt separated by \n then)
87 # value = array(oldval, newval)
88 self
.changed_opts
= {}
91 self
.right_true_dict
= {True: _('Activated'), False: _('Deactivated')}
93 'boolean': _('Boolean'),
94 'integer': _('Integer'),
98 treeview
= self
.xml
.get_object('advanced_treeview')
99 self
.treeview
= treeview
100 self
.model
= gtk
.TreeStore(str, str, str)
102 self
.model
.set_sort_column_id(0, gtk
.SORT_ASCENDING
)
103 self
.modelfilter
= self
.model
.filter_new()
104 self
.modelfilter
.set_visible_func(self
.visible_func
)
106 renderer_text
= gtk
.CellRendererText()
107 col
= treeview
.insert_column_with_attributes(-1, _('Preference Name'),
108 renderer_text
, text
= 0)
109 col
.set_resizable(True)
111 renderer_text
= gtk
.CellRendererText()
112 renderer_text
.connect('edited', self
.on_config_edited
)
113 col
= treeview
.insert_column_with_attributes(-1, _('Value'),
114 renderer_text
, text
= 1)
115 col
.set_cell_data_func(renderer_text
, self
.cb_value_column_data
)
117 col
.props
.resizable
= True
118 col
.set_max_width(250)
120 renderer_text
= gtk
.CellRendererText()
121 treeview
.insert_column_with_attributes(-1, _('Type'),
122 renderer_text
, text
= 2)
124 treeview
.set_model(self
.modelfilter
)
126 # connect signal for selection change
127 treeview
.get_selection().connect('changed',
128 self
.on_advanced_treeview_selection_changed
)
130 self
.xml
.connect_signals(self
)
131 self
.window
.show_all()
132 self
.restart_label
.hide()
133 gajim
.interface
.instances
['advanced_config'] = self
135 def cb_value_column_data(self
, col
, cell
, model
, iter_
):
137 Check if it's boolen or holds password stuff and if yes make the
138 cellrenderertext not editable, else - it's editable
140 optname
= model
[iter_
][C_PREFNAME
]
141 opttype
= model
[iter_
][C_TYPE
]
142 if opttype
== self
.types
['boolean'] or optname
== 'password':
143 cell
.set_property('editable', False)
145 cell
.set_property('editable', True)
147 def get_option_path(self
, model
, iter_
):
148 # It looks like path made from reversed array
149 # path[0] is the true one optname
150 # path[1] is the key name
151 # path[2] is the root of tree
152 # last two is optional
153 path
= [model
[iter_
][0].decode('utf-8')]
154 parent
= model
.iter_parent(iter_
)
156 path
.append(model
[parent
][0].decode('utf-8'))
157 parent
= model
.iter_parent(parent
)
160 def on_advanced_treeview_selection_changed(self
, treeselection
):
161 model
, iter_
= treeselection
.get_selected()
162 # Check for GtkTreeIter
164 opt_path
= self
.get_option_path(model
, iter_
)
165 # Get text from first column in this row
167 if len(opt_path
) == 3:
168 desc
= gajim
.config
.get_desc_per(opt_path
[2], opt_path
[1],
170 elif len(opt_path
) == 1:
171 desc
= gajim
.config
.get_desc(opt_path
[0])
173 self
.desc_label
.set_text(desc
)
175 #we talk about option description in advanced configuration editor
176 self
.desc_label
.set_text(_('(None)'))
178 def remember_option(self
, option
, oldval
, newval
):
179 if option
in self
.changed_opts
:
180 self
.changed_opts
[option
] = (self
.changed_opts
[option
][0], newval
)
182 self
.changed_opts
[option
] = (oldval
, newval
)
184 def on_advanced_treeview_row_activated(self
, treeview
, path
, column
):
185 modelpath
= self
.modelfilter
.convert_path_to_child_path(path
)
186 modelrow
= self
.model
[modelpath
]
187 option
= modelrow
[0].decode('utf-8')
188 if modelrow
[2] == self
.types
['boolean']:
189 for key
in self
.right_true_dict
.keys():
190 if self
.right_true_dict
[key
] == modelrow
[1]:
192 newval
= {'False': True, 'True': False}[modelrow
[1]]
193 if len(modelpath
) > 1:
194 optnamerow
= self
.model
[modelpath
[0]]
195 optname
= optnamerow
[0].decode('utf-8')
196 keyrow
= self
.model
[modelpath
[:2]]
197 key
= keyrow
[0].decode('utf-8')
198 gajim
.config
.get_desc_per(optname
, key
, option
)
199 self
.remember_option(option
+ '\n' + key
+ '\n' + optname
,
201 gajim
.config
.set_per(optname
, key
, option
, newval
)
203 self
.remember_option(option
, modelrow
[1], newval
)
204 gajim
.config
.set(option
, newval
)
205 gajim
.interface
.save_config()
206 modelrow
[1] = self
.right_true_dict
[newval
]
207 self
.check_for_restart()
209 def check_for_restart(self
):
210 self
.restart_label
.hide()
211 for opt
in self
.changed_opts
:
212 opt_path
= opt
.split('\n')
214 restart
= gajim
.config
.get_restart_per(opt_path
[2], opt_path
[1],
217 restart
= gajim
.config
.get_restart(opt_path
[0])
219 if self
.changed_opts
[opt
][0] != self
.changed_opts
[opt
][1]:
220 self
.restart_label
.show()
223 def on_config_edited(self
, cell
, path
, text
):
224 # convert modelfilter path to model path
225 modelpath
= self
.modelfilter
.convert_path_to_child_path(path
)
226 modelrow
= self
.model
[modelpath
]
227 option
= modelrow
[0].decode('utf-8')
228 text
= text
.decode('utf-8')
229 if len(modelpath
) > 1:
230 optnamerow
= self
.model
[modelpath
[0]]
231 optname
= optnamerow
[0].decode('utf-8')
232 keyrow
= self
.model
[modelpath
[:2]]
233 key
= keyrow
[0].decode('utf-8')
234 self
.remember_option(option
+ '\n' + key
+ '\n' + optname
, modelrow
[1],
236 gajim
.config
.set_per(optname
, key
, option
, text
)
238 self
.remember_option(option
, modelrow
[1], text
)
239 gajim
.config
.set(option
, text
)
240 gajim
.interface
.save_config()
242 self
.check_for_restart()
244 def on_advanced_configuration_window_destroy(self
, widget
):
245 del gajim
.interface
.instances
['advanced_config']
247 def on_advanced_close_button_clicked(self
, widget
):
248 self
.window
.destroy()
250 def fill_model(self
, node
=None, parent
=None):
251 for item
, option
in gajim
.config
.get_children(node
):
253 if option
is None: # Node
254 newparent
= self
.model
.append(parent
, [name
, '', ''])
255 self
.fill_model(item
, newparent
)
257 type_
= self
.types
[option
[OPT_TYPE
][0]]
258 if name
== 'password':
261 if type_
== self
.types
['boolean']:
262 value
= self
.right_true_dict
[option
[OPT_VAL
]]
264 value
= option
[OPT_VAL
]
265 self
.model
.append(parent
, [name
, value
, type_
])
267 def visible_func(self
, model
, treeiter
):
268 search_string
= self
.entry
.get_text().decode('utf-8').lower()
269 for it
in tree_model_pre_order(model
, treeiter
):
270 if model
[it
][C_TYPE
] != '':
271 opt_path
= self
.get_option_path(model
, it
)
272 if len(opt_path
) == 3:
273 desc
= gajim
.config
.get_desc_per(opt_path
[2], opt_path
[1],
275 elif len(opt_path
) == 1:
276 desc
= gajim
.config
.get_desc(opt_path
[0])
277 if search_string
in model
[it
][C_PREFNAME
] or (desc
and \
278 search_string
in desc
.lower()):
283 def on_advanced_entry_changed(self
, widget
):
284 self
.modelfilter
.refilter()
285 if not widget
.get_text():
286 # Maybe the expanded rows should be remembered here ...
287 self
.treeview
.collapse_all()
289 # ... and be restored correctly here
290 self
.treeview
.expand_all()