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

Revision 8708, 13.5 kB (checked in by asterix, 15 months ago)

Update combobox in prefs window to reflect theme changes

  • 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                if gajim.interface.instances.has_key('preferences'):
85                        gajim.interface.instances['preferences'].update_theme_list()
86                self.window.hide()
87
88        def on_theme_cell_edited(self, cell, row, new_name):
89                model = self.themes_tree.get_model()
90                iter = model.get_iter_from_string(row)
91                old_name = model.get_value(iter, 0).decode('utf-8')
92                new_name = new_name.decode('utf-8')
93                if old_name == new_name:
94                        return
95                new_config_name = new_name.replace(' ', '_')
96                if new_config_name in gajim.config.get_per('themes'):
97                        return
98                gajim.config.add_per('themes', new_config_name)
99                # Copy old theme values
100                old_config_name = old_name.replace(' ', '_')
101                properties = ['textcolor', 'bgcolor', 'font', 'fontattrs']
102                gajim.config.add_per('themes', new_config_name)
103                for option in self.options:
104                        for property in properties:
105                                option_name = option + property
106                                gajim.config.set_per('themes', new_config_name, option_name,
107                                        gajim.config.get_per('themes', old_config_name, option_name))
108                gajim.config.del_per('themes', old_config_name)
109                if old_config_name == gajim.config.get('roster_theme'):
110                        gajim.config.set('roster_theme', new_config_name)
111                model.set_value(iter, 0, new_name)
112                self.current_theme = new_name
113
114        def fill_themes_treeview(self):
115                self.xml.get_widget('remove_button').set_sensitive(False)
116                self.theme_options_vbox.set_sensitive(False)
117                model = self.themes_tree.get_model()
118                model.clear()
119                for config_theme in gajim.config.get_per('themes'):
120                        theme = config_theme.replace('_', ' ')
121                        iter = model.append([theme])
122                        if gajim.config.get('roster_theme') == config_theme:
123                                self.themes_tree.get_selection().select_iter(iter)
124                                self.xml.get_widget('remove_button').set_sensitive(True)
125                                self.theme_options_vbox.set_sensitive(True)
126
127        def select_active_theme(self):
128                model = self.themes_tree.get_model()
129                iter = model.get_iter_root()
130                active_theme = gajim.config.get('roster_theme')
131                while iter:
132                        theme = model[iter][0]
133                        if theme == active_theme:
134                                self.themes_tree.get_selection().select_iter(iter)
135                                self.xml.get_widget('remove_button').set_sensitive(True)
136                                self.theme_options_vbox.set_sensitive(True)
137                                break
138                        iter = model.iter_next(iter)
139
140        def selection_changed(self, widget = None):
141                (model, iter) = self.themes_tree.get_selection().get_selected()
142                selected = self.themes_tree.get_selection().get_selected_rows()
143                if not iter or selected[1] == []:
144                        self.theme_options_vbox.set_sensitive(False)
145                        return
146                self.xml.get_widget('remove_button').set_sensitive(True)
147                self.theme_options_vbox.set_sensitive(True)
148                self.current_theme = model.get_value(iter, 0).decode('utf-8')
149                self.current_theme = self.current_theme.replace(' ', '_')
150                self.set_theme_options(self.current_theme)
151
152        def on_add_button_clicked(self, widget):
153                model = self.themes_tree.get_model()
154                iter = model.append()
155                i = 0
156                # don't confuse translators
157                theme_name = _('theme name')
158                theme_name_ns = theme_name.replace(' ', '_')
159                while theme_name_ns + unicode(i) in gajim.config.get_per('themes'):
160                        i += 1
161                model.set_value(iter, 0, theme_name + unicode(i))
162                gajim.config.add_per('themes', theme_name_ns + unicode(i))
163                self.themes_tree.get_selection().select_iter(iter)
164                col = self.themes_tree.get_column(0)
165                path = model.get_path(iter)
166                self.themes_tree.set_cursor(path, col, True)
167
168        def on_remove_button_clicked(self, widget):
169                (model, iter) = self.themes_tree.get_selection().get_selected()
170                if not iter:
171                        return
172                if self.current_theme == gajim.config.get('roster_theme'):
173                        dialogs.ErrorDialog(
174                                _('You cannot delete your current theme'),
175                        _('Please first choose another for your current theme.'))
176                        return
177                self.theme_options_vbox.set_sensitive(False)
178                gajim.config.del_per('themes', self.current_theme)
179                model.remove(iter)
180       
181        def set_theme_options(self, theme, option = 'account'):
182                self.no_update = True
183                self.options_combobox.set_active(self.options.index(option))
184                textcolor = gajim.config.get_per('themes', theme, option + 'textcolor')
185                if textcolor:
186                        state = True
187                        self.text_colorbutton.set_color(gtk.gdk.color_parse(textcolor))
188                else:
189                        state = False
190                self.textcolor_checkbutton.set_active(state)
191                self.text_colorbutton.set_sensitive(state)
192                bgcolor = gajim.config.get_per('themes', theme, option + 'bgcolor')
193                if bgcolor:
194                        state = True
195                        self.background_colorbutton.set_color(gtk.gdk.color_parse(
196                                bgcolor))
197                else:
198                        state = False
199                self.background_checkbutton.set_active(state)
200                self.background_colorbutton.set_sensitive(state)
201               
202                # get the font name before we set widgets and it will not be overriden
203                font_name = gajim.config.get_per('themes', theme, option + 'font')
204                font_attrs = gajim.config.get_per('themes', theme, option + 'fontattrs')
205                self._set_font_widgets(font_attrs)
206                if font_name:
207                        state = True
208                        self.text_fontbutton.set_font_name(font_name)
209                else:
210                        state = False
211                self.textfont_checkbutton.set_active(state)
212                self.text_fontbutton.set_sensitive(state)
213                self.no_update = False
214                gajim.interface.roster.change_roster_style(None)
215
216                for chatstate in ('inactive', 'composing', 'paused', 'gone',
217                'muc_msg', 'muc_directed_msg'):
218                        color = gajim.config.get_per('themes', theme, 'state_' + chatstate + \
219                                '_color')
220                        self.colorbuttons[chatstate].set_color(gtk.gdk.color_parse(color))
221               
222        def on_textcolor_checkbutton_toggled(self, widget):
223                state = widget.get_active()
224                self.text_colorbutton.set_sensitive(state)
225                self._set_color(state, self.text_colorbutton, 
226                        'textcolor')
227       
228        def on_background_checkbutton_toggled(self, widget):
229                state = widget.get_active()
230                self.background_colorbutton.set_sensitive(state)
231                self._set_color(state, self.background_colorbutton, 
232                        'bgcolor')
233               
234        def on_textfont_checkbutton_toggled(self, widget):
235                self.text_fontbutton.set_sensitive(widget.get_active())
236                self._set_font()
237       
238        def on_text_colorbutton_color_set(self, widget):
239                self._set_color(True, widget, 'textcolor')
240                       
241        def on_background_colorbutton_color_set(self, widget):
242                self._set_color(True, widget, 'bgcolor')
243       
244        def on_text_fontbutton_font_set(self, widget):
245                self._set_font()
246       
247        def on_options_combobox_changed(self, widget):
248                index = self.options_combobox.get_active()
249                if index == -1:
250                        return
251                self.current_option = self.options[index]
252                self.set_theme_options(self.current_theme,
253                        self.current_option)
254               
255        def on_bold_togglebutton_toggled(self, widget):
256                if not self.no_update:
257                        self._set_font()
258       
259        def on_italic_togglebutton_toggled(self, widget):
260                if not self.no_update:
261                        self._set_font()
262       
263        def _set_color(self, state, widget, option):
264                ''' set color value in prefs and update the UI '''
265                if state:
266                        color = widget.get_color()
267                        color_string = gtkgui_helpers.make_color_string(color)
268                else:
269                        color_string = ''
270                begin_option = ''
271                if not option.startswith('state'):
272                        begin_option = self.current_option
273                gajim.config.set_per('themes', self.current_theme, 
274                        begin_option + option, color_string)
275                # use faster functions for this
276                if self.current_option == 'banner':
277                        gajim.interface.roster.repaint_themed_widgets()
278                        gajim.interface.save_config()
279                        return
280                if self.no_update:
281                        return
282                gajim.interface.roster.change_roster_style(self.current_option)
283                gajim.interface.save_config()
284               
285        def _set_font(self):
286                ''' set font value in prefs and update the UI '''
287                state = self.textfont_checkbutton.get_active()
288                if state:
289                        font_string = self.text_fontbutton.get_font_name()
290                else:
291                        font_string = ''
292                gajim.config.set_per('themes', self.current_theme, 
293                        self.current_option + 'font', font_string)
294                font_attrs = self._get_font_attrs()
295                gajim.config.set_per('themes', self.current_theme, 
296                        self.current_option + 'fontattrs', font_attrs)
297                # use faster functions for this
298                if self.current_option == 'banner':
299                        gajim.interface.roster.repaint_themed_widgets()
300                if self.no_update:
301                        return
302                gajim.interface.roster.change_roster_style(self.current_option)
303                gajim.interface.save_config()
304       
305        def _toggle_font_widgets(self, font_props):
306                ''' toggle font buttons with the bool values of font_props tuple'''
307                self.bold_togglebutton.set_active(font_props[0])
308                self.italic_togglebutton.set_active(font_props[1])
309       
310        def _get_font_description(self):
311                ''' return a FontDescription from togglebuttons
312                states'''
313                fd = pango.FontDescription()
314                if self.bold_togglebutton.get_active():
315                        fd.set_weight(pango.WEIGHT_BOLD)
316                if self.italic_togglebutton.get_active():
317                        fd.set_style(pango.STYLE_ITALIC)
318                return fd
319               
320        def _set_font_widgets(self, font_attrs):
321                ''' set the correct toggle state of font style buttons by
322                a font string of type 'BI' '''
323                font_props = [False, False, False]
324                if font_attrs:
325                        if font_attrs.find('B') != -1:
326                                font_props[0] = True
327                        if font_attrs.find('I') != -1:
328                                font_props[1] = True
329                self._toggle_font_widgets(font_props)
330               
331        def _get_font_attrs(self):
332                ''' get a string with letters of font attribures: 'BI' '''
333                attrs = ''
334                if self.bold_togglebutton.get_active():
335                        attrs += 'B'
336                if self.italic_togglebutton.get_active():
337                        attrs += 'I'
338                return attrs
339               
340
341        def _get_font_props(self, font_name):
342                ''' get tuple of font properties: Weight, Style '''
343                font_props = [False, False, False]
344                font_description = pango.FontDescription(font_name)
345                if font_description.get_weight() != pango.WEIGHT_NORMAL:
346                        font_props[0] = True
347                if font_description.get_style() != pango.STYLE_ITALIC:
348                        font_props[1] = True
349                return font_props
350
351        def on_inactive_colorbutton_color_set(self, widget):
352                self.no_update = True
353                self._set_color(True, widget, 'state_inactive_color')
354                self.no_update = False
355
356        def on_composing_colorbutton_color_set(self, widget):
357                self.no_update = True
358                self._set_color(True, widget, 'state_composing_color')
359                self.no_update = False
360
361        def on_paused_colorbutton_color_set(self, widget):
362                self.no_update = True
363                self._set_color(True, widget, 'state_paused_color')
364                self.no_update = False
365
366        def on_gone_colorbutton_color_set(self, widget):
367                self.no_update = True
368                self._set_color(True, widget, 'state_gone_color')
369                self.no_update = False
370
371        def on_muc_msg_colorbutton_color_set(self, widget):
372                self.no_update = True
373                self._set_color(True, widget, 'state_muc_msg_color')
374                self.no_update = False
375
376        def on_muc_directed_msg_colorbutton_color_set(self, widget):
377                self.no_update = True
378                self._set_color(True, widget, 'state_muc_directed_msg_color')
379                self.no_update = False
Note: See TracBrowser for help on using the browser.