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

Revision 4854, 96.5 kB (checked in by nk, 3 years ago)

[greblus] preferences window now can control the color of URLs

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