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

Revision 4818, 96.2 kB (checked in by asterix, 3 years ago)

we can add big smeileys

  • 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                #Font for messages
227                font = gajim.config.get('conversation_font')
228                # try to set default font for the current desktop env
229                if font == '':
230                        font = gtkgui_helpers.get_default_font()
231                        if font is None:
232                                font = 'Sans 10'
233                        gajim.config.set('conversation_font', font)
234                self.xml.get_widget('conversation_fontbutton').set_font_name(font)
235
236                # on new message
237                only_in_roster = True
238                if gajim.config.get('notify_on_new_message'):
239                        self.xml.get_widget('notify_on_new_message_radiobutton').set_active(
240                                True)
241                        only_in_roster = False
242                if gajim.config.get('autopopup'):
243                        self.xml.get_widget('popup_new_message_radiobutton').set_active(True)
244                        only_in_roster = False
245                if only_in_roster:
246                        self.xml.get_widget('only_in_roster_radiobutton').set_active(True)
247
248                #notify on online statuses
249                st = gajim.config.get('notify_on_signin')
250                self.notify_on_signin_checkbutton.set_active(st)
251
252                #notify on offline statuses
253                st = gajim.config.get('notify_on_signout')
254                self.notify_on_signout_checkbutton.set_active(st)
255
256                #autopopupaway
257                st = gajim.config.get('autopopupaway')
258                self.auto_popup_away_checkbutton.set_active(st)
259
260                #Ignore messages from unknown contacts
261                self.xml.get_widget('ignore_events_from_unknown_contacts_checkbutton').\
262                        set_active(gajim.config.get('ignore_unknown_contacts'))
263
264                # send chat state notifications
265                st = gajim.config.get('chat_state_notifications')
266                combo = self.xml.get_widget('chat_states_combobox')
267                if st == 'all':
268                        combo.set_active(0)
269                elif st == 'composing_only':
270                        combo.set_active(1)
271                else: # disabled
272                        combo.set_active(2)
273
274                #sounds
275                if os.name == 'nt': # if windows, player must not become visible on show_all
276                        soundplayer_hbox = self.xml.get_widget('soundplayer_hbox')
277                        soundplayer_hbox.set_no_show_all(True)
278                if gajim.config.get('sounds_on'):
279                        self.xml.get_widget('play_sounds_checkbutton').set_active(True)
280                else:
281                        self.xml.get_widget('soundplayer_hbox').set_sensitive(False)
282                        self.xml.get_widget('sounds_scrolledwindow').set_sensitive(False)
283                        self.xml.get_widget('browse_sounds_hbox').set_sensitive(False)
284
285                # sound player
286                player = gajim.config.get('soundplayer')
287                self.xml.get_widget('soundplayer_entry').set_text(player)
288                if player == '': # only on first time Gajim starts
289                        commands = ('aplay', 'play', 'esdplay', 'artsplay')
290                        for command in commands:
291                                if helpers.is_in_path(command):
292                                        self.xml.get_widget('soundplayer_entry').set_text(command)
293                                        gajim.config.set('soundplayer', command)
294                                        break
295
296                #sounds treeview
297                self.sound_tree = self.xml.get_widget('sounds_treeview')
298                model = gtk.ListStore(str,      bool, str)
299                self.sound_tree.set_model(model)
300
301                col = gtk.TreeViewColumn(_('Active'))
302                self.sound_tree.append_column(col)
303                renderer = gtk.CellRendererToggle()
304                renderer.set_property('activatable', True)
305                renderer.connect('toggled', self.sound_toggled_cb)
306                col.pack_start(renderer)
307                col.set_attributes(renderer, active = 1)
308
309                col = gtk.TreeViewColumn(_('Event'))
310                self.sound_tree.append_column(col)
311                renderer = gtk.CellRendererText()
312                col.pack_start(renderer)
313                col.set_attributes(renderer, text = 0)
314
315                col = gtk.TreeViewColumn(_('Sound'))
316                self.sound_tree.append_column(col)
317                renderer = gtk.CellRendererText()
318                col.pack_start(renderer)
319                col.set_attributes(renderer, text = 2)
320                self.fill_sound_treeview()
321
322                #Autoaway
323                st = gajim.config.get('autoaway')
324                self.auto_away_checkbutton.set_active(st)
325
326                #Autoawaytime
327                st = gajim.config.get('autoawaytime')
328                self.auto_away_time_spinbutton.set_value(st)
329                self.auto_away_time_spinbutton.set_sensitive(gajim.config.get('autoaway'))
330
331                #autoaway message
332                st = gajim.config.get('autoaway_message')
333                self.auto_away_message_entry.set_text(st)
334                self.auto_away_message_entry.set_sensitive(gajim.config.get('autoaway'))
335
336                #Autoxa
337                st = gajim.config.get('autoxa')
338                self.auto_xa_checkbutton.set_active(st)
339
340                #Autoxatime
341                st = gajim.config.get('autoxatime')
342                self.auto_xa_time_spinbutton.set_value(st)
343                self.auto_xa_time_spinbutton.set_sensitive(gajim.config.get('autoxa'))
344
345                #autoxa message
346                st = gajim.config.get('autoxa_message')
347                self.auto_xa_message_entry.set_text(st)
348                self.auto_xa_message_entry.set_sensitive(gajim.config.get('autoxa'))
349
350                #ask_status when online / offline
351                st = gajim.config.get('ask_online_status')
352                self.xml.get_widget('prompt_online_status_message_checkbutton').\
353                        set_active(st)
354                st = gajim.config.get('ask_offline_status')
355                self.xml.get_widget('prompt_offline_status_message_checkbutton').\
356                        set_active(st)
357
358                #Status messages
359                self.msg_tree = self.xml.get_widget('msg_treeview')
360                model = gtk.ListStore(str, str)
361                self.msg_tree.set_model(model)
362                col = gtk.TreeViewColumn('name')
363                self.msg_tree.append_column(col)
364                renderer = gtk.CellRendererText()
365                col.pack_start(renderer, True)
366                col.set_attributes(renderer, text = 0)
367                renderer.connect('edited', self.on_msg_cell_edited)
368                renderer.set_property('editable', True)
369                self.fill_msg_treeview()
370                buf = self.xml.get_widget('msg_textview').get_buffer()
371                buf.connect('changed', self.on_msg_textview_changed)
372
373                #open links with
374                if os.name == 'nt':
375                        self.applications_frame = self.xml.get_widget('applications_frame')
376                        self.applications_frame.set_no_show_all(True)
377                        self.applications_frame.hide()
378                else:
379                        self.applications_combobox = self.xml.get_widget(
380                                'applications_combobox')
381                        if gajim.config.get('autodetect_browser_mailer'):
382                                self.applications_combobox.set_active(0)
383                                gtkgui_helpers.autodetect_browser_mailer()
384                        # autodetect_browser_mailer is now False.
385                        # so user has 'Always Use GNOME/KDE' or Custom
386                        elif gajim.config.get('openwith') == 'gnome-open':
387                                self.applications_combobox.set_active(1)
388                        elif gajim.config.get('openwith') == 'kfmclient exec':
389                                self.applications_combobox.set_active(2)
390                        elif gajim.config.get('openwith') == 'custom':
391                                self.applications_combobox.set_active(3)
392                                self.xml.get_widget('custom_apps_frame').set_sensitive(True)
393                        self.xml.get_widget('custom_browser_entry').set_text(
394                                gajim.config.get('custombrowser'))
395                        self.xml.get_widget('custom_mail_client_entry').set_text(
396                                gajim.config.get('custommailapp'))
397                        self.xml.get_widget('custom_file_manager_entry').set_text(
398                                gajim.config.get('custom_file_manager'))
399
400                # log status changes of contacts
401                st = gajim.config.get('log_contact_status_changes')
402                self.xml.get_widget('log_show_changes_checkbutton').set_active(st)
403
404                # send os info
405                st = gajim.config.get('send_os_info')
406                self.xml.get_widget('send_os_info_checkbutton').set_active(st)
407
408                self.xml.signal_autoconnect(self)
409
410                self.sound_tree.get_model().connect('row-changed',
411                                        self.on_sounds_treemodel_row_changed)
412                self.msg_tree.get_model().connect('row-changed',
413                                        self.on_msg_treemodel_row_changed)
414                self.msg_tree.get_model().connect('row-deleted',
415                                        self.on_msg_treemodel_row_deleted)
416
417        def on_preferences_window_show(self, widget):
418                self.update_preferences_window()
419                self.notebook.set_current_page(0)
420
421        def update_preferences_window(self):
422                st = gajim.config.get('print_ichat_every_foo_minutes')
423                text = _('Every %s _minutes') % st
424                self.xml.get_widget('time_sometimes_radiobutton').set_label(text)
425
426                #Themes
427                theme_combobox = self.xml.get_widget('theme_combobox')
428                model = theme_combobox.get_model()
429                model.clear()
430                i = 0
431                for config_theme in gajim.config.get_per('themes'):
432                        theme = config_theme.replace('_', ' ')
433                        model.append([theme])
434                        if gajim.config.get('roster_theme') == config_theme:
435                                theme_combobox.set_active(i)
436                        i += 1
437                self.on_theme_combobox_changed(theme_combobox)
438                #FIXME: move code from __init__ here
439
440        def on_preferences_window_key_press_event(self, widget, event):
441                if event.keyval == gtk.keysyms.Escape:
442                        self.window.hide()
443
444        def on_checkbutton_toggled(self, widget, config_name,
445                change_sensitivity_widgets = None):
446                gajim.config.set(config_name, widget.get_active())
447                if change_sensitivity_widgets:
448                        for w in change_sensitivity_widgets:
449                                w.set_sensitive(widget.get_active())
450                gajim.interface.save_config()
451
452        def on_trayicon_checkbutton_toggled(self, widget):
453                if widget.get_active():
454                        gajim.config.set('trayicon', True)
455                        gajim.interface.show_systray()
456                else:
457                        gajim.config.set('trayicon', False)
458                        gajim.interface.hide_systray()
459                        gajim.config.set('show_roster_on_startup', True) # no tray, show roster!
460                gajim.interface.roster.draw_roster()
461                gajim.interface.save_config()
462
463        def on_save_position_checkbutton_toggled(self, widget):
464                self.on_checkbutton_toggled(widget, 'saveposition')
465
466        def on_sort_by_show_checkbutton_toggled(self, widget):
467                self.on_checkbutton_toggled(widget, 'sort_by_show')
468                gajim.interface.roster.draw_roster()
469
470        def on_show_status_msgs_in_roster_checkbutton_toggled(self, widget):
471                self.on_checkbutton_toggled(widget, 'show_status_msgs_in_roster')
472                gajim.interface.roster.draw_roster()
473                for account in gajim.connections:
474                        gcs = gajim.interface.instances[account]['gc']
475                        if gcs.has_key('tabbed'):
476                                gcs['tabbed'].draw_all_roster()
477                        else:
478                                for room_jid in gcs:
479                                        gcs[room_jid].draw_all_roster()
480
481        def on_show_avatars_in_roster_checkbutton_toggled(self, widget):
482                self.on_checkbutton_toggled(widget, 'show_avatars_in_roster')
483                gajim.interface.roster.draw_roster()
484
485        def on_use_emoticons_checkbutton_toggled(self, widget):
486                self.on_checkbutton_toggled(widget, 'useemoticons',
487                        [self.xml.get_widget('add_remove_emoticons_button')])
488                gajim.interface.init_emoticons()
489                gajim.interface.make_regexps()
490                self.toggle_emoticons()
491
492        def toggle_emoticons(self):
493                '''Update emoticons state in Opened Chat Windows'''
494                for a in gajim.connections:
495                        for kind in ('chats', 'gc'):
496                                windows = gajim.interface.instances[a][kind]
497                                if windows.has_key('tabbed'):
498                                        windows['tabbed'].toggle_emoticons()
499                                else:
500                                        for jid in windows.keys():
501                                                windows[jid].toggle_emoticons()
502
503        def on_add_remove_emoticons_button_clicked(self, widget):
504                if gajim.interface.instances.has_key('manage_emots'):
505                        gajim.interface.instances['manage_emots'].window.present()
506                else:
507                        gajim.interface.instances['manage_emots'] = ManageEmoticonsWindow()
508
509        def on_iconset_combobox_changed(self, widget):
510                model = widget.get_model()
511                active = widget.get_active()
512                icon_string = model[active][1].decode('utf-8')
513                gajim.config.set('iconset', icon_string)
514                gajim.interface.roster.reload_jabber_state_images()
515                gajim.interface.save_config()
516
517        def on_transports_iconsets_checkbutton_toggled(self, widget):
518                self.on_checkbutton_toggled(widget, 'use_transports_iconsets')
519                gajim.interface.roster.draw_roster()
520
521        def on_manage_theme_button_clicked(self, widget):
522                dialogs.GajimThemesWindow()
523
524        def on_theme_combobox_changed(self, widget):
525                model = widget.get_model()
526                active = widget.get_active()
527                config_theme = model[active][0].decode('utf-8').replace(' ', '_')
528
529                gajim.config.set('roster_theme', config_theme)
530
531                # begin repainting themed widgets throughout
532                gajim.interface.roster.repaint_themed_widgets()
533                gajim.interface.roster.change_roster_style(None)
534                gajim.interface.save_config()
535
536        def merge_windows(self, kind):
537                for acct in gajim.connections:
538                        # save buffers and close windows
539                        buf1 = {}
540                        buf2 = {}
541                        saved_var = {}
542                        windows = gajim.interface.instances[acct][kind]
543                        jids = windows.keys()
544                        for jid in jids:
545                                window = windows[jid]
546                                buf1[jid] = window.conversation_textviews[jid].get_buffer()
547                                buf2[jid] = window.message_textviews[jid].get_buffer()
548                                saved_var[jid] = window.save_var(jid)
549                                window.window.destroy()
550                        # open new tabbed chat windows
551                        for jid in jids:
552                                if kind == 'chats':
553                                        c = gajim.get_contact_instance_with_highest_priority(acct, jid)
554                                        gajim.interface.roster.new_chat(c, acct)
555                                if kind == 'gc':
556                                        gajim.interface.roster.new_room(jid, saved_var[jid]['nick'], acct)
557                                window = windows[jid]
558                                window.conversation_textviews[jid].set_buffer(buf1[jid])
559                                window.message_textviews[jid].set_buffer(buf2[jid])
560                                window.load_var(jid, saved_var[jid])
561
562        def split_windows(self, kind):
563                for acct in gajim.connections:
564                        # save buffers and close tabbed chat windows
565                        buf1 = {}
566                        buf2 = {}
567                        saved_var = {}
568                        windows = gajim.interface.instances[acct][kind]
569                        jids = windows.keys()
570                        if not 'tabbed' in jids:
571                                continue
572                        jids.remove('tabbed')
573                        for jid in jids:
574                                window = windows[jid]
575                                buf1[jid] = window.conversation_textviews[jid].get_buffer()
576                                buf2[jid] = window.message_textviews[jid].get_buffer()
577                                saved_var[jid] = window.save_var(jid)
578                        windows['tabbed'].window.destroy()
579                        # open new tabbed chat windows
580                        for jid in jids:
581                                if kind == 'chats':
582                                        c = gajim.get_contact_instance_with_highest_priority(acct, jid)
583                                        gajim.interface.roster.new_chat(c, acct)