root/branches/gajim_0.11/src/gajim_themes_window.py

Revision 7646, 13.4 kB (checked in by asterix, 2 years ago)

select active theme when we re-open gajim theme window. fixes #2778

  • Property svn:eol-style set to LF
Line 
1##      gajim_themes_window.py
2##
3## Contributors for this file:
4##      - Yann Le Boulanger <asterix@lagaule.org>
5##      - Nikos Kouremenos <kourem@gmail.com>
6##      - Dimitur Kirov <dkirov@gmail.com>
7##
8## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
9##                         Vincent Hanquez <tab@snarc.org>
10## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
11##                    Vincent Hanquez <tab@snarc.org>
12##                    Nikos Kouremenos <kourem@gmail.com>
13##                    Dimitur Kirov <dkirov@gmail.com>
14##                    Travis Shirk <travis@pobox.com>
15##                    Norman Rasmussen <norman@rasmussen.co.za>
16##
17## This program is free software; you can redistribute it and/or modify
18## it under the terms of the GNU General Public License as published
19## by the Free Software Foundation; version 2 only.
20##
21## This program is distributed in the hope that it will be useful,
22## but WITHOUT ANY WARRANTY; without even the implied warranty of
23## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24## GNU General Public License for more details.
25##
26
27import gtk
28import pango
29import dialogs
30import gtkgui_helpers
31
32from common import gajim
33
34class GajimThemesWindow:
35
36        def __init__(self):
37                self.xml = gtkgui_helpers.get_glade('gajim_themes_window.glade')
38                self.window = self.xml.get_widget('gajim_themes_window')
39                self.window.set_transient_for(gajim.interface.roster.window)
40               
41                self.options = ['account', 'group', 'contact', 'banner']
42                self.options_combobox = self.xml.get_widget('options_combobox')
43                self.textcolor_checkbutton = self.xml.get_widget('textcolor_checkbutton')
44                self.background_checkbutton = self.xml.get_widget('background_checkbutton')
45                self.textfont_checkbutton = self.xml.get_widget('textfont_checkbutton')
46                self.text_colorbutton = self.xml.get_widget('text_colorbutton')
47                self.background_colorbutton = self.xml.get_widget('background_colorbutton')
48                self.text_fontbutton = self.xml.get_widget('text_fontbutton')
49                self.bold_togglebutton = self.xml.get_widget('bold_togglebutton')
50                self.italic_togglebutton = self.xml.get_widget('italic_togglebutton')
51                self.themes_tree = self.xml.get_widget('themes_treeview')
52                self.theme_options_vbox = self.xml.get_widget('theme_options_vbox')
53                self.colorbuttons = {}
54                for chatstate in ('inactive', 'composing', 'paused', 'gone',
55                'muc_msg', 'muc_directed_msg'):
56                        self.colorbuttons[chatstate] = self.xml.get_widget(chatstate + \
57                                '_colorbutton')
58                model = gtk.ListStore(str)
59                self.themes_tree.set_model(model)
60                col = gtk.TreeViewColumn(_('Theme'))
61                self.themes_tree.append_column(col)
62                renderer = gtk.CellRendererText()
63                col.pack_start(renderer, True)
64                col.set_attributes(renderer, text = 0)
65                renderer.connect('edited', self.on_theme_cell_edited)
66                renderer.set_property('editable', True)
67                self.current_theme = gajim.config.get('roster_theme')
68                self.no_update = False
69                self.fill_themes_treeview()
70                self.current_option = self.options[0]
71                self.set_theme_options(self.current_theme, self.current_option)
72               
73                self.xml.signal_autoconnect(self)
74                self.window.connect('delete-event', self.on_themese_window_delete_event)
75                self.themes_tree.get_selection().connect('changed', 
76                                self.selection_changed)
77                self.window.show_all()
78       
79        def on_themese_window_delete_event(self, widget, event):
80                self.window.hide()
81                return True # do NOT destroy the window
82       
83        def on_close_button_clicked(self, widget):
84                self.window.hide()
85
86        def on_theme_cell_edited(self, cell, row, new_name):
87                model = self.themes_tree.get_model()
88                iter = model.get_iter_from_string(row)
89                old_name = model.get_value(iter, 0).decode('utf-8')
90                new_name = new_name.decode('utf-8')
91                if old_name == new_name:
92                        return
93                new_config_name = new_name.replace(' ', '_')
94                if new_config_name in gajim.config.get_per('themes'):
95                        return
96                gajim.config.add_per('themes', new_config_name)
97                # Copy old theme values
98                old_config_name = old_name.replace(' ', '_')
99                properties = ['textcolor', 'bgcolor', 'font', 'fontattrs']
100                gajim.config.add_per('themes', new_config_name)
101                for option in self.options:
102                        for property in properties:
103                                option_name = option + property
104                                gajim.config.set_per('themes', new_config_name, option_name,
105                                        gajim.config.get_per('themes', old_config_name, option_name))
106                gajim.config.del_per('themes', old_config_name)
107                if old_config_name == gajim.config.get('roster_theme'):
108                        gajim.config.set('roster_theme', new_config_name)
109                model.set_value(iter, 0, new_name)
110                self.current_theme = new_name
111
112        def fill_themes_treeview(self):
113                self.xml.get_widget('remove_button').set_sensitive(False)
114                self.theme_options_vbox.set_sensitive(False)
115                model = self.themes_tree.get_model()
116                model.clear()
117                for config_theme in gajim.config.get_per('themes'):
118                        theme = config_theme.replace('_', ' ')
119                        iter = model.append([theme])
120                        if gajim.config.get('roster_theme') == config_theme:
121                                self.themes_tree.get_selection().select_iter(iter)
122                                self.xml.get_widget('remove_button').set_sensitive(True)
123                                self.theme_options_vbox.set_sensitive(True)
124
125        def select_active_theme(self):
126                model = self.themes_tree.get_model()
127                iter = model.get_iter_root()
128                active_theme = gajim.config.get('roster_theme')
129                while iter:
130                        theme = model[iter][0]
131                        if theme == active_theme:
132                                self.themes_tree.get_selection().select_iter(iter)
133                                self.xml.get_widget('remove_button').set_sensitive(True)
134                                self.theme_options_vbox.set_sensitive(True)
135                                break
136                        iter = model.iter_next(iter)
137
138        def selection_changed(self, widget = None):
139                (model, iter) = self.themes_tree.get_selection().get_selected()
140                selected = self.themes_tree.get_selection().get_selected_rows()
141                if not iter or selected[1] == []:
142                        self.theme_options_vbox.set_sensitive(False)
143                        return
144                self.xml.get_widget('remove_button').set_sensitive(True)
145                self.theme_options_vbox.set_sensitive(True)
146                self.current_theme = model.get_value(iter, 0).decode('utf-8')
147                self.current_theme = self.current_theme.replace(' ', '_')
148                self.set_theme_options(self.current_theme)
149
150        def on_add_button_clicked(self, widget):
151                model = self.themes_tree.get_model()
152                iter = model.append()
153                i = 0
154                # don't confuse translators
155                theme_name = _('theme name')
156                theme_name_ns = theme_name.replace(' ', '_')
157                while theme_name_ns + unicode(i) in gajim.config.get_per('themes'):
158                        i += 1
159                model.set_value(iter, 0, theme_name + unicode(i))
160                gajim.config.add_per('themes', theme_name_ns + unicode(i))
161                self.themes_tree.get_selection().select_iter(iter)
162                col = self.themes_tree.get_column(0)
163                path = model.get_path(iter)
164                self.themes_tree.set_cursor(path, col, True)
165
166        def on_remove_button_clicked(self, widget):
167                (model, iter) = self.themes_tree.get_selection().get_selected()
168                if not iter:
169                        return
170                if self.current_theme == gajim.config.get('roster_theme'):
171                        dialogs.ErrorDialog(
172                                _('You cannot delete your current theme'),
173                        _('Please first choose another for your current theme.'))
174                        return
175                self.theme_options_vbox.set_sensitive(False)
176                gajim.config.del_per('themes', self.current_theme)
177                model.remove(iter)
178       
179        def set_theme_options(self, theme, option = 'account'):
180                self.no_update = True
181                self.options_combobox.set_active(self.options.index(option))
182                textcolor = gajim.config.get_per('themes', theme, option + 'textcolor')
183                if textcolor:
184                        state = True
185                        self.text_colorbutton.set_color(gtk.gdk.color_parse(textcolor))
186                else:
187                        state = False
188                self.textcolor_checkbutton.set_active(state)
189                self.text_colorbutton.set_sensitive(state)
190                bgcolor = gajim.config.get_per('themes', theme, option + 'bgcolor')
191                if bgcolor:
192                        state = True
193                        self.background_colorbutton.set_color(gtk.gdk.color_parse(
194                                bgcolor))
195                else:
196                        state = False
197                self.background_checkbutton.set_active(state)
198                self.background_colorbutton.set_sensitive(state)
199               
200                # get the font name before we set widgets and it will not be overriden
201                font_name = gajim.config.get_per('themes', theme, option + 'font')
202                font_attrs = gajim.config.get_per('themes', theme, option + 'fontattrs')
203                self._set_font_widgets(font_attrs)
204                if font_name:
205                        state = True
206                        self.text_fontbutton.set_font_name(font_name)
207                else:
208                        state = False
209                self.textfont_checkbutton.set_active(state)
210                self.text_fontbutton.set_sensitive(state)
211                self.no_update = False
212                gajim.interface.roster.change_roster_style(None)
213
214                for chatstate in ('inactive', 'composing', 'paused', 'gone',
215                'muc_msg', 'muc_directed_msg'):
216                        color = gajim.config.get_per('themes', theme, 'state_' + chatstate + \
217                                '_color')
218                        self.colorbuttons[chatstate].set_color(gtk.gdk.color_parse(color))
219               
220        def on_textcolor_checkbutton_toggled(self, widget):
221                state = widget.get_active()
222                self.text_colorbutton.set_sensitive(state)
223                self._set_color(state, self.text_colorbutton, 
224                        'textcolor')
225       
226        def on_background_checkbutton_toggled(self, widget):
227                state = widget.get_active()
228                self.background_colorbutton.set_sensitive(state)
229                self._set_color(state, self.background_colorbutton, 
230                        'bgcolor')
231               
232        def on_textfont_checkbutton_toggled(self, widget):
233                self.text_fontbutton.set_sensitive(widget.get_active())
234                self._set_font()
235       
236        def on_text_colorbutton_color_set(self, widget):
237                self._set_color(True, widget, 'textcolor')
238                       
239        def on_background_colorbutton_color_set(self, widget):
240                self._set_color(True, widget, 'bgcolor')
241       
242        def on_text_fontbutton_font_set(self, widget):
243                self._set_font()
244       
245        def on_options_combobox_changed(self, widget):
246                index = self.options_combobox.get_active()
247                if index == -1:
248                        return
249                self.current_option = self.options[index]
250                self.set_theme_options(self.current_theme,
251                        self.current_option)
252               
253        def on_bold_togglebutton_toggled(self, widget):
254                if not self.no_update:
255                        self._set_font()
256       
257        def on_italic_togglebutton_toggled(self, widget):
258                if not self.no_update:
259                        self._set_font()
260       
261        def _set_color(self, state, widget, option):
262                ''' set color value in prefs and update the UI '''
263                if state:
264                        color = widget.get_color()
265                        color_string = gtkgui_helpers.make_color_string(color)
266                else:
267                        color_string = ''
268                begin_option = ''
269                if not option.startswith('state'):
270                        begin_option = self.current_option
271                gajim.config.set_per('themes', self.current_theme, 
272                        begin_option + option, color_string)
273                # use faster functions for this
274                if self.current_option == 'banner':
275                        gajim.interface.roster.repaint_themed_widgets()
276                        gajim.interface.save_config()
277                        return
278                if self.no_update:
279                        return
280                gajim.interface.roster.change_roster_style(self.current_option)
281                gajim.interface.save_config()
282               
283        def _set_font(self):
284                ''' set font value in prefs and update the UI '''
285                state = self.textfont_checkbutton.get_active()
286                if state:
287                        font_string = self.text_fontbutton.get_font_name()
288                else:
289                        font_string = ''
290                gajim.config.set_per('themes', self.current_theme, 
291                        self.current_option + 'font', font_string)
292                font_attrs = self._get_font_attrs()
293                gajim.config.set_per('themes', self.current_theme, 
294                        self.current_option + 'fontattrs', font_attrs)
295                # use faster functions for this
296                if self.current_option == 'banner':
297                        gajim.interface.roster.repaint_themed_widgets()
298                if self.no_update:
299                        return
300                gajim.interface.roster.change_roster_style(self.current_option)
301                gajim.interface.save_config()
302       
303        def _toggle_font_widgets(self, font_props):
304                ''' toggle font buttons with the bool values of font_props tuple'''
305                self.bold_togglebutton.set_active(font_props[0])
306                self.italic_togglebutton.set_active(font_props[1])
307       
308        def _get_font_description(self):
309                ''' return a FontDescription from togglebuttons
310                states'''
311                fd = pango.FontDescription()
312                if self.bold_togglebutton.get_active():
313                        fd.set_weight(pango.WEIGHT_BOLD)
314                if self.italic_togglebutton.get_active():
315                        fd.set_style(pango.STYLE_ITALIC)
316                return fd
317               
318        def _set_font_widgets(self, font_attrs):
319                ''' set the correct toggle state of font style buttons by
320                a font string of type 'BI' '''
321                font_props = [False, False, False]
322                if font_attrs:
323                        if font_attrs.find('B') != -1:
324                                font_props[0] = True
325                        if font_attrs.find('I') != -1:
326                                font_props[1] = True
327                self._toggle_font_widgets(font_props)
328               
329        def _get_font_attrs(self):
330                ''' get a string with letters of font attribures: 'BI' '''
331                attrs = ''
332                if self.bold_togglebutton.get_active():
333                        attrs += 'B'
334                if self.italic_togglebutton.get_active():
335                        attrs += 'I'
336                return attrs
337               
338
339        def _get_font_props(self, font_name):
340                ''' get tuple of font properties: Weight, Style '''
341                font_props = [False, False, False]
342                font_description = pango.FontDescription(font_name)
343                if font_description.get_weight() != pango.WEIGHT_NORMAL:
344                        font_props[0] = True
345                if font_description.get_style() != pango.STYLE_ITALIC:
346                        font_props[1] = True
347                return font_props
348
349        def on_inactive_colorbutton_color_set(self, widget):
350                self.no_update = True
351                self._set_color(True, widget, 'state_inactive_color')
352                self.no_update = False
353
354        def on_composing_colorbutton_color_set(self, widget):
355                self.no_update = True
356                self._set_color(True, widget, 'state_composing_color')
357                self.no_update = False
358
359        def on_paused_colorbutton_color_set(self, widget):
360                self.no_update = True
361                self._set_color(True, widget, 'state_paused_color')
362                self.no_update = False
363
364        def on_gone_colorbutton_color_set(self, widget):
365                self.no_update = True
366                self._set_color(True, widget, 'state_gone_color')
367                self.no_update = False
368
369        def on_muc_msg_colorbutton_color_set(self, widget):
370                self.no_update = True
371                self._set_color(True, widget, 'state_muc_msg_color')
372                self.no_update = False
373
374        def on_muc_directed_msg_colorbutton_color_set(self, widget):
375                self.no_update = True
376                self._set_color(True, widget, 'state_muc_directed_msg_color')
377                self.no_update = False
Note: See TracBrowser for help on using the browser.