root/trunk/src/gajim_themes_window.py

Revision 10549, 14.2 kB (checked in by asterix, 6 weeks ago)

revert thorstenp patches for now. They introduce bugs.

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