root/branches/gajim_0.8.1/src/config.py

Revision 3313, 103.7 kB (checked in by nk, 3 years ago)

[stephan k.] fix so theme names can have space

Line 
1##      config.py
2##
3## Gajim Team:
4##      - Yann Le Boulanger <asterix@lagaule.org>
5##      - Vincent Hanquez <tab@snarc.org>
6##      - Nikos Kouremenos <kourem@gmail.com>
7##
8##      Copyright (C) 2003-2005 Gajim Team
9##
10## This program is free software; you can redistribute it and/or modify
11## it under the terms of the GNU General Public License as published
12## by the Free Software Foundation; version 2 only.
13##
14## This program is distributed in the hope that it will be useful,
15## but WITHOUT ANY WARRANTY; without even the implied warranty of
16## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17## GNU General Public License for more details.
18##
19
20import gtk
21import gtk.glade
22import gobject
23import os
24import sys
25import common.config
26import common.sleepy
27
28import gtkgui_helpers
29import dialogs
30import cell_renderer_image
31import cell_renderer_image
32
33try:
34        import gtkspell
35except:
36        pass
37
38from gajim import Contact
39from common import helpers
40from common import gajim
41from common import connection
42from common import i18n
43
44_ = i18n._
45APP = i18n.APP
46gtk.glade.bindtextdomain (APP, i18n.DIR)
47gtk.glade.textdomain (APP)
48
49GTKGUI_GLADE = 'gtkgui.glade'
50
51
52# helper function to create #aabbcc color string
53def mk_color_string(color):
54        return '#' + (hex(color.red) + '0')[2:4] + \
55                (hex(color.green) + '0')[2:4] + \
56                (hex(color.blue) + '0')[2:4]
57
58
59#---------- PreferencesWindow class -------------#
60class PreferencesWindow:
61        '''Class for Preferences window'''
62       
63        def on_preferences_window_delete_event(self, widget, event):
64                self.window.hide()
65                return True # do NOT destroy the window
66       
67        def on_close_button_clicked(self, widget):
68                self.window.hide()
69
70        def __init__(self, plugin):
71                '''Initialize Preferences window'''
72                self.xml = gtk.glade.XML(GTKGUI_GLADE, 'preferences_window', APP)
73                self.window = self.xml.get_widget('preferences_window')
74                self.plugin = plugin
75                self.iconset_combobox = self.xml.get_widget('iconset_combobox')
76                self.notify_on_new_message_radiobutton = self.xml.get_widget \
77                        ('notify_on_new_message_radiobutton')
78                self.popup_new_message_radiobutton = self.xml.get_widget \
79                        ('popup_new_message_radiobutton')
80                self.notify_on_signin_checkbutton = self.xml.get_widget \
81                        ('notify_on_signin_checkbutton')
82                self.notify_on_signout_checkbutton = self.xml.get_widget \
83                        ('notify_on_signout_checkbutton')
84                self.auto_popup_away_checkbutton = self.xml.get_widget \
85                        ('auto_popup_away_checkbutton')
86                self.auto_away_checkbutton = self.xml.get_widget('auto_away_checkbutton')
87                self.auto_away_time_spinbutton = self.xml.get_widget \
88                        ('auto_away_time_spinbutton')
89                self.auto_away_message_entry = self.xml.get_widget \
90                        ('auto_away_message_entry')
91                self.auto_xa_checkbutton = self.xml.get_widget('auto_xa_checkbutton')
92                self.auto_xa_time_spinbutton = self.xml.get_widget(
93                        'auto_xa_time_spinbutton')
94                self.auto_xa_message_entry = self.xml.get_widget('auto_xa_message_entry')
95                self.trayicon_checkbutton = self.xml.get_widget('trayicon_checkbutton')
96                self.notebook = self.xml.get_widget('preferences_notebook')
97               
98                #trayicon
99                if self.plugin.systray_capabilities:
100                        st = gajim.config.get('trayicon')
101                        self.trayicon_checkbutton.set_active(st)
102                else:
103                        self.trayicon_checkbutton.set_sensitive(False)
104
105                #Show roster on Gajim startup
106                st = gajim.config.get('show_roster_on_startup')
107                show_roster_on_startup_checkbutton = self.xml.get_widget(
108                        'show_roster_on_startup_checkbutton')
109                if os.name == 'nt':
110                        show_roster_on_startup_checkbutton.set_no_show_all(True)
111                else:
112                        if gajim.config.get('trayicon'): # allow it only when trayicon ON
113                                show_roster_on_startup_checkbutton.set_active(st)
114                        else:
115                                show_roster_on_startup_checkbutton.set_sensitive(False)
116                                show_roster_on_startup_checkbutton.set_active(st)
117
118                #Save position
119                st = gajim.config.get('saveposition')
120                self.xml.get_widget('save_position_checkbutton').set_active(st)
121               
122                #Merge accounts
123                st = gajim.config.get('mergeaccounts')
124                self.xml.get_widget('merge_checkbutton').set_active(st)
125
126                # Sort contacts by show
127                st = gajim.config.get('sort_by_show')
128                self.xml.get_widget('sort_by_show_checkbutton').set_active(st)
129
130                #Use emoticons
131                st = gajim.config.get('useemoticons')
132                self.xml.get_widget('use_emoticons_checkbutton').set_active(st)
133                self.xml.get_widget('add_remove_emoticons_button').set_sensitive(st)
134
135                #iconset
136                iconsets_list = os.listdir(os.path.join(gajim.DATA_DIR, 'iconsets'))
137                # new model, image in 0, string in 1
138                model = gtk.ListStore(gtk.Image, str)
139                renderer_image = cell_renderer_image.CellRendererImage()
140                renderer_text = gtk.CellRendererText()
141                renderer_text.set_property('xpad', 5)
142                self.iconset_combobox.pack_start(renderer_image, expand=False)
143                self.iconset_combobox.pack_start(renderer_text, expand=True)
144                self.iconset_combobox.set_attributes(renderer_text, text=1)
145                self.iconset_combobox.add_attribute(renderer_image, 'image', 0)
146                self.iconset_combobox.set_model(model)
147                l = []
148                for dir in iconsets_list:
149                        if dir != '.svn' and dir != 'transports':
150                                l.append(dir)
151                if l.count == 0:
152                        l.append(' ')
153                for i in range(len(l)):
154                        preview = gtk.Image()
155                        files = []
156                        files.append(os.path.join(gajim.DATA_DIR, 'iconsets', l[i], '16x16', 'online.png'))
157                        files.append(os.path.join(gajim.DATA_DIR, 'iconsets', l[i], '16x16', 'online.gif'))
158                        for file in files:
159                                if os.path.exists(file):
160                                        preview.set_from_file(file)
161                        model.append([preview, l[i]])
162                        if gajim.config.get('iconset') == l[i]:
163                                self.iconset_combobox.set_active(i)
164
165                # Use transports iconsets
166                st = gajim.config.get('use_transports_iconsets')
167                self.xml.get_widget('transports_iconsets_checkbutton').set_active(st)
168
169                # Themes
170                theme_combobox = self.xml.get_widget('theme_combobox')
171                cell = gtk.CellRendererText()
172                theme_combobox.pack_start(cell, True)
173                theme_combobox.add_attribute(cell, 'text', 0) 
174                model = gtk.ListStore(str)
175                theme_combobox.set_model(model)
176
177                #use tabbed chat window
178                st = gajim.config.get('usetabbedchat')
179                self.xml.get_widget('use_tabbed_chat_window_checkbutton').set_active(st)
180               
181                # always compact view
182                st = gajim.config.get('always_compact_view')
183                self.xml.get_widget('always_compact_view_checkbutton').set_active(st)
184               
185                #use speller
186                if os.name == 'nt':
187                        self.xml.get_widget('speller_checkbutton').set_no_show_all(True)
188                else:
189                        if 'gtkspell' in globals():
190                                st = gajim.config.get('use_speller')
191                                self.xml.get_widget('speller_checkbutton').set_active(st)
192                        else:
193                                self.xml.get_widget('speller_checkbutton').set_sensitive(False)
194               
195                #Print time
196                st = gajim.config.get('print_ichat_every_foo_minutes')
197                text = _('Every %s _minutes') % st
198                self.xml.get_widget('time_sometimes_radiobutton').set_label(text)
199
200                if gajim.config.get('print_time') == 'never':
201                        self.xml.get_widget('time_never_radiobutton').set_active(True)
202                elif gajim.config.get('print_time') == 'sometimes':
203                        self.xml.get_widget('time_sometimes_radiobutton').set_active(True)
204                else:
205                        self.xml.get_widget('time_always_radiobutton').set_active(True)
206
207                #before time
208                st = gajim.config.get('before_time')
209                self.xml.get_widget('before_time_entry').set_text(st)
210               
211                #after time
212                st = gajim.config.get('after_time')
213                self.xml.get_widget('after_time_entry').set_text(st)
214
215                #before nickname
216                st = gajim.config.get('before_nickname')
217                self.xml.get_widget('before_nickname_entry').set_text(st)
218
219                #after nickanme
220                st = gajim.config.get('after_nickname')
221                self.xml.get_widget('after_nickname_entry').set_text(st)
222
223                #Color for incomming messages
224                colSt = gajim.config.get('inmsgcolor')
225                self.xml.get_widget('incoming_msg_colorbutton').set_color(
226                        gtk.gdk.color_parse(colSt))
227               
228                #Color for outgoing messages
229                colSt = gajim.config.get('outmsgcolor')
230                self.xml.get_widget('outgoing_msg_colorbutton').set_color(
231                        gtk.gdk.color_parse(colSt))
232               
233                #Color for status messages
234                colSt = gajim.config.get('statusmsgcolor')
235                self.xml.get_widget('status_msg_colorbutton').set_color(
236                        gtk.gdk.color_parse(colSt))
237
238                #Font for messages
239                font = gajim.config.get('conversation_font')
240                # try to set default font for the current desktop env
241                if font == '':
242                        font = gtkgui_helpers.get_default_font()
243                        if font is None:
244                                font = 'Sans 10'
245                        gajim.config.set('conversation_font', font)
246                self.xml.get_widget('conversation_fontbutton').set_font_name(font)
247
248                # on new message
249                only_in_roster = True
250                if gajim.config.get('notify_on_new_message'):
251                        self.xml.get_widget('notify_on_new_message_radiobutton').set_active(
252                                True)
253                        only_in_roster = False
254                if gajim.config.get('autopopup'):
255                        self.xml.get_widget('popup_new_message_radiobutton').set_active(True)
256                        only_in_roster = False
257                if only_in_roster:
258                        self.xml.get_widget('only_in_roster_radiobutton').set_active(True)
259
260                #notify on online statuses
261                st = gajim.config.get('notify_on_signin')
262                self.notify_on_signin_checkbutton.set_active(st)
263
264                #notify on offline statuses
265                st = gajim.config.get('notify_on_signout')
266                self.notify_on_signout_checkbutton.set_active(st)
267
268                #autopopupaway
269                st = gajim.config.get('autopopupaway')
270                self.auto_popup_away_checkbutton.set_active(st)
271
272                #Ignore messages from unknown contacts
273                self.xml.get_widget('ignore_events_from_unknown_contacts_checkbutton').\
274                        set_active(gajim.config.get('ignore_unknown_contacts'))
275               
276                # send chat state notifications
277                st = gajim.config.get('chat_state_notifications')
278                combo = self.xml.get_widget('chat_states_combobox')
279                if st == 'all':
280                        combo.set_active(0)
281                elif st == 'composing_only':
282                        combo.set_active(1)
283                else: # disabled
284                        combo.set_active(2)
285
286                #sounds
287                if os.name == 'nt': # if windows, player must not become visible on show_all
288                        soundplayer_hbox = self.xml.get_widget('soundplayer_hbox')
289                        soundplayer_hbox.set_no_show_all(True)
290                if gajim.config.get('sounds_on'):
291                        self.xml.get_widget('play_sounds_checkbutton').set_active(True)
292                else:
293                        self.xml.get_widget('soundplayer_hbox').set_sensitive(False)
294                        self.xml.get_widget('sounds_scrolledwindow').set_sensitive(False)
295                        self.xml.get_widget('browse_sounds_hbox').set_sensitive(False)
296
297                # sound player
298                player = gajim.config.get('soundplayer')
299                self.xml.get_widget('soundplayer_entry').set_text(player)
300                if player == '': # only on first time Gajim starts
301                        commands = ('esdplay', 'artsplay', 'aplay', 'play')
302                        for command in commands:
303                                if helpers.is_in_path(command):
304                                        self.xml.get_widget('soundplayer_entry').set_text(command)
305                                        gajim.config.set('soundplayer', command)
306                                        break
307               
308               
309
310                #sounds treeview
311                self.sound_tree = self.xml.get_widget('sounds_treeview')
312                model = gtk.ListStore(str,      bool, str)
313                self.sound_tree.set_model(model)
314
315                col = gtk.TreeViewColumn(_('Active'))
316                self.sound_tree.append_column(col)
317                renderer = gtk.CellRendererToggle()
318                renderer.set_property('activatable', True)
319                renderer.connect('toggled', self.sound_toggled_cb)
320                col.pack_start(renderer)
321                col.set_attributes(renderer, active = 1)
322
323                col = gtk.TreeViewColumn(_('Event'))
324                self.sound_tree.append_column(col)
325                renderer = gtk.CellRendererText()
326                col.pack_start(renderer)
327                col.set_attributes(renderer, text = 0)
328
329                col = gtk.TreeViewColumn(_('Sound'))
330                self.sound_tree.append_column(col)
331                renderer = gtk.CellRendererText()
332                col.pack_start(renderer)
333                col.set_attributes(renderer, text = 2)
334                self.fill_sound_treeview()
335               
336                #Autoaway
337                st = gajim.config.get('autoaway')
338                self.auto_away_checkbutton.set_active(st)
339
340                #Autoawaytime
341                st = gajim.config.get('autoawaytime')
342                self.auto_away_time_spinbutton.set_value(st)
343                self.auto_away_time_spinbutton.set_sensitive(gajim.config.get('autoaway'))
344
345                #autoaway message
346                st = gajim.config.get('autoaway_message')
347                self.auto_away_message_entry.set_text(st)
348                self.auto_away_message_entry.set_sensitive(gajim.config.get('autoaway'))
349
350                #Autoxa
351                st = gajim.config.get('autoxa')
352                self.auto_xa_checkbutton.set_active(st)
353
354                #Autoxatime
355                st = gajim.config.get('autoxatime')
356                self.auto_xa_time_spinbutton.set_value(st)
357                self.auto_xa_time_spinbutton.set_sensitive(gajim.config.get('autoxa'))
358
359                #autoxa message
360                st = gajim.config.get('autoxa_message')
361                self.auto_xa_message_entry.set_text(st)
362                self.auto_xa_message_entry.set_sensitive(gajim.config.get('autoxa'))
363
364                #ask_status when online / offline
365                st = gajim.config.get('ask_online_status')
366                self.xml.get_widget('prompt_online_status_message_checkbutton').\
367                        set_active(st)
368                st = gajim.config.get('ask_offline_status')
369                self.xml.get_widget('prompt_offline_status_message_checkbutton').\
370                        set_active(st)
371
372                #Status messages
373                self.msg_tree = self.xml.get_widget('msg_treeview')
374                model = gtk.ListStore(str, str)
375                self.msg_tree.set_model(model)
376                col = gtk.TreeViewColumn('name')
377                self.msg_tree.append_column(col)
378                renderer = gtk.CellRendererText()
379                col.pack_start(renderer, True)
380                col.set_attributes(renderer, text = 0)
381                renderer.connect('edited', self.on_msg_cell_edited)
382                renderer.set_property('editable', True)
383                self.fill_msg_treeview()
384                buf = self.xml.get_widget('msg_textview').get_buffer()
385                buf.connect('changed', self.on_msg_textview_changed)
386
387                #open links with
388                if os.name == 'nt':
389                        self.applications_frame = self.xml.get_widget('applications_frame')
390                        self.applications_frame.set_no_show_all(True)
391                        self.applications_frame.hide()
392                else:
393                        self.applications_combobox = self.xml.get_widget('applications_combobox')
394                        if gajim.config.get('autodetect_browser_mailer'):
395                                self.applications_combobox.set_active(0)
396                                gtkgui_helpers.autodetect_browser_mailer()
397                        # autodetect_browser_mailer is now False.
398                        # so user has 'Always Use GNOME/KDE' or Custom
399                        elif gajim.config.get('openwith') == 'gnome-open':
400                                self.applications_combobox.set_active(1)
401                        elif gajim.config.get('openwith') == 'kfmclient exec':
402                                self.applications_combobox.set_active(2)
403                        elif gajim.config.get('openwith') == 'custom':
404                                self.applications_combobox.set_active(3)
405                                self.xml.get_widget('custom_apps_frame').set_sensitive(True)
406                        self.xml.get_widget('custom_browser_entry').set_text(
407                                gajim.config.get('custombrowser'))
408                        self.xml.get_widget('custom_mail_client_entry').set_text(
409                                gajim.config.get('custommailapp'))
410                        self.xml.get_widget('custom_file_manager_entry').set_text(
411                                gajim.config.get('custom_file_manager'))
412
413                #log presences in user file
414                st = gajim.config.get('log_notif_in_user_file')
415                self.xml.get_widget('log_in_contact_checkbutton').set_active(st)
416
417                #log presences in external file
418                st = gajim.config.get('log_notif_in_sep_file')
419                self.xml.get_widget('log_in_extern_checkbutton').set_active(st)
420               
421                # send os info
422                st = gajim.config.get('send_os_info')
423                self.xml.get_widget('send_os_info_checkbutton').set_active(st)
424               
425                # check for new version
426                st = gajim.config.get('check_for_new_version')
427                btn = self.xml.get_widget('check_for_new_version_checkbutton')
428                btn.set_active(st)
429                               
430                self.xml.signal_autoconnect(self)
431               
432                self.sound_tree.get_model().connect('row-changed',
433                                        self.on_sounds_treemodel_row_changed)
434                self.msg_tree.get_model().connect('row-changed',
435                                        self.on_msg_treemodel_row_changed)
436                self.msg_tree.get_model().connect('row-deleted',
437                                        self.on_msg_treemodel_row_deleted)
438
439        def on_preferences_window_show(self, widget):
440                self.update_preferences_window()
441                self.notebook.set_current_page(0)
442               
443        def update_preferences_window(self):
444                st = gajim.config.get('print_ichat_every_foo_minutes')
445                text = _('Every %s _minutes') % st
446                self.xml.get_widget('time_sometimes_radiobutton').set_label(text)
447
448                #Themes
449                theme_combobox = self.xml.get_widget('theme_combobox')
450                model = theme_combobox.get_model()
451                model.clear()
452                i = 0
453                for config_theme in gajim.config.get_per('themes'):
454                        theme = config_theme.replace('_', ' ')
455                        model.append([theme])
456                        if gajim.config.get('roster_theme') == config_theme:
457                                theme_combobox.set_active(i)
458                        i += 1
459                self.on_theme_combobox_changed(theme_combobox)
460                #FIXME: move code from __init__ here
461
462        def on_preferences_window_key_press_event(self, widget, event):
463                if event.keyval == gtk.keysyms.Escape:
464                        self.window.hide()
465
466        def on_checkbutton_toggled(self, widget, config_name, \
467                change_sensitivity_widgets = None):
468                gajim.config.set(config_name, widget.get_active())
469                if change_sensitivity_widgets:
470                        for w in change_sensitivity_widgets:
471                                w.set_sensitive(widget.get_active())
472                self.plugin.save_config()
473
474        def on_trayicon_checkbutton_toggled(self, widget):
475                if widget.get_active():
476                        gajim.config.set('trayicon', True)
477                        self.plugin.show_systray()
478                        self.plugin.roster.update_status_comboxbox()
479
480                        self.xml.get_widget(
481                                'show_roster_on_startup_checkbutton').set_sensitive(True)
482                else:
483                        gajim.config.set('trayicon', False)
484                        self.plugin.hide_systray()
485                        show_roster_on_startup_checkbutton = self.xml.get_widget(
486                                'show_roster_on_startup_checkbutton')
487                        gajim.config.set('show_roster_on_startup', True) # no tray, show roster!
488                        show_roster_on_startup_checkbutton.set_active(True)
489                        show_roster_on_startup_checkbutton.set_sensitive(False)
490                self.plugin.roster.draw_roster()
491                self.plugin.save_config()
492       
493        def on_save_position_checkbutton_toggled(self, widget):
494                self.on_checkbutton_toggled(widget, 'saveposition')
495       
496        def on_merge_checkbutton_toggled(self, widget):
497                self.on_checkbutton_toggled(widget, 'mergeaccounts')
498                self.plugin.roster.regroup = gajim.config.get('mergeaccounts')
499                self.plugin.roster.draw_roster()
500       
501        def on_sort_by_show_checkbutton_toggled(self, widget):
502                self.on_checkbutton_toggled(widget, 'sort_by_show')
503                self.plugin.roster.draw_roster()
504       
505        def on_use_emoticons_checkbutton_toggled(self, widget):
506                self.on_checkbutton_toggled(widget, 'useemoticons', 
507                        [self.xml.get_widget('add_remove_emoticons_button')])
508       
509        def on_add_remove_emoticons_button_clicked(self, widget):
510                window = self.plugin.windows['add_remove_emoticons'].window
511                if window.get_property('visible'):
512                        window.present()
513                else:
514                        window.show_all()
515
516        def on_iconset_combobox_changed(self, widget):
517                model = widget.get_model()
518                active = widget.get_active()
519                icon_string = model[active][1].decode('utf-8')
520                gajim.config.set('iconset', icon_string)
521                self.plugin.roster.reload_jabber_state_images()
522                self.plugin.save_config()
523       
524        def on_transports_iconsets_checkbutton_toggled(self, widget):
525                self.on_checkbutton_toggled(widget, 'use_transports_iconsets')
526                self.plugin.roster.draw_roster()
527
528        def on_manage_theme_button_clicked(self, widget):
529                dialogs.GajimThemesWindow(self.plugin)
530       
531        def on_theme_combobox_changed(self, widget):
532                model = widget.get_model()
533                active = widget.get_active()
534                config_theme = model[active][0].decode('utf-8').replace(' ', '_')
535                               
536                gajim.config.set('roster_theme', config_theme)
537
538                # begin repainting themed widgets throughout
539                self.plugin.roster.repaint_themed_widgets()
540                self.plugin.save_config()
541                self.plugin.roster.draw_roster()
542
543        def merge_windows(self, kind):
544                for acct in gajim.connections:
545                        #save buffers and close windows
546                        buf1 = {}
547                        buf2 = {}
548                        saved_var = {}
549                        windows = self.plugin.windows[acct][kind]
550                        jids = windows.keys()
551                        for jid in jids:
552                                window = windows[jid]
553                                buf1[jid] = window.xmls[jid].get_widget('conversation_textview').\
554                                        get_buffer()
555                                buf2[jid] = window.xmls[jid].get_widget('message_textview').\
556                                        get_buffer()
557                                saved_var[jid] = window.save_var(jid)
558                                window.window.destroy()
559                        #open new tabbed chat windows
560                        for jid in jids:
561                                if kind == 'chats':
562                                        c = gajim.get_contact_instance_with_highest_priority(acct, jid)
563                                        self.plugin.roster.new_chat(c, acct)
564                                if kind == 'gc':
565                                        self.plugin.roster.new_room(jid, saved_var[jid]['nick'], acct)
566                                window = windows[jid]
567                                window.xmls[jid].get_widget('conversation_textview').set_buffer(
568                                        buf1[jid])
569                                window.xmls[jid].get_widget('message_textview').set_buffer(
570                                        buf2[jid])
571                                window.load_var(jid, saved_var[jid])
572
573        def split_windows(self, kind):
574                for acct in gajim.connections:
575                        #save buffers and close tabbed chat windows
576                        buf1 = {}
577                        buf2 = {}
578                        saved_var = {}
579                        windows = self.plugin.windows[acct][kind]
580                        jids = windows.keys()
581