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

Revision 6438, 99.5 kB (checked in by jim++, 2 years ago)

Use unified way to ask our own vcard so it is auto retrieved

  • Property svn:eol-style set to LF
Line 
1##      config.py
2##
3## Copyright (C) 2003-2006 Yann Le Boulanger <asterix@lagaule.org>
4## Copyright (C) 2005-2006 Nikos Kouremenos <nkour@jabber.org>
5## Copyright (C) 2005 Dimitur Kirov <dkirov@gmail.com>
6## Copyright (C) 2003-2005 Vincent Hanquez <tab@snarc.org>
7##
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published
10## by the Free Software Foundation; version 2 only.
11##
12## This program is distributed in the hope that it will be useful,
13## but WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15## GNU General Public License for more details.
16##
17
18import gtk
19import gtk.glade
20import gobject
21import os
22import common.config
23import common.sleepy
24
25import gtkgui_helpers
26import dialogs
27import vcard
28import cell_renderer_image
29import message_control
30import chat_control
31
32try:
33        import gtkspell
34        HAS_GTK_SPELL = True
35except:
36        HAS_GTK_SPELL = False
37
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
48#---------- PreferencesWindow class -------------#
49class PreferencesWindow:
50        '''Class for Preferences window'''
51
52        def on_preferences_window_destroy(self, widget):
53                '''close window'''
54                del gajim.interface.instances['preferences']
55
56        def on_close_button_clicked(self, widget):
57                self.window.destroy()
58
59        def __init__(self):
60                '''Initialize Preferences window'''
61                self.xml = gtkgui_helpers.get_glade('preferences_window.glade')
62                self.window = self.xml.get_widget('preferences_window')
63                self.iconset_combobox = self.xml.get_widget('iconset_combobox')
64                self.notify_on_new_message_radiobutton = self.xml.get_widget(
65                        'notify_on_new_message_radiobutton')
66                self.popup_new_message_radiobutton = self.xml.get_widget(
67                        'popup_new_message_radiobutton')
68                self.notify_on_signin_checkbutton = self.xml.get_widget(
69                        'notify_on_signin_checkbutton')
70                self.notify_on_signout_checkbutton = self.xml.get_widget(
71                        'notify_on_signout_checkbutton')
72                self.auto_popup_away_checkbutton = self.xml.get_widget(
73                        'auto_popup_away_checkbutton')
74                self.auto_away_checkbutton = self.xml.get_widget('auto_away_checkbutton')
75                self.auto_away_time_spinbutton = self.xml.get_widget(
76                        'auto_away_time_spinbutton')
77                self.auto_away_message_entry = self.xml.get_widget(
78                        'auto_away_message_entry')
79                self.auto_xa_checkbutton = self.xml.get_widget('auto_xa_checkbutton')
80                self.auto_xa_time_spinbutton = self.xml.get_widget(
81                        'auto_xa_time_spinbutton')
82                self.auto_xa_message_entry = self.xml.get_widget('auto_xa_message_entry')
83                self.trayicon_checkbutton = self.xml.get_widget('trayicon_checkbutton')
84                self.notebook = self.xml.get_widget('preferences_notebook')
85                self.one_window_type_combobox =\
86                        self.xml.get_widget('one_window_type_combobox')
87
88                #trayicon
89                if gajim.interface.systray_capabilities:
90                        st = gajim.config.get('trayicon')
91                        self.trayicon_checkbutton.set_active(st)
92                else:
93                        self.trayicon_checkbutton.set_sensitive(False)
94
95                #Save position
96                st = gajim.config.get('saveposition')
97                self.xml.get_widget('save_position_checkbutton').set_active(st)
98
99                # Sort contacts by show
100                st = gajim.config.get('sort_by_show')
101                self.xml.get_widget('sort_by_show_checkbutton').set_active(st)
102
103                # Display avatars in roster
104                st = gajim.config.get('show_avatars_in_roster')
105                self.xml.get_widget('show_avatars_in_roster_checkbutton').set_active(st)
106
107                # Display status msg under contact name in roster
108                st = gajim.config.get('show_status_msgs_in_roster')
109                self.xml.get_widget('show_status_msgs_in_roster_checkbutton').set_active(
110                        st)
111
112                # emoticons
113                emoticons_combobox = self.xml.get_widget('emoticons_combobox')
114                emoticons_list = os.listdir(os.path.join(gajim.DATA_DIR, 'emoticons'))
115                # user themes
116                if os.path.isdir(gajim.MY_EMOTS_PATH):
117                        emoticons_list += os.listdir(gajim.MY_EMOTS_PATH)
118                renderer_text = gtk.CellRendererText()
119                emoticons_combobox.pack_start(renderer_text, True)
120                emoticons_combobox.add_attribute(renderer_text, 'text', 0)
121                model = gtk.ListStore(str)
122                emoticons_combobox.set_model(model)
123                l = []
124                for dir in emoticons_list:
125                        if dir != '.svn':
126                                l.append(dir)
127                l.append('Disabled')
128                for i in xrange(len(l)):
129                        model.append([l[i]])
130                        if gajim.config.get('emoticons_theme') == l[i]:
131                                emoticons_combobox.set_active(i)
132                if not gajim.config.get('emoticons_theme'):
133                        emoticons_combobox.set_active(len(l)-1)
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(0, 0)
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 xrange(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                # Set default for single window type
166                choices = common.config.opt_one_window_types
167                type = gajim.config.get('one_message_window')
168                if type in choices:
169                        self.one_window_type_combobox.set_active(choices.index(type))
170                else:
171                        self.one_window_type_combobox.set_active(0)
172
173                # Use transports iconsets
174                st = gajim.config.get('use_transports_iconsets')
175                self.xml.get_widget('transports_iconsets_checkbutton').set_active(st)
176
177                # Themes
178                theme_combobox = self.xml.get_widget('theme_combobox')
179                cell = gtk.CellRendererText()
180                theme_combobox.pack_start(cell, True)
181                theme_combobox.add_attribute(cell, 'text', 0)
182                model = gtk.ListStore(str)
183                theme_combobox.set_model(model)
184               
185                i = 0
186                for config_theme in gajim.config.get_per('themes'):
187                        theme = config_theme.replace('_', ' ')
188                        model.append([theme])
189                        if gajim.config.get('roster_theme') == config_theme:
190                                 theme_combobox.set_active(i)
191                        i += 1
192                self.on_theme_combobox_changed(theme_combobox)
193
194                #use speller
195                if os.name == 'nt':
196                        self.xml.get_widget('speller_checkbutton').set_no_show_all(True)
197                else:
198                        if HAS_GTK_SPELL:
199                                st = gajim.config.get('use_speller')
200                                self.xml.get_widget('speller_checkbutton').set_active(st)
201                        else:
202                                self.xml.get_widget('speller_checkbutton').set_sensitive(False)
203
204                #Print time
205                st = gajim.config.get('print_ichat_every_foo_minutes')
206                text = _('Every %s _minutes') % st
207                self.xml.get_widget('time_sometimes_radiobutton').set_label(text)
208
209                if gajim.config.get('print_time') == 'never':
210                        self.xml.get_widget('time_never_radiobutton').set_active(True)
211                        self._set_sensitivity_for_before_after_time_widgets(False)
212                elif gajim.config.get('print_time') == 'sometimes':
213                        self.xml.get_widget('time_sometimes_radiobutton').set_active(True)
214                        self._set_sensitivity_for_before_after_time_widgets(False)
215                else:
216                        self.xml.get_widget('time_always_radiobutton').set_active(True)
217
218                #before time
219                st = gajim.config.get('before_time')
220                self.xml.get_widget('before_time_entry').set_text(st)
221
222                #after time
223                st = gajim.config.get('after_time')
224                self.xml.get_widget('after_time_entry').set_text(st)
225
226                #before nickname
227                st = gajim.config.get('before_nickname')
228                self.xml.get_widget('before_nickname_entry').set_text(st)
229
230                #after nickanme
231                st = gajim.config.get('after_nickname')
232                self.xml.get_widget('after_nickname_entry').set_text(st)
233
234                #Color for incomming messages
235                colSt = gajim.config.get('inmsgcolor')
236                self.xml.get_widget('incoming_msg_colorbutton').set_color(
237                        gtk.gdk.color_parse(colSt))
238
239                #Color for outgoing messages
240                colSt = gajim.config.get('outmsgcolor')
241                self.xml.get_widget('outgoing_msg_colorbutton').set_color(
242                        gtk.gdk.color_parse(colSt))
243
244                #Color for status messages
245                colSt = gajim.config.get('statusmsgcolor')
246                self.xml.get_widget('status_msg_colorbutton').set_color(
247                        gtk.gdk.color_parse(colSt))
248               
249                #Color for hyperlinks
250                colSt = gajim.config.get('urlmsgcolor')
251                self.xml.get_widget('url_msg_colorbutton').set_color(
252                        gtk.gdk.color_parse(colSt))
253
254                #Font for messages
255                font = gajim.config.get('conversation_font')
256                # try to set default font for the current desktop env
257                if font == '':
258                        font = gtkgui_helpers.get_default_font()
259                        if font is None:
260                                font = 'Sans 10'
261                        gajim.config.set('conversation_font', font)
262                self.xml.get_widget('conversation_fontbutton').set_font_name(font)
263
264                # on new message
265                only_in_roster = True
266                if gajim.config.get('notify_on_new_message'):
267                        self.xml.get_widget('notify_on_new_message_radiobutton').set_active(
268                                True)
269                        only_in_roster = False
270                if gajim.config.get('autopopup'):
271                        self.xml.get_widget('popup_new_message_radiobutton').set_active(True)
272                        only_in_roster = False
273                if only_in_roster:
274                        self.xml.get_widget('only_in_roster_radiobutton').set_active(True)
275
276                #notify on online statuses
277                st = gajim.config.get('notify_on_signin')
278                self.notify_on_signin_checkbutton.set_active(st)
279
280                #notify on offline statuses
281                st = gajim.config.get('notify_on_signout')
282                self.notify_on_signout_checkbutton.set_active(st)
283
284                #autopopupaway
285                st = gajim.config.get('autopopupaway')
286                self.auto_popup_away_checkbutton.set_active(st)
287
288                #Ignore messages from unknown contacts
289                self.xml.get_widget('ignore_events_from_unknown_contacts_checkbutton').\
290                        set_active(gajim.config.get('ignore_unknown_contacts'))
291
292                # send chat state notifications
293                st = gajim.config.get('chat_state_notifications')
294                combo = self.xml.get_widget('chat_states_combobox')
295                if st == 'all':
296                        combo.set_active(0)
297                elif st == 'composing_only':
298                        combo.set_active(1)
299                else: # disabled
300                        combo.set_active(2)
301
302                #sounds
303                if os.name == 'nt': # if windows, player must not become visible on show_all
304                        soundplayer_hbox = self.xml.get_widget('soundplayer_hbox')
305                        soundplayer_hbox.set_no_show_all(True)
306                if gajim.config.get('sounds_on'):
307                        self.xml.get_widget('play_sounds_checkbutton').set_active(True)
308                else:
309                        self.xml.get_widget('soundplayer_hbox').set_sensitive(False)
310                        self.xml.get_widget('sounds_scrolledwindow').set_sensitive(False)
311                        self.xml.get_widget('browse_sounds_hbox').set_sensitive(False)
312
313                # sound player
314                player = gajim.config.get('soundplayer')
315                self.xml.get_widget('soundplayer_entry').set_text(player)
316                if player == '': # only on first time Gajim starts
317                        commands = ('aplay', 'play', 'esdplay', 'artsplay')
318                        for command in commands:
319                                if helpers.is_in_path(command):
320                                        self.xml.get_widget('soundplayer_entry').set_text(command)
321                                        gajim.config.set('soundplayer', command)
322                                        break
323
324                #sounds treeview
325                self.sound_tree = self.xml.get_widget('sounds_treeview')
326               
327                # active, event ui name, path to sound file, event_config_name
328                model = gtk.ListStore(bool, str, str, str)
329                self.sound_tree.set_model(model)
330
331                col = gtk.TreeViewColumn(_('Active'))
332                self.sound_tree.append_column(col)
333                renderer = gtk.CellRendererToggle()
334                renderer.set_property('activatable', True)
335                renderer.connect('toggled', self.sound_toggled_cb)
336                col.pack_start(renderer)
337                col.set_attributes(renderer, active = 0)
338
339                col = gtk.TreeViewColumn(_('Event'))
340                self.sound_tree.append_column(col)
341                renderer = gtk.CellRendererText()
342                col.pack_start(renderer)
343                col.set_attributes(renderer, text = 1)
344
345                self.fill_sound_treeview()
346
347                #Autoaway
348                st = gajim.config.get('autoaway')
349                self.auto_away_checkbutton.set_active(st)
350
351                #Autoawaytime
352                st = gajim.config.get('autoawaytime')
353                self.auto_away_time_spinbutton.set_value(st)
354                self.auto_away_time_spinbutton.set_sensitive(gajim.config.get('autoaway'))
355
356                #autoaway message
357                st = gajim.config.get('autoaway_message')
358                self.auto_away_message_entry.set_text(st)
359                self.auto_away_message_entry.set_sensitive(gajim.config.get('autoaway'))
360
361                #Autoxa
362                st = gajim.config.get('autoxa')
363                self.auto_xa_checkbutton.set_active(st)
364
365                #Autoxatime
366                st = gajim.config.get('autoxatime')
367                self.auto_xa_time_spinbutton.set_value(st)
368                self.auto_xa_time_spinbutton.set_sensitive(gajim.config.get('autoxa'))
369
370                #autoxa message
371                st = gajim.config.get('autoxa_message')
372                self.auto_xa_message_entry.set_text(st)
373                self.auto_xa_message_entry.set_sensitive(gajim.config.get('autoxa'))
374
375                #ask_status when online / offline
376                st = gajim.config.get('ask_online_status')
377                self.xml.get_widget('prompt_online_status_message_checkbutton').\
378                        set_active(st)
379                st = gajim.config.get('ask_offline_status')
380                self.xml.get_widget('prompt_offline_status_message_checkbutton').\
381                        set_active(st)
382
383                #Status messages
384                self.msg_tree = self.xml.get_widget('msg_treeview')
385                model = gtk.ListStore(str, str)
386                self.msg_tree.set_model(model)
387                col = gtk.TreeViewColumn('name')
388                self.msg_tree.append_column(col)
389                renderer = gtk.CellRendererText()
390                col.pack_start(renderer, True)
391                col.set_attributes(renderer, text = 0)
392                renderer.connect('edited', self.on_msg_cell_edited)
393                renderer.set_property('editable', True)
394                self.fill_msg_treeview()
395                buf = self.xml.get_widget('msg_textview').get_buffer()
396                buf.connect('changed', self.on_msg_textview_changed)
397
398                #open links with
399                if os.name == 'nt':
400                        applications_frame = self.xml.get_widget('applications_frame')
401                        applications_frame.set_no_show_all(True)
402                        applications_frame.hide()
403                else:
404                        self.applications_combobox = self.xml.get_widget(
405                                'applications_combobox')
406                        self.xml.get_widget('custom_apps_frame').hide()
407                        self.xml.get_widget('custom_apps_frame').set_no_show_all(True)
408                        if gajim.config.get('autodetect_browser_mailer'):
409                                self.applications_combobox.set_active(0)
410                                gtkgui_helpers.autodetect_browser_mailer()
411                        # autodetect_browser_mailer is now False.
412                        # so user has 'Always Use GNOME/KDE' or Custom
413                        elif gajim.config.get('openwith') == 'gnome-open':
414                                self.applications_combobox.set_active(1)
415                        elif gajim.config.get('openwith') == 'kfmclient exec':
416                                self.applications_combobox.set_active(2)
417                        elif gajim.config.get('openwith') == 'custom':
418                                self.applications_combobox.set_active(3)
419                                self.xml.get_widget('custom_apps_frame').show()
420                               
421                        self.xml.get_widget('custom_browser_entry').set_text(
422                                gajim.config.get('custombrowser'))
423                        self.xml.get_widget('custom_mail_client_entry').set_text(
424                                gajim.config.get('custommailapp'))
425                        self.xml.get_widget('custom_file_manager_entry').set_text(
426                                gajim.config.get('custom_file_manager'))
427
428                # log status changes of contacts
429                st = gajim.config.get('log_contact_status_changes')
430                self.xml.get_widget('log_show_changes_checkbutton').set_active(st)
431
432                # send os info
433                st = gajim.config.get('send_os_info')
434                self.xml.get_widget('send_os_info_checkbutton').set_active(st)
435               
436                # Notify user of new gmail e-mail messages,
437                # only show checkbox if user has a gtalk account
438                notify_gmail_checkbutton = self.xml.get_widget('notify_gmail_checkbutton')
439                notify_gmail_checkbutton.set_no_show_all(True)
440                for account in gajim.config.get_per('accounts'):
441                        jid = gajim.get_jid_from_account(account)
442                        if gajim.get_server_from_jid(jid) == 'gmail.com':
443                                st = gajim.config.get('notify_on_new_gmail_email')
444                                notify_gmail_checkbutton.set_active(st)
445                                notify_gmail_checkbutton.show()
446                                break
447                else:
448                        notify_gmail_checkbutton.hide()
449               
450                self.xml.signal_autoconnect(self)
451
452                self.sound_tree.get_model().connect('row-changed',
453                                        self.on_sounds_treemodel_row_changed)
454                self.msg_tree.get_model().connect('row-changed',
455                                        self.on_msg_treemodel_row_changed)
456                self.msg_tree.get_model().connect('row-deleted',
457                                        self.on_msg_treemodel_row_deleted)
458               
459                self.theme_preferences = None
460               
461                self.notebook.set_current_page(0)
462                self.window.show_all()
463
464        def on_preferences_window_key_press_event(self, widget, event):
465                if event.keyval == gtk.keysyms.Escape:
466                        self.window.hide()
467
468        def on_checkbutton_toggled(self, widget, config_name,
469                change_sensitivity_widgets = None):
470                gajim.config.set(config_name, widget.get_active())
471                if change_sensitivity_widgets:
472                        for w in change_sensitivity_widgets:
473                                w.set_sensitive(widget.get_active())
474                gajim.interface.save_config()
475
476        def on_trayicon_checkbutton_toggled(self, widget):
477                if widget.get_active():
478                        gajim.config.set('trayicon', True)
479                        gajim.interface.show_systray()
480                        show = helpers.get_global_show()
481                        gajim.interface.systray.change_status(show)
482                else:
483                        gajim.config.set('trayicon', False)
484                        gajim.interface.hide_systray()
485                        gajim.config.set('show_roster_on_startup', True) # no tray, show roster!
486                gajim.interface.roster.draw_roster()
487                gajim.interface.save_config()
488
489        def on_save_position_checkbutton_toggled(self, widget):
490                self.on_checkbutton_toggled(widget, 'saveposition')
491
492        def on_sort_by_show_checkbutton_toggled(self, widget):
493                self.on_checkbutton_toggled(widget, 'sort_by_show')
494                gajim.interface.roster.draw_roster()
495
496        def on_show_status_msgs_in_roster_checkbutton_toggled(self, widget):
497                self.on_checkbutton_toggled(widget, 'show_status_msgs_in_roster')
498                gajim.interface.roster.draw_roster()
499                for ctl in gajim.interface.msg_win_mgr.controls():
500                        if ctl.type_id == message_control.TYPE_GC:
501                                ctl.update_ui()
502
503        def on_show_avatars_in_roster_checkbutton_toggled(self, widget):
504                self.on_checkbutton_toggled(widget, 'show_avatars_in_roster')
505                gajim.interface.roster.draw_roster()
506
507        def on_emoticons_combobox_changed(self, widget):
508                active = widget.get_active()
509                model = widget.get_model()
510                emot_theme = model[active][0].decode('utf-8')
511                if emot_theme == _('Disabled'):
512                        gajim.config.set('emoticons_theme', '')
513                else:
514                        gajim.config.set('emoticons_theme', emot_theme)
515
516                gajim.interface.init_emoticons()
517                gajim.interface.make_regexps()
518                self.toggle_emoticons()
519
520        def toggle_emoticons(self):
521                '''Update emoticons state in Opened Chat Windows'''
522                for win in gajim.interface.msg_win_mgr.windows():
523                        win.toggle_emoticons()
524
525        def on_iconset_combobox_changed(self, widget):
526                model = widget.get_model()
527                active = widget.get_active()
528                icon_string = model[active][1].decode('utf-8')
529                gajim.config.set('iconset', icon_string)
530                gajim.interface.roster.reload_jabber_state_images()
531                gajim.interface.save_config()
532
533        def on_transports_iconsets_checkbutton_toggled(self, widget):
534                self.on_checkbutton_toggled(widget, 'use_transports_iconsets')
535                gajim.interface.roster.reload_jabber_state_images()
536
537        def on_manage_theme_button_clicked(self, widget):
538                if self.theme_preferences is None:
539                        self.theme_preferences = dialogs.GajimThemesWindow()
540                else:
541                        self.theme_preferences.window.present()
542
543        def on_theme_combobox_changed(self, widget):
544                model = widget.get_model()
545                active = widget.get_active()
546                config_theme = model[active][0].decode('utf-8').replace(' ', '_')
547
548                gajim.config.set('roster_theme', config_theme)
549
550                # begin repainting themed widgets throughout
551                gajim.interface.roster.repaint_themed_widgets()
552                gajim.interface.roster.change_roster_style(None)
553                gajim.interface.save_config()
554
555        def on_one_window_type_combo_changed(self, widget):
556                active = widget.get_active()
557                config_type = common.config.opt_one_window_types[active]
558                gajim.config.set('one_message_window', config_type)
559                gajim.interface.save_config()
560                gajim.interface.msg_win_mgr.reconfig()
561
562        def apply_speller(self):
563                for acct in gajim.connections:
564                        for ctrl in gajim.interface.msg_win_mgr.controls():
565                                if isinstance(ctrl, chat_control.ChatControlBase):
566                                        try:
567                                                spell_obj = gtkspell.get_from_text_view(ctrl.msg_textview)
568                                        except:
569                                                spell_obj = None
570
571                                        if not spell_obj:
572                                                gtkspell.Spell(ctrl.msg_textview)
573
574        def remove_speller(self):
575                for acct in gajim.connections:
576                        for ctrl in gajim.interface.msg_win_mgr.controls():
577                                if isinstance(ctrl, chat_control.ChatControlBase):
578                                        try:
579                                                spell_obj = gtkspell.get_from_text_view(ctrl.msg_textview)
580                                        except:
581                                                spell_obj = None
582                                        if spell_obj:
583                                                spell_obj.detach()
584
585