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

Revision 3114, 101.5 kB (checked in by nk, 3 years ago)

xs:boolean is '0', '1', 'true', 'false'. so update bookmark to handle the last two

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