4 ## Copyright (C) 2003-2005 Vincent Hanquez <tab AT snarc.org>
5 ## Copyright (C) 2003-2010 Yann Leboulanger <asterix AT lagaule.org>
6 ## Copyright (C) 2005 Alex Podaras <bigpod AT gmail.com>
7 ## Stéphan Kochen <stephan AT kochen.nl>
8 ## Copyright (C) 2005-2006 Dimitur Kirov <dkirov AT gmail.com>
9 ## Nikos Kouremenos <kourem AT gmail.com>
10 ## Copyright (C) 2006 Junglecow J <junglecow AT gmail.com>
11 ## Copyright (C) 2006-2007 Travis Shirk <travis AT pobox.com>
12 ## Stefan Bethge <stefan AT lanpartei.de>
13 ## Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
14 ## Copyright (C) 2007 James Newton <redshodan AT gmail.com>
15 ## Julien Pivotto <roidelapluie AT gmail.com>
16 ## Copyright (C) 2007-2008 Stephan Erb <steve-e AT h3c.de>
17 ## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
19 ## This file is part of Gajim.
21 ## Gajim is free software; you can redistribute it and/or modify
22 ## it under the terms of the GNU General Public License as published
23 ## by the Free Software Foundation; version 3 only.
25 ## Gajim is distributed in the hope that it will be useful,
26 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
27 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 ## GNU General Public License for more details.
30 ## You should have received a copy of the GNU General Public License
31 ## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
39 from common
.i18n
import Q_
43 import cell_renderer_image
44 import message_control
46 import dataforms_widget
54 from common
import helpers
55 from common
import gajim
56 from common
import connection
57 from common
import passwords
58 from common
.zeroconf
import connection_zeroconf
59 from common
import dataforms
60 from common
import gpg
61 from common
import ged
64 from common
.multimedia_helpers
import AudioInputManager
, AudioOutputManager
65 from common
.multimedia_helpers
import VideoInputManager
, VideoOutputManager
70 from common
.exceptions
import GajimGeneralException
72 #---------- PreferencesWindow class -------------#
73 class PreferencesWindow
:
75 Class for Preferences window
78 def on_preferences_window_destroy(self
, widget
):
82 del gajim
.interface
.instances
['preferences']
84 def on_close_button_clicked(self
, widget
):
89 Initialize Preferences window
91 self
.xml
= gtkgui_helpers
.get_gtk_builder('preferences_window.ui')
92 self
.window
= self
.xml
.get_object('preferences_window')
93 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
94 self
.notebook
= self
.xml
.get_object('preferences_notebook')
95 self
.one_window_type_combobox
=\
96 self
.xml
.get_object('one_window_type_combobox')
97 self
.iconset_combobox
= self
.xml
.get_object('iconset_combobox')
98 self
.notify_on_signin_checkbutton
= self
.xml
.get_object(
99 'notify_on_signin_checkbutton')
100 self
.notify_on_signout_checkbutton
= self
.xml
.get_object(
101 'notify_on_signout_checkbutton')
102 self
.auto_popup_away_checkbutton
= self
.xml
.get_object(
103 'auto_popup_away_checkbutton')
104 self
.sound_dnd_checkbutton
= self
.xml
.get_object('sound_dnd_checkbutton')
105 self
.auto_away_checkbutton
= self
.xml
.get_object('auto_away_checkbutton')
106 self
.auto_away_time_spinbutton
= self
.xml
.get_object(
107 'auto_away_time_spinbutton')
108 self
.auto_away_message_entry
= self
.xml
.get_object(
109 'auto_away_message_entry')
110 self
.auto_xa_checkbutton
= self
.xml
.get_object('auto_xa_checkbutton')
111 self
.auto_xa_time_spinbutton
= self
.xml
.get_object(
112 'auto_xa_time_spinbutton')
113 self
.auto_xa_message_entry
= self
.xml
.get_object('auto_xa_message_entry')
116 # Display avatars in roster
117 st
= gajim
.config
.get('show_avatars_in_roster')
118 self
.xml
.get_object('show_avatars_in_roster_checkbutton'). \
121 # Display status msg under contact name in roster
122 st
= gajim
.config
.get('show_status_msgs_in_roster')
123 self
.xml
.get_object('show_status_msgs_in_roster_checkbutton'). \
126 # Display mood in roster
127 st
= gajim
.config
.get('show_mood_in_roster')
128 self
.xml
.get_object('show_mood_in_roster_checkbutton'). \
131 # Display activity in roster
132 st
= gajim
.config
.get('show_activity_in_roster')
133 self
.xml
.get_object('show_activity_in_roster_checkbutton'). \
136 # Display tunes in roster
137 st
= gajim
.config
.get('show_tunes_in_roster')
138 self
.xml
.get_object('show_tunes_in_roster_checkbutton'). \
141 # Display location in roster
142 st
= gajim
.config
.get('show_location_in_roster')
143 self
.xml
.get_object('show_location_in_roster_checkbutton'). \
146 # Sort contacts by show
147 st
= gajim
.config
.get('sort_by_show_in_roster')
148 self
.xml
.get_object('sort_by_show_in_roster_checkbutton').set_active(st
)
149 st
= gajim
.config
.get('sort_by_show_in_muc')
150 self
.xml
.get_object('sort_by_show_in_muc_checkbutton').set_active(st
)
153 emoticons_combobox
= self
.xml
.get_object('emoticons_combobox')
154 emoticons_list
= os
.listdir(os
.path
.join(gajim
.DATA_DIR
, 'emoticons'))
156 if os
.path
.isdir(gajim
.MY_EMOTS_PATH
):
157 emoticons_list
+= os
.listdir(gajim
.MY_EMOTS_PATH
)
158 renderer_text
= gtk
.CellRendererText()
159 emoticons_combobox
.pack_start(renderer_text
, True)
160 emoticons_combobox
.add_attribute(renderer_text
, 'text', 0)
161 model
= gtk
.ListStore(str)
162 emoticons_combobox
.set_model(model
)
164 for dir_
in emoticons_list
:
165 if not os
.path
.isdir(os
.path
.join(gajim
.DATA_DIR
, 'emoticons', dir_
)) \
166 and not os
.path
.isdir(os
.path
.join(gajim
.MY_EMOTS_PATH
, dir_
)) :
170 l
.append(_('Disabled'))
171 for i
in xrange(len(l
)):
173 if gajim
.config
.get('emoticons_theme') == l
[i
]:
174 emoticons_combobox
.set_active(i
)
175 if not gajim
.config
.get('emoticons_theme'):
176 emoticons_combobox
.set_active(len(l
)-1)
178 # Set default for single window type
179 choices
= common
.config
.opt_one_window_types
180 type_
= gajim
.config
.get('one_message_window')
182 self
.one_window_type_combobox
.set_active(choices
.index(type_
))
184 self
.one_window_type_combobox
.set_active(0)
187 st
= gajim
.config
.get('compact_view')
188 self
.xml
.get_object('compact_view_checkbutton').set_active(st
)
191 st
= gajim
.config
.get('ignore_incoming_xhtml')
192 self
.xml
.get_object('xhtml_checkbutton').set_active(st
)
196 st
= gajim
.config
.get('use_speller')
197 self
.xml
.get_object('speller_checkbutton').set_active(st
)
199 self
.xml
.get_object('speller_checkbutton').set_sensitive(False)
203 theme_combobox
= self
.xml
.get_object('theme_combobox')
204 cell
= gtk
.CellRendererText()
205 theme_combobox
.pack_start(cell
, True)
206 theme_combobox
.add_attribute(cell
, 'text', 0)
207 self
.update_theme_list()
210 iconsets_list
= os
.listdir(os
.path
.join(gajim
.DATA_DIR
, 'iconsets'))
211 if os
.path
.isdir(gajim
.MY_ICONSETS_PATH
):
212 iconsets_list
+= os
.listdir(gajim
.MY_ICONSETS_PATH
)
213 # new model, image in 0, string in 1
214 model
= gtk
.ListStore(gtk
.Image
, str)
215 renderer_image
= cell_renderer_image
.CellRendererImage(0, 0)
216 renderer_text
= gtk
.CellRendererText()
217 renderer_text
.set_property('xpad', 5)
218 self
.iconset_combobox
.pack_start(renderer_image
, expand
= False)
219 self
.iconset_combobox
.pack_start(renderer_text
, expand
= True)
220 self
.iconset_combobox
.set_attributes(renderer_text
, text
= 1)
221 self
.iconset_combobox
.add_attribute(renderer_image
, 'image', 0)
222 self
.iconset_combobox
.set_model(model
)
224 for dir in iconsets_list
:
225 if not os
.path
.isdir(os
.path
.join(gajim
.DATA_DIR
, 'iconsets', dir)) \
226 and not os
.path
.isdir(os
.path
.join(gajim
.MY_ICONSETS_PATH
, dir)):
228 if dir != '.svn' and dir != 'transports':
232 for i
in xrange(len(l
)):
233 preview
= gtk
.Image()
235 files
.append(os
.path
.join(helpers
.get_iconset_path(l
[i
]), '16x16',
237 files
.append(os
.path
.join(helpers
.get_iconset_path(l
[i
]), '16x16',
240 if os
.path
.exists(file_
):
241 preview
.set_from_file(file_
)
242 model
.append([preview
, l
[i
]])
243 if gajim
.config
.get('iconset') == l
[i
]:
244 self
.iconset_combobox
.set_active(i
)
246 # Use transports iconsets
247 st
= gajim
.config
.get('use_transports_iconsets')
248 self
.xml
.get_object('transports_iconsets_checkbutton').set_active(st
)
251 self
.draw_color_widgets()
254 font
= gajim
.config
.get('conversation_font')
255 # try to set default font for the current desktop env
256 fontbutton
= self
.xml
.get_object('conversation_fontbutton')
258 fontbutton
.set_sensitive(False)
259 self
.xml
.get_object('default_chat_font').set_active(True)
261 fontbutton
.set_font_name(font
)
263 ### Personal Events tab ###
264 # outgoing send chat state notifications
265 st
= gajim
.config
.get('outgoing_chat_state_notifications')
266 combo
= self
.xml
.get_object('outgoing_chat_states_combobox')
269 elif st
== 'composing_only':
274 # displayed send chat state notifications
275 st
= gajim
.config
.get('displayed_chat_state_notifications')
276 combo
= self
.xml
.get_object('displayed_chat_states_combobox')
279 elif st
== 'composing_only':
285 ### Notifications tab ###
287 on_event_combobox
= self
.xml
.get_object('on_event_combobox')
288 if gajim
.config
.get('autopopup'):
289 on_event_combobox
.set_active(0)
290 elif gajim
.config
.get('notify_on_new_message'):
291 on_event_combobox
.set_active(1)
293 on_event_combobox
.set_active(2)
295 # notify on online statuses
296 st
= gajim
.config
.get('notify_on_signin')
297 self
.notify_on_signin_checkbutton
.set_active(st
)
299 # notify on offline statuses
300 st
= gajim
.config
.get('notify_on_signout')
301 self
.notify_on_signout_checkbutton
.set_active(st
)
304 st
= gajim
.config
.get('autopopupaway')
305 self
.auto_popup_away_checkbutton
.set_active(st
)
308 st
= gajim
.config
.get('sounddnd')
309 self
.sound_dnd_checkbutton
.set_active(st
)
312 systray_combobox
= self
.xml
.get_object('systray_combobox')
313 if gajim
.config
.get('trayicon') == 'never':
314 systray_combobox
.set_active(0)
315 elif gajim
.config
.get('trayicon') == 'on_event':
316 systray_combobox
.set_active(1)
318 systray_combobox
.set_active(2)
321 if gajim
.config
.get('sounds_on'):
322 self
.xml
.get_object('play_sounds_checkbutton').set_active(True)
324 self
.xml
.get_object('manage_sounds_button').set_sensitive(False)
326 # Notify user of new gmail e-mail messages,
327 # make checkbox sensitive if user has a gtalk account
328 frame_gmail
= self
.xml
.get_object('frame_gmail')
329 notify_gmail_checkbutton
= self
.xml
.get_object('notify_gmail_checkbutton')
330 notify_gmail_extra_checkbutton
= self
.xml
.get_object(
331 'notify_gmail_extra_checkbutton')
333 for account
in gajim
.config
.get_per('accounts'):
334 jid
= gajim
.get_jid_from_account(account
)
335 if gajim
.get_server_from_jid(jid
) in gajim
.gmail_domains
:
336 frame_gmail
.set_sensitive(True)
337 st
= gajim
.config
.get('notify_on_new_gmail_email')
338 notify_gmail_checkbutton
.set_active(st
)
339 st
= gajim
.config
.get('notify_on_new_gmail_email_extra')
340 notify_gmail_extra_checkbutton
.set_active(st
)
345 st
= gajim
.config
.get('autoaway')
346 self
.auto_away_checkbutton
.set_active(st
)
349 st
= gajim
.config
.get('autoawaytime')
350 self
.auto_away_time_spinbutton
.set_value(st
)
351 self
.auto_away_time_spinbutton
.set_sensitive(gajim
.config
.get('autoaway'))
354 st
= gajim
.config
.get('autoaway_message')
355 self
.auto_away_message_entry
.set_text(st
)
356 self
.auto_away_message_entry
.set_sensitive(gajim
.config
.get('autoaway'))
359 st
= gajim
.config
.get('autoxa')
360 self
.auto_xa_checkbutton
.set_active(st
)
363 st
= gajim
.config
.get('autoxatime')
364 self
.auto_xa_time_spinbutton
.set_value(st
)
365 self
.auto_xa_time_spinbutton
.set_sensitive(gajim
.config
.get('autoxa'))
368 st
= gajim
.config
.get('autoxa_message')
369 self
.auto_xa_message_entry
.set_text(st
)
370 self
.auto_xa_message_entry
.set_sensitive(gajim
.config
.get('autoxa'))
372 from common
import sleepy
373 if not sleepy
.SUPPORTED
:
374 self
.xml
.get_object('autoaway_table').set_sensitive(False)
376 # ask_status when online / offline
377 st
= gajim
.config
.get('ask_online_status')
378 self
.xml
.get_object('prompt_online_status_message_checkbutton').\
380 st
= gajim
.config
.get('ask_offline_status')
381 self
.xml
.get_object('prompt_offline_status_message_checkbutton').\
384 # Default Status messages
385 self
.default_msg_tree
= self
.xml
.get_object('default_msg_treeview')
386 col2
= self
.default_msg_tree
.rc_get_style().bg
[gtk
.STATE_ACTIVE
].\
388 # (status, translated_status, message, enabled)
389 model
= gtk
.ListStore(str, str, str, bool)
390 self
.default_msg_tree
.set_model(model
)
391 col
= gtk
.TreeViewColumn(_('Status'))
392 col
.set_resizable(True)
393 self
.default_msg_tree
.append_column(col
)
394 renderer
= gtk
.CellRendererText()
395 col
.pack_start(renderer
, False)
396 col
.set_attributes(renderer
, text
= 1)
397 col
= gtk
.TreeViewColumn(_('Default Message'))
398 col
.set_resizable(True)
399 self
.default_msg_tree
.append_column(col
)
400 renderer
= gtk
.CellRendererText()
401 col
.pack_start(renderer
, True)
402 col
.set_attributes(renderer
, text
= 2)
403 renderer
.connect('edited', self
.on_default_msg_cell_edited
)
404 renderer
.set_property('editable', True)
405 renderer
.set_property('cell-background', col2
)
406 col
= gtk
.TreeViewColumn(_('Enabled'))
407 col
.set_resizable(True)
408 self
.default_msg_tree
.append_column(col
)
409 renderer
= gtk
.CellRendererToggle()
410 col
.pack_start(renderer
, False)
411 col
.set_attributes(renderer
, active
= 3)
412 renderer
.set_property('activatable', True)
413 renderer
.connect('toggled', self
.default_msg_toggled_cb
)
414 self
.fill_default_msg_treeview()
417 self
.msg_tree
= self
.xml
.get_object('msg_treeview')
418 model
= gtk
.ListStore(str, str, str, str, str, str, str)
419 self
.msg_tree
.set_model(model
)
420 col
= gtk
.TreeViewColumn('name')
421 self
.msg_tree
.append_column(col
)
422 renderer
= gtk
.CellRendererText()
423 col
.pack_start(renderer
, True)
424 col
.set_attributes(renderer
, text
= 0)
425 renderer
.connect('edited', self
.on_msg_cell_edited
)
426 renderer
.set_property('editable', True)
427 self
.fill_msg_treeview()
428 buf
= self
.xml
.get_object('msg_textview').get_buffer()
429 buf
.connect('changed', self
.on_msg_textview_changed
)
431 ### Audio / Video tab ###
432 def create_av_combobox(opt_name
, device_dict
, config_name
=None,
434 combobox
= self
.xml
.get_object(opt_name
+ '_combobox')
435 cell
= gtk
.CellRendererText()
436 combobox
.pack_start(cell
, True)
437 combobox
.add_attribute(cell
, 'text', 0)
438 model
= gtk
.ListStore(str, str)
439 combobox
.set_model(model
)
441 config
= gajim
.config
.get(config_name
)
443 config
= gajim
.config
.get(opt_name
+ '_device')
445 for index
, (name
, value
) in enumerate(sorted(device_dict
.\
446 iteritems(), key
=key
)):
447 model
.append((name
, value
))
449 combobox
.set_active(index
)
452 create_av_combobox('audio_input', AudioInputManager().get_devices())
453 create_av_combobox('audio_output', AudioOutputManager().get_devices(
455 create_av_combobox('video_input', VideoInputManager().get_devices())
456 create_av_combobox('video_output', VideoOutputManager().get_devices(
459 create_av_combobox('video_framerate', {_('Default'): '',
460 '15fps': '15/1', '10fps': '10/1', '5fps': '5/1',
461 '2.5fps': '5/2'}, 'video_framerate', key
=lambda x
: -1 if \
462 not x
[1] else float(x
[0][:-3]))
463 create_av_combobox('video_size', {_('Default'): '',
464 '800x600': '800x600', '640x480': '640x480',
465 '320x240': '320x240'}, 'video_size', key
=lambda x
: -1 if \
466 not x
[1] else int(x
[0][:3]))
469 for opt_name
in ('audio_input', 'audio_output', 'video_input',
470 'video_output', 'video_framerate', 'video_size'):
471 combobox
= self
.xml
.get_object(opt_name
+ '_combobox')
472 combobox
.set_sensitive(False)
475 cb
= self
.xml
.get_object('stun_checkbutton')
476 st
= gajim
.config
.get('use_stun_server')
479 entry
= self
.xml
.get_object('stun_server_entry')
480 entry
.set_text(gajim
.config
.get('stun_server'))
482 entry
.set_sensitive(False)
487 applications_frame
= self
.xml
.get_object('applications_frame')
488 applications_frame
.set_no_show_all(True)
489 applications_frame
.hide()
491 self
.applications_combobox
= self
.xml
.get_object(
492 'applications_combobox')
493 self
.xml
.get_object('custom_apps_frame').hide()
494 self
.xml
.get_object('custom_apps_frame').set_no_show_all(True)
496 if gajim
.config
.get('autodetect_browser_mailer'):
497 self
.applications_combobox
.set_active(0)
498 # else autodetect_browser_mailer is False.
499 # so user has 'Always Use GNOME/KDE/Xfce' or Custom
500 elif gajim
.config
.get('openwith') == 'custom':
501 self
.applications_combobox
.set_active(1)
502 self
.xml
.get_object('custom_apps_frame').show()
504 self
.xml
.get_object('custom_browser_entry').set_text(
505 gajim
.config
.get('custombrowser'))
506 self
.xml
.get_object('custom_mail_client_entry').set_text(
507 gajim
.config
.get('custommailapp'))
508 self
.xml
.get_object('custom_file_manager_entry').set_text(
509 gajim
.config
.get('custom_file_manager'))
511 # log status changes of contacts
512 st
= gajim
.config
.get('log_contact_status_changes')
513 self
.xml
.get_object('log_show_changes_checkbutton').set_active(st
)
515 # log encrypted chat sessions
516 w
= self
.xml
.get_object('log_encrypted_chats_checkbutton')
517 st
= self
.get_per_account_option('log_encrypted_sessions')
519 w
.set_inconsistent(True)
524 w
= self
.xml
.get_object('send_os_info_checkbutton')
525 st
= self
.get_per_account_option('send_os_info')
527 w
.set_inconsistent(True)
532 w
= self
.xml
.get_object('send_idle_time_checkbutton')
533 st
= self
.get_per_account_option('send_idle_time')
535 w
.set_inconsistent(True)
539 # check if gajm is default
540 st
= gajim
.config
.get('check_if_gajim_is_default')
541 self
.xml
.get_object('check_default_client_checkbutton').set_active(st
)
543 # Ignore messages from unknown contacts
544 w
= self
.xml
.get_object('ignore_events_from_unknown_contacts_checkbutton')
545 st
= self
.get_per_account_option('ignore_unknown_contacts')
547 w
.set_inconsistent(True)
551 self
.xml
.connect_signals(self
)
553 self
.msg_tree
.get_model().connect('row-changed',
554 self
.on_msg_treemodel_row_changed
)
555 self
.msg_tree
.get_model().connect('row-deleted',
556 self
.on_msg_treemodel_row_deleted
)
557 self
.default_msg_tree
.get_model().connect('row-changed',
558 self
.on_default_msg_treemodel_row_changed
)
560 self
.theme_preferences
= None
561 self
.sounds_preferences
= None
563 self
.notebook
.set_current_page(0)
565 self
.window
.show_all()
566 gtkgui_helpers
.possibly_move_window_in_current_desktop(self
.window
)
568 def on_preferences_window_key_press_event(self
, widget
, event
):
569 if event
.keyval
== gtk
.keysyms
.Escape
:
572 def get_per_account_option(self
, opt
):
574 Return the value of the option opt if it's the same in all accounts else
577 if len(gajim
.connections
) == 0:
578 # a non existant key return default value
579 return gajim
.config
.get_per('accounts', '__default__', opt
)
581 for account
in gajim
.connections
:
582 v
= gajim
.config
.get_per('accounts', account
, opt
)
589 def on_checkbutton_toggled(self
, widget
, config_name
,
590 change_sensitivity_widgets
=None):
591 gajim
.config
.set(config_name
, widget
.get_active())
592 if change_sensitivity_widgets
:
593 for w
in change_sensitivity_widgets
:
594 w
.set_sensitive(widget
.get_active())
595 gajim
.interface
.save_config()
597 def on_per_account_checkbutton_toggled(self
, widget
, config_name
,
598 change_sensitivity_widgets
=None):
599 for account
in gajim
.connections
:
600 gajim
.config
.set_per('accounts', account
, config_name
,
602 if change_sensitivity_widgets
:
603 for w
in change_sensitivity_widgets
:
604 w
.set_sensitive(widget
.get_active())
605 gajim
.interface
.save_config()
607 def _get_all_controls(self
):
608 for ctrl
in gajim
.interface
.msg_win_mgr
.get_controls():
610 for account
in gajim
.connections
:
611 for ctrl
in gajim
.interface
.minimized_controls
[account
].values():
614 def _get_all_muc_controls(self
):
615 for ctrl
in gajim
.interface
.msg_win_mgr
.get_controls(
616 message_control
.TYPE_GC
):
618 for account
in gajim
.connections
:
619 for ctrl
in gajim
.interface
.minimized_controls
[account
].values():
622 def on_sort_by_show_in_roster_checkbutton_toggled(self
, widget
):
623 self
.on_checkbutton_toggled(widget
, 'sort_by_show_in_roster')
624 gajim
.interface
.roster
.setup_and_draw_roster()
626 def on_sort_by_show_in_muc_checkbutton_toggled(self
, widget
):
627 self
.on_checkbutton_toggled(widget
, 'sort_by_show_in_muc')
629 for ctrl
in self
._get
_all
_muc
_controls
():
632 def on_show_avatars_in_roster_checkbutton_toggled(self
, widget
):
633 self
.on_checkbutton_toggled(widget
, 'show_avatars_in_roster')
634 gajim
.interface
.roster
.setup_and_draw_roster()
635 # Redraw groupchats (in an ugly way)
636 for ctrl
in self
._get
_all
_muc
_controls
():
639 def on_show_status_msgs_in_roster_checkbutton_toggled(self
, widget
):
640 self
.on_checkbutton_toggled(widget
, 'show_status_msgs_in_roster')
641 gajim
.interface
.roster
.setup_and_draw_roster()
642 for ctrl
in self
._get
_all
_muc
_controls
():
645 def on_show_mood_in_roster_checkbutton_toggled(self
, widget
):
646 self
.on_checkbutton_toggled(widget
, 'show_mood_in_roster')
647 gajim
.interface
.roster
.setup_and_draw_roster()
649 def on_show_activity_in_roster_checkbutton_toggled(self
, widget
):
650 self
.on_checkbutton_toggled(widget
, 'show_activity_in_roster')
651 gajim
.interface
.roster
.setup_and_draw_roster()
653 def on_show_tunes_in_roster_checkbutton_toggled(self
, widget
):
654 self
.on_checkbutton_toggled(widget
, 'show_tunes_in_roster')
655 gajim
.interface
.roster
.setup_and_draw_roster()
657 def on_show_location_in_roster_checkbutton_toggled(self
, widget
):
658 self
.on_checkbutton_toggled(widget
, 'show_location_in_roster')
659 gajim
.interface
.roster
.setup_and_draw_roster()
661 def on_emoticons_combobox_changed(self
, widget
):
662 active
= widget
.get_active()
663 model
= widget
.get_model()
664 emot_theme
= model
[active
][0].decode('utf-8')
665 if emot_theme
== _('Disabled'):
666 gajim
.config
.set('emoticons_theme', '')
668 gajim
.config
.set('emoticons_theme', emot_theme
)
670 gajim
.interface
.init_emoticons(need_reload
= True)
671 gajim
.interface
.make_regexps()
672 self
.toggle_emoticons()
674 def toggle_emoticons(self
):
676 Update emoticons state in Opened Chat Windows
678 for ctrl
in self
._get
_all
_controls
():
679 ctrl
.toggle_emoticons()
681 def on_one_window_type_combo_changed(self
, widget
):
682 active
= widget
.get_active()
683 config_type
= common
.config
.opt_one_window_types
[active
]
684 gajim
.config
.set('one_message_window', config_type
)
685 gajim
.interface
.save_config()
686 gajim
.interface
.msg_win_mgr
.reconfig()
688 def on_compact_view_checkbutton_toggled(self
, widget
):
689 active
= widget
.get_active()
690 for ctrl
in self
._get
_all
_controls
():
691 ctrl
.chat_buttons_set_visible(active
)
692 gajim
.config
.set('compact_view', active
)
693 gajim
.interface
.save_config()
695 def on_xhtml_checkbutton_toggled(self
, widget
):
696 self
.on_checkbutton_toggled(widget
, 'ignore_incoming_xhtml')
697 helpers
.update_optional_features()
699 def apply_speller(self
):
700 for ctrl
in self
._get
_all
_controls
():
701 if isinstance(ctrl
, chat_control
.ChatControlBase
):
703 spell_obj
= gtkspell
.get_from_text_view(ctrl
.msg_textview
)
704 except (TypeError, RuntimeError, OSError):
710 def remove_speller(self
):
711 for ctrl
in self
._get
_all
_controls
():
712 if isinstance(ctrl
, chat_control
.ChatControlBase
):
714 spell_obj
= gtkspell
.get_from_text_view(ctrl
.msg_textview
)
715 except (TypeError, RuntimeError):
720 def on_speller_checkbutton_toggled(self
, widget
):
721 active
= widget
.get_active()
722 gajim
.config
.set('use_speller', active
)
723 gajim
.interface
.save_config()
725 lang
= gajim
.config
.get('speller_language')
730 gtkspell
.Spell(tv
, lang
)
731 except (TypeError, RuntimeError, OSError):
733 _('Dictionary for lang %s not available') % lang
,
734 _('You have to install %s dictionary to use spellchecking, or '
735 'choose another language by setting the speller_language option.'
737 gajim
.config
.set('use_speller', False)
738 widget
.set_active(False)
740 gajim
.config
.set('speller_language', lang
)
743 self
.remove_speller()
745 def on_theme_combobox_changed(self
, widget
):
746 model
= widget
.get_model()
747 active
= widget
.get_active()
748 config_theme
= model
[active
][0].decode('utf-8').replace(' ', '_')
750 gajim
.config
.set('roster_theme', config_theme
)
752 # begin repainting themed widgets throughout
753 gajim
.interface
.roster
.repaint_themed_widgets()
754 gajim
.interface
.roster
.change_roster_style(None)
755 gajim
.interface
.save_config()
757 def update_theme_list(self
):
758 theme_combobox
= self
.xml
.get_object('theme_combobox')
759 model
= gtk
.ListStore(str)
760 theme_combobox
.set_model(model
)
762 for config_theme
in gajim
.config
.get_per('themes'):
763 theme
= config_theme
.replace('_', ' ')
764 model
.append([theme
])
765 if gajim
.config
.get('roster_theme') == config_theme
:
766 theme_combobox
.set_active(i
)
769 def on_manage_theme_button_clicked(self
, widget
):
770 if self
.theme_preferences
is None:
771 self
.theme_preferences
= dialogs
.GajimThemesWindow()
773 self
.theme_preferences
.window
.present()
774 self
.theme_preferences
.select_active_theme()
776 def on_iconset_combobox_changed(self
, widget
):
777 model
= widget
.get_model()
778 active
= widget
.get_active()
779 icon_string
= model
[active
][1].decode('utf-8')
780 gajim
.config
.set('iconset', icon_string
)
781 gtkgui_helpers
.reload_jabber_state_images()
782 gajim
.interface
.save_config()
784 def on_transports_iconsets_checkbutton_toggled(self
, widget
):
785 self
.on_checkbutton_toggled(widget
, 'use_transports_iconsets')
786 gtkgui_helpers
.reload_jabber_state_images()
788 def on_outgoing_chat_states_combobox_changed(self
, widget
):
789 active
= widget
.get_active()
790 old_value
= gajim
.config
.get('outgoing_chat_state_notifications')
791 if active
== 0: # all
792 gajim
.config
.set('outgoing_chat_state_notifications', 'all')
793 elif active
== 1: # only composing
794 gajim
.config
.set('outgoing_chat_state_notifications', 'composing_only')
796 gajim
.config
.set('outgoing_chat_state_notifications', 'disabled')
797 new_value
= gajim
.config
.get('outgoing_chat_state_notifications')
798 if 'disabled' in (old_value
, new_value
):
799 # we changed from disabled to sth else or vice versa
800 helpers
.update_optional_features()
802 def on_displayed_chat_states_combobox_changed(self
, widget
):
803 active
= widget
.get_active()
804 if active
== 0: # all
805 gajim
.config
.set('displayed_chat_state_notifications', 'all')
806 elif active
== 1: # only composing
807 gajim
.config
.set('displayed_chat_state_notifications',
810 gajim
.config
.set('displayed_chat_state_notifications', 'disabled')
812 def on_ignore_events_from_unknown_contacts_checkbutton_toggled(self
, widget
):
813 widget
.set_inconsistent(False)
814 self
.on_per_account_checkbutton_toggled(widget
, 'ignore_unknown_contacts')
816 def on_on_event_combobox_changed(self
, widget
):
817 active
= widget
.get_active()
819 gajim
.config
.set('autopopup', True)
820 gajim
.config
.set('notify_on_new_message', False)
822 gajim
.config
.set('autopopup', False)
823 gajim
.config
.set('notify_on_new_message', True)
825 gajim
.config
.set('autopopup', False)
826 gajim
.config
.set('notify_on_new_message', False)
828 def on_notify_on_signin_checkbutton_toggled(self
, widget
):
829 self
.on_checkbutton_toggled(widget
, 'notify_on_signin')
831 def on_notify_on_signout_checkbutton_toggled(self
, widget
):
832 self
.on_checkbutton_toggled(widget
, 'notify_on_signout')
834 def on_auto_popup_away_checkbutton_toggled(self
, widget
):
835 self
.on_checkbutton_toggled(widget
, 'autopopupaway')
837 def on_sound_dnd_checkbutton_toggled(self
, widget
):
838 self
.on_checkbutton_toggled(widget
, 'sounddnd')
840 def on_systray_combobox_changed(self
, widget
):
841 active
= widget
.get_active()
843 gajim
.config
.set('trayicon', 'never')
844 gajim
.interface
.systray_enabled
= False
845 gajim
.interface
.systray
.hide_icon()
847 gajim
.config
.set('trayicon', 'on_event')
848 gajim
.interface
.systray_enabled
= True
849 gajim
.interface
.systray
.show_icon()
851 gajim
.config
.set('trayicon', 'always')
852 gajim
.interface
.systray_enabled
= True
853 gajim
.interface
.systray
.show_icon()
855 def on_advanced_notifications_button_clicked(self
, widget
):
856 dialogs
.AdvancedNotificationsWindow()
858 def on_play_sounds_checkbutton_toggled(self
, widget
):
859 self
.on_checkbutton_toggled(widget
, 'sounds_on',
860 [self
.xml
.get_object('manage_sounds_button')])
862 def on_manage_sounds_button_clicked(self
, widget
):
863 if self
.sounds_preferences
is None:
864 self
.sounds_preferences
= ManageSoundsWindow()
866 self
.sounds_preferences
.window
.present()
868 def update_text_tags(self
):
870 Update color tags in opened chat windows
872 for ctrl
in self
._get
_all
_controls
():
875 def on_preference_widget_color_set(self
, widget
, text
):
876 color
= widget
.get_color()
877 color_string
= gtkgui_helpers
.make_color_string(color
)
878 gajim
.config
.set(text
, color_string
)
879 self
.update_text_tags()
880 gajim
.interface
.save_config()
882 def on_preference_widget_font_set(self
, widget
, text
):
884 font
= widget
.get_font_name()
887 gajim
.config
.set(text
, font
)
888 self
.update_text_font()
889 gajim
.interface
.save_config()
891 def update_text_font(self
):
893 Update text font in opened chat windows
895 for ctrl
in self
._get
_all
_controls
():
898 def on_incoming_nick_colorbutton_color_set(self
, widget
):
899 self
.on_preference_widget_color_set(widget
, 'inmsgcolor')
901 def on_outgoing_nick_colorbutton_color_set(self
, widget
):
902 self
.on_preference_widget_color_set(widget
, 'outmsgcolor')
904 def on_incoming_msg_colorbutton_color_set(self
, widget
):
905 self
.on_preference_widget_color_set(widget
, 'inmsgtxtcolor')
907 def on_outgoing_msg_colorbutton_color_set(self
, widget
):
908 self
.on_preference_widget_color_set(widget
, 'outmsgtxtcolor')
910 def on_url_msg_colorbutton_color_set(self
, widget
):
911 self
.on_preference_widget_color_set(widget
, 'urlmsgcolor')
913 def on_status_msg_colorbutton_color_set(self
, widget
):
914 self
.on_preference_widget_color_set(widget
, 'statusmsgcolor')
916 def on_conversation_fontbutton_font_set(self
, widget
):
917 self
.on_preference_widget_font_set(widget
, 'conversation_font')
919 def on_default_chat_font_toggled(self
, widget
):
920 font_widget
= self
.xml
.get_object('conversation_fontbutton')
921 if widget
.get_active():
922 font_widget
.set_sensitive(False)
925 font_widget
.set_sensitive(True)
926 self
.on_preference_widget_font_set(font_widget
, 'conversation_font')
928 def draw_color_widgets(self
):
929 col_to_widget
= {'inmsgcolor': 'incoming_nick_colorbutton',
930 'outmsgcolor': 'outgoing_nick_colorbutton',
931 'inmsgtxtcolor': ['incoming_msg_colorbutton',
932 'incoming_msg_checkbutton'],
933 'outmsgtxtcolor': ['outgoing_msg_colorbutton',
934 'outgoing_msg_checkbutton'],
935 'statusmsgcolor': 'status_msg_colorbutton',
936 'urlmsgcolor': 'url_msg_colorbutton'}
937 for c
in col_to_widget
:
938 col
= gajim
.config
.get(c
)
940 if isinstance(col_to_widget
[c
], list):
941 self
.xml
.get_object(col_to_widget
[c
][0]).set_color(
942 gtk
.gdk
.color_parse(col
))
943 self
.xml
.get_object(col_to_widget
[c
][0]).set_sensitive(True)
944 self
.xml
.get_object(col_to_widget
[c
][1]).set_active(True)
946 self
.xml
.get_object(col_to_widget
[c
]).set_color(
947 gtk
.gdk
.color_parse(col
))
949 if isinstance(col_to_widget
[c
], list):
950 self
.xml
.get_object(col_to_widget
[c
][0]).set_color(
951 gtk
.gdk
.color_parse('#000000'))
952 self
.xml
.get_object(col_to_widget
[c
][0]).set_sensitive(False)
953 self
.xml
.get_object(col_to_widget
[c
][1]).set_active(False)
955 self
.xml
.get_object(col_to_widget
[c
]).set_color(
956 gtk
.gdk
.color_parse('#000000'))
958 def on_reset_colors_button_clicked(self
, widget
):
959 col_to_widget
= {'inmsgcolor': 'incoming_nick_colorbutton',
960 'outmsgcolor': 'outgoing_nick_colorbutton',
961 'inmsgtxtcolor': 'incoming_msg_colorbutton',
962 'outmsgtxtcolor': 'outgoing_msg_colorbutton',
963 'statusmsgcolor': 'status_msg_colorbutton',
964 'urlmsgcolor': 'url_msg_colorbutton'}
965 for c
in col_to_widget
:
966 gajim
.config
.set(c
, gajim
.interface
.default_colors
[c
])
967 self
.draw_color_widgets()
969 self
.update_text_tags()
970 gajim
.interface
.save_config()
972 def _set_color(self
, state
, widget_name
, option
):
974 Set color value in prefs and update the UI
977 color
= self
.xml
.get_object(widget_name
).get_color()
978 color_string
= gtkgui_helpers
.make_color_string(color
)
981 gajim
.config
.set(option
, color_string
)
982 gajim
.interface
.save_config()
984 def on_incoming_msg_checkbutton_toggled(self
, widget
):
985 state
= widget
.get_active()
986 self
.xml
.get_object('incoming_msg_colorbutton').set_sensitive(state
)
987 self
._set
_color
(state
, 'incoming_msg_colorbutton', 'inmsgtxtcolor')
989 def on_outgoing_msg_checkbutton_toggled(self
, widget
):
990 state
= widget
.get_active()
991 self
.xml
.get_object('outgoing_msg_colorbutton').set_sensitive(state
)
992 self
._set
_color
(state
, 'outgoing_msg_colorbutton', 'outmsgtxtcolor')
994 def on_auto_away_checkbutton_toggled(self
, widget
):
995 self
.on_checkbutton_toggled(widget
, 'autoaway',
996 [self
.auto_away_time_spinbutton
, self
.auto_away_message_entry
])
998 def on_auto_away_time_spinbutton_value_changed(self
, widget
):
999 aat
= widget
.get_value_as_int()
1000 gajim
.config
.set('autoawaytime', aat
)
1001 gajim
.interface
.sleeper
= common
.sleepy
.Sleepy(
1002 gajim
.config
.get('autoawaytime') * 60,
1003 gajim
.config
.get('autoxatime') * 60)
1004 gajim
.interface
.save_config()
1006 def on_auto_away_message_entry_changed(self
, widget
):
1007 gajim
.config
.set('autoaway_message', widget
.get_text().decode('utf-8'))
1009 def on_auto_xa_checkbutton_toggled(self
, widget
):
1010 self
.on_checkbutton_toggled(widget
, 'autoxa',
1011 [self
.auto_xa_time_spinbutton
, self
.auto_xa_message_entry
])
1013 def on_auto_xa_time_spinbutton_value_changed(self
, widget
):
1014 axt
= widget
.get_value_as_int()
1015 gajim
.config
.set('autoxatime', axt
)
1016 gajim
.interface
.sleeper
= common
.sleepy
.Sleepy(
1017 gajim
.config
.get('autoawaytime') * 60,
1018 gajim
.config
.get('autoxatime') * 60)
1019 gajim
.interface
.save_config()
1021 def on_auto_xa_message_entry_changed(self
, widget
):
1022 gajim
.config
.set('autoxa_message', widget
.get_text().decode('utf-8'))
1024 def on_prompt_online_status_message_checkbutton_toggled(self
, widget
):
1025 self
.on_checkbutton_toggled(widget
, 'ask_online_status')
1027 def on_prompt_offline_status_message_checkbutton_toggled(self
, widget
):
1028 self
.on_checkbutton_toggled(widget
, 'ask_offline_status')
1030 def fill_default_msg_treeview(self
):
1031 model
= self
.default_msg_tree
.get_model()
1034 for status_
in gajim
.config
.get_per('defaultstatusmsg'):
1035 status
.append(status_
)
1037 for status_
in status
:
1038 msg
= gajim
.config
.get_per('defaultstatusmsg', status_
, 'message')
1039 msg
= helpers
.from_one_line(msg
)
1040 enabled
= gajim
.config
.get_per('defaultstatusmsg', status_
, 'enabled')
1041 iter_
= model
.append()
1042 uf_show
= helpers
.get_uf_show(status_
)
1043 model
.set(iter_
, 0, status_
, 1, uf_show
, 2, msg
, 3, enabled
)
1045 def on_default_msg_cell_edited(self
, cell
, row
, new_text
):
1046 model
= self
.default_msg_tree
.get_model()
1047 iter_
= model
.get_iter_from_string(row
)
1048 model
.set_value(iter_
, 2, new_text
)
1050 def default_msg_toggled_cb(self
, cell
, path
):
1051 model
= self
.default_msg_tree
.get_model()
1052 model
[path
][3] = not model
[path
][3]
1054 def on_default_msg_treemodel_row_changed(self
, model
, path
, iter_
):
1055 status
= model
[iter_
][0]
1056 message
= model
[iter_
][2].decode('utf-8')
1057 message
= helpers
.to_one_line(message
)
1058 gajim
.config
.set_per('defaultstatusmsg', status
, 'enabled',
1060 gajim
.config
.set_per('defaultstatusmsg', status
, 'message', message
)
1062 def on_default_status_expander_activate(self
, expander
):
1063 eventbox
= self
.xml
.get_object('default_status_eventbox')
1064 vbox
= self
.xml
.get_object('status_vbox')
1065 vbox
.set_child_packing(eventbox
, not expander
.get_expanded(), True, 0,
1068 def save_status_messages(self
, model
):
1069 for msg
in gajim
.config
.get_per('statusmsg'):
1070 gajim
.config
.del_per('statusmsg', msg
)
1071 iter_
= model
.get_iter_first()
1073 val
= model
[iter_
][0].decode('utf-8')
1074 if model
[iter_
][1]: # we have a preset message
1075 if not val
: # no title, use message text for title
1076 val
= model
[iter_
][1]
1077 gajim
.config
.add_per('statusmsg', val
)
1078 msg
= helpers
.to_one_line(model
[iter_
][1].decode('utf-8'))
1079 gajim
.config
.set_per('statusmsg', val
, 'message', msg
)
1081 # store mood / activity
1082 for subname
in ('activity', 'subactivity', 'activity_text',
1083 'mood', 'mood_text'):
1084 gajim
.config
.set_per('statusmsg', val
, subname
,
1085 model
[iter_
][i
].decode('utf-8'))
1087 iter_
= model
.iter_next(iter_
)
1088 gajim
.interface
.save_config()
1090 def on_msg_treemodel_row_changed(self
, model
, path
, iter_
):
1091 self
.save_status_messages(model
)
1093 def on_msg_treemodel_row_deleted(self
, model
, path
):
1094 self
.save_status_messages(model
)
1096 def on_av_combobox_changed(self
, combobox
, config_name
):
1097 model
= combobox
.get_model()
1098 active
= combobox
.get_active()
1099 device
= model
[active
][1].decode('utf-8')
1100 gajim
.config
.set(config_name
, device
)
1102 def on_audio_input_combobox_changed(self
, widget
):
1103 self
.on_av_combobox_changed(widget
, 'audio_input_device')
1105 def on_audio_output_combobox_changed(self
, widget
):
1106 self
.on_av_combobox_changed(widget
, 'audio_output_device')
1108 def on_video_input_combobox_changed(self
, widget
):
1109 self
.on_av_combobox_changed(widget
, 'video_input_device')
1111 def on_video_output_combobox_changed(self
, widget
):
1112 self
.on_av_combobox_changed(widget
, 'video_output_device')
1114 def on_video_framerate_combobox_changed(self
, widget
):
1115 self
.on_av_combobox_changed(widget
, 'video_framerate')
1117 def on_video_size_combobox_changed(self
, widget
):
1118 self
.on_av_combobox_changed(widget
, 'video_size')
1120 def on_stun_checkbutton_toggled(self
, widget
):
1121 self
.on_checkbutton_toggled(widget
, 'use_stun_server',
1122 [self
.xml
.get_object('stun_server_entry')])
1124 def stun_server_entry_changed(self
, widget
):
1125 gajim
.config
.set('stun_server', widget
.get_text().decode('utf-8'))
1127 def on_applications_combobox_changed(self
, widget
):
1128 if widget
.get_active() == 0:
1129 gajim
.config
.set('autodetect_browser_mailer', True)
1130 self
.xml
.get_object('custom_apps_frame').hide()
1131 elif widget
.get_active() == 1:
1132 gajim
.config
.set('autodetect_browser_mailer', False)
1133 self
.xml
.get_object('custom_apps_frame').show()
1134 gajim
.config
.set('openwith', 'custom')
1135 gajim
.interface
.save_config()
1137 def on_custom_browser_entry_changed(self
, widget
):
1138 gajim
.config
.set('custombrowser', widget
.get_text().decode('utf-8'))
1139 gajim
.interface
.save_config()
1141 def on_custom_mail_client_entry_changed(self
, widget
):
1142 gajim
.config
.set('custommailapp', widget
.get_text().decode('utf-8'))
1143 gajim
.interface
.save_config()
1145 def on_custom_file_manager_entry_changed(self
, widget
):
1146 gajim
.config
.set('custom_file_manager', widget
.get_text().decode('utf-8'))
1147 gajim
.interface
.save_config()
1149 def on_log_show_changes_checkbutton_toggled(self
, widget
):
1150 self
.on_checkbutton_toggled(widget
, 'log_contact_status_changes')
1152 def on_log_encrypted_chats_checkbutton_toggled(self
, widget
):
1153 widget
.set_inconsistent(False)
1154 self
.on_per_account_checkbutton_toggled(widget
, 'log_encrypted_sessions')
1156 def on_send_os_info_checkbutton_toggled(self
, widget
):
1157 widget
.set_inconsistent(False)
1158 self
.on_per_account_checkbutton_toggled(widget
, 'send_os_info')
1160 def on_send_idle_time_checkbutton_toggled(self
, widget
):
1161 widget
.set_inconsistent(False)
1162 self
.on_per_account_checkbutton_toggled(widget
, 'send_idle_time')
1164 def on_check_default_client_checkbutton_toggled(self
, widget
):
1165 self
.on_checkbutton_toggled(widget
, 'check_if_gajim_is_default')
1167 def on_notify_gmail_checkbutton_toggled(self
, widget
):
1168 self
.on_checkbutton_toggled(widget
, 'notify_on_new_gmail_email')
1170 def on_notify_gmail_extra_checkbutton_toggled(self
, widget
):
1171 self
.on_checkbutton_toggled(widget
, 'notify_on_new_gmail_email_extra')
1173 def fill_msg_treeview(self
):
1174 self
.xml
.get_object('delete_msg_button').set_sensitive(False)
1175 model
= self
.msg_tree
.get_model()
1178 for msg_name
in gajim
.config
.get_per('statusmsg'):
1179 if msg_name
.startswith('_last_'):
1181 preset_status
.append(msg_name
)
1182 preset_status
.sort()
1183 for msg_name
in preset_status
:
1184 msg_text
= gajim
.config
.get_per('statusmsg', msg_name
, 'message')
1185 msg_text
= helpers
.from_one_line(msg_text
)
1186 activity
= gajim
.config
.get_per('statusmsg', msg_name
, 'activity')
1187 subactivity
= gajim
.config
.get_per('statusmsg', msg_name
,
1189 activity_text
= gajim
.config
.get_per('statusmsg', msg_name
,
1191 mood
= gajim
.config
.get_per('statusmsg', msg_name
, 'mood')
1192 mood_text
= gajim
.config
.get_per('statusmsg', msg_name
, 'mood_text')
1193 iter_
= model
.append()
1194 model
.set(iter_
, 0, msg_name
, 1, msg_text
, 2, activity
, 3,
1195 subactivity
, 4, activity_text
, 5, mood
, 6, mood_text
)
1197 def on_msg_cell_edited(self
, cell
, row
, new_text
):
1198 model
= self
.msg_tree
.get_model()
1199 iter_
= model
.get_iter_from_string(row
)
1200 model
.set_value(iter_
, 0, new_text
)
1202 def on_msg_treeview_cursor_changed(self
, widget
, data
= None):
1203 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1206 self
.xml
.get_object('delete_msg_button').set_sensitive(True)
1207 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1208 msg
= model
[iter_
][1]
1211 def on_new_msg_button_clicked(self
, widget
, data
= None):
1212 model
= self
.msg_tree
.get_model()
1213 iter_
= model
.append()
1214 model
.set(iter_
, 0, _('status message title'), 1, _('status message text'))
1215 self
.msg_tree
.set_cursor(model
.get_path(iter_
))
1217 def on_delete_msg_button_clicked(self
, widget
, data
= None):
1218 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1221 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1224 self
.xml
.get_object('delete_msg_button').set_sensitive(False)
1226 def on_msg_textview_changed(self
, widget
, data
= None):
1227 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1230 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1231 first_iter
, end_iter
= buf
.get_bounds()
1232 model
.set_value(iter_
, 1, buf
.get_text(first_iter
, end_iter
))
1234 def on_msg_treeview_key_press_event(self
, widget
, event
):
1235 if event
.keyval
== gtk
.keysyms
.Delete
:
1236 self
.on_delete_msg_button_clicked(widget
)
1238 def on_open_advanced_editor_button_clicked(self
, widget
, data
= None):
1239 if 'advanced_config' in gajim
.interface
.instances
:
1240 gajim
.interface
.instances
['advanced_config'].window
.present()
1242 gajim
.interface
.instances
['advanced_config'] = \
1243 dialogs
.AdvancedConfigurationWindow()
1245 #---------- ManageProxiesWindow class -------------#
1246 class ManageProxiesWindow
:
1248 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_proxies_window.ui')
1249 self
.window
= self
.xml
.get_object('manage_proxies_window')
1250 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
1251 self
.proxies_treeview
= self
.xml
.get_object('proxies_treeview')
1252 self
.proxyname_entry
= self
.xml
.get_object('proxyname_entry')
1253 self
.proxytype_combobox
= self
.xml
.get_object('proxytype_combobox')
1256 self
.block_signal
= False
1257 self
.xml
.connect_signals(self
)
1258 self
.window
.show_all()
1259 # hide the BOSH fields by default
1260 self
.show_bosh_fields()
1262 def show_bosh_fields(self
, show
=True):
1264 self
.xml
.get_object('boshuri_entry').show()
1265 self
.xml
.get_object('boshuri_label').show()
1266 self
.xml
.get_object('boshuseproxy_checkbutton').show()
1268 cb
= self
.xml
.get_object('boshuseproxy_checkbutton')
1271 self
.on_boshuseproxy_checkbutton_toggled(cb
)
1272 self
.xml
.get_object('boshuri_entry').hide()
1273 self
.xml
.get_object('boshuri_label').hide()
1276 def fill_proxies_treeview(self
):
1277 model
= self
.proxies_treeview
.get_model()
1279 iter_
= model
.append()
1280 model
.set(iter_
, 0, _('None'))
1281 for p
in gajim
.config
.get_per('proxies'):
1282 iter_
= model
.append()
1283 model
.set(iter_
, 0, p
)
1285 def init_list(self
):
1286 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1287 self
.proxytype_combobox
.set_sensitive(False)
1288 self
.xml
.get_object('proxy_table').set_sensitive(False)
1289 model
= gtk
.ListStore(str)
1290 self
.proxies_treeview
.set_model(model
)
1291 col
= gtk
.TreeViewColumn('Proxies')
1292 self
.proxies_treeview
.append_column(col
)
1293 renderer
= gtk
.CellRendererText()
1294 col
.pack_start(renderer
, True)
1295 col
.set_attributes(renderer
, text
= 0)
1296 self
.fill_proxies_treeview()
1297 self
.xml
.get_object('proxytype_combobox').set_active(0)
1299 def on_manage_proxies_window_destroy(self
, widget
):
1300 if 'accounts' in gajim
.interface
.instances
:
1301 gajim
.interface
.instances
['accounts'].\
1303 del gajim
.interface
.instances
['manage_proxies']
1305 def on_add_proxy_button_clicked(self
, widget
):
1306 model
= self
.proxies_treeview
.get_model()
1307 proxies
= gajim
.config
.get_per('proxies')
1309 while ('proxy' + unicode(i
)) in proxies
:
1311 iter_
= model
.append()
1312 model
.set(iter_
, 0, 'proxy' + unicode(i
))
1313 gajim
.config
.add_per('proxies', 'proxy' + unicode(i
))
1314 self
.proxies_treeview
.set_cursor(model
.get_path(iter_
))
1316 def on_remove_proxy_button_clicked(self
, widget
):
1317 (model
, iter_
) = self
.proxies_treeview
.get_selection().get_selected()
1320 proxy
= model
[iter_
][0].decode('utf-8')
1322 gajim
.config
.del_per('proxies', proxy
)
1323 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1324 self
.block_signal
= True
1325 self
.on_proxies_treeview_cursor_changed(self
.proxies_treeview
)
1326 self
.block_signal
= False
1328 def on_close_button_clicked(self
, widget
):
1329 self
.window
.destroy()
1331 def on_useauth_checkbutton_toggled(self
, widget
):
1332 if self
.block_signal
:
1334 act
= widget
.get_active()
1335 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1336 gajim
.config
.set_per('proxies', proxy
, 'useauth', act
)
1337 self
.xml
.get_object('proxyuser_entry').set_sensitive(act
)
1338 self
.xml
.get_object('proxypass_entry').set_sensitive(act
)
1340 def on_boshuseproxy_checkbutton_toggled(self
, widget
):
1341 if self
.block_signal
:
1343 act
= widget
.get_active()
1344 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1345 gajim
.config
.set_per('proxies', proxy
, 'bosh_useproxy', act
)
1346 self
.xml
.get_object('proxyhost_entry').set_sensitive(act
)
1347 self
.xml
.get_object('proxyport_entry').set_sensitive(act
)
1349 def on_proxies_treeview_cursor_changed(self
, widget
):
1350 #FIXME: check if off proxy settings are correct (see
1351 # http://trac.gajim.org/changeset/1921#file2 line 1221
1352 proxyhost_entry
= self
.xml
.get_object('proxyhost_entry')
1353 proxyport_entry
= self
.xml
.get_object('proxyport_entry')
1354 proxyuser_entry
= self
.xml
.get_object('proxyuser_entry')
1355 proxypass_entry
= self
.xml
.get_object('proxypass_entry')
1356 boshuri_entry
= self
.xml
.get_object('boshuri_entry')
1357 useauth_checkbutton
= self
.xml
.get_object('useauth_checkbutton')
1358 boshuseproxy_checkbutton
= self
.xml
.get_object('boshuseproxy_checkbutton')
1359 self
.block_signal
= True
1360 proxyhost_entry
.set_text('')
1361 proxyport_entry
.set_text('')
1362 proxyuser_entry
.set_text('')
1363 proxypass_entry
.set_text('')
1364 boshuri_entry
.set_text('')
1366 #boshuseproxy_checkbutton.set_active(False)
1367 #self.on_boshuseproxy_checkbutton_toggled(boshuseproxy_checkbutton)
1369 #useauth_checkbutton.set_active(False)
1370 #self.on_useauth_checkbutton_toggled(useauth_checkbutton)
1372 (model
, iter_
) = widget
.get_selection().get_selected()
1374 self
.xml
.get_object('proxyname_entry').set_text('')
1375 self
.xml
.get_object('proxytype_combobox').set_sensitive(False)
1376 self
.xml
.get_object('proxy_table').set_sensitive(False)
1377 self
.block_signal
= False
1380 proxy
= model
[iter_
][0]
1381 self
.xml
.get_object('proxyname_entry').set_text(proxy
)
1383 if proxy
== _('None'): # special proxy None
1384 self
.show_bosh_fields(False)
1385 self
.proxyname_entry
.set_editable(False)
1386 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1387 self
.xml
.get_object('proxytype_combobox').set_sensitive(False)
1388 self
.xml
.get_object('proxy_table').set_sensitive(False)
1390 proxytype
= gajim
.config
.get_per('proxies', proxy
, 'type')
1392 self
.show_bosh_fields(proxytype
=='bosh')
1394 self
.proxyname_entry
.set_editable(True)
1395 self
.xml
.get_object('remove_proxy_button').set_sensitive(True)
1396 self
.xml
.get_object('proxytype_combobox').set_sensitive(True)
1397 self
.xml
.get_object('proxy_table').set_sensitive(True)
1398 proxyhost_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1400 proxyport_entry
.set_text(unicode(gajim
.config
.get_per('proxies',
1402 proxyuser_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1404 proxypass_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1406 boshuri_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1408 types
= ['http', 'socks5', 'bosh']
1409 self
.proxytype_combobox
.set_active(types
.index(proxytype
))
1410 boshuseproxy_checkbutton
.set_active(
1411 gajim
.config
.get_per('proxies', proxy
, 'bosh_useproxy'))
1412 useauth_checkbutton
.set_active(
1413 gajim
.config
.get_per('proxies', proxy
, 'useauth'))
1414 self
.block_signal
= False
1416 def on_proxies_treeview_key_press_event(self
, widget
, event
):
1417 if event
.keyval
== gtk
.keysyms
.Delete
:
1418 self
.on_remove_proxy_button_clicked(widget
)
1420 def on_proxyname_entry_changed(self
, widget
):
1421 if self
.block_signal
:
1423 (model
, iter_
) = self
.proxies_treeview
.get_selection().get_selected()
1426 old_name
= model
.get_value(iter_
, 0).decode('utf-8')
1427 new_name
= widget
.get_text().decode('utf-8')
1430 if new_name
== old_name
:
1432 config
= gajim
.config
.get_per('proxies', old_name
)
1433 gajim
.config
.del_per('proxies', old_name
)
1434 gajim
.config
.add_per('proxies', new_name
)
1435 for option
in config
:
1436 gajim
.config
.set_per('proxies', new_name
, option
,
1437 config
[option
][common
.config
.OPT_VAL
])
1438 model
.set_value(iter_
, 0, new_name
)
1440 def on_proxytype_combobox_changed(self
, widget
):
1441 if self
.block_signal
:
1443 types
= ['http', 'socks5', 'bosh']
1444 type_
= self
.proxytype_combobox
.get_active()
1445 self
.show_bosh_fields(types
[type_
]=='bosh')
1446 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1447 gajim
.config
.set_per('proxies', proxy
, 'type', types
[type_
])
1449 def on_proxyhost_entry_changed(self
, widget
):
1450 if self
.block_signal
:
1452 value
= widget
.get_text().decode('utf-8')
1453 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1454 gajim
.config
.set_per('proxies', proxy
, 'host', value
)
1456 def on_proxyport_entry_changed(self
, widget
):
1457 if self
.block_signal
:
1459 value
= widget
.get_text().decode('utf-8')
1460 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1461 gajim
.config
.set_per('proxies', proxy
, 'port', value
)
1463 def on_proxyuser_entry_changed(self
, widget
):
1464 if self
.block_signal
:
1466 value
= widget
.get_text().decode('utf-8')
1467 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1468 gajim
.config
.set_per('proxies', proxy
, 'user', value
)
1470 def on_boshuri_entry_changed(self
, widget
):
1471 if self
.block_signal
:
1473 value
= widget
.get_text().decode('utf-8')
1474 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1475 gajim
.config
.set_per('proxies', proxy
, 'bosh_uri', value
)
1477 def on_proxypass_entry_changed(self
, widget
):
1478 if self
.block_signal
:
1480 value
= widget
.get_text().decode('utf-8')
1481 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1482 gajim
.config
.set_per('proxies', proxy
, 'pass', value
)
1485 #---------- AccountsWindow class -------------#
1486 class AccountsWindow
:
1488 Class for accounts window: list of accounts
1491 def on_accounts_window_destroy(self
, widget
):
1492 del gajim
.interface
.instances
['accounts']
1494 def on_close_button_clicked(self
, widget
):
1495 self
.check_resend_relog()
1496 self
.window
.destroy()
1499 self
.xml
= gtkgui_helpers
.get_gtk_builder('accounts_window.ui')
1500 self
.window
= self
.xml
.get_object('accounts_window')
1501 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
1502 self
.accounts_treeview
= self
.xml
.get_object('accounts_treeview')
1503 self
.remove_button
= self
.xml
.get_object('remove_button')
1504 self
.rename_button
= self
.xml
.get_object('rename_button')
1505 path_to_kbd_input_img
= gtkgui_helpers
.get_icon_path('gajim-kbd_input')
1506 img
= self
.xml
.get_object('rename_image')
1507 img
.set_from_file(path_to_kbd_input_img
)
1508 self
.notebook
= self
.xml
.get_object('notebook')
1510 model
= gtk
.ListStore(str)
1511 self
.accounts_treeview
.set_model(model
)
1513 renderer
= gtk
.CellRendererText()
1514 self
.accounts_treeview
.insert_column_with_attributes(-1, _('Name'),
1517 self
.current_account
= None
1518 # When we fill info, we don't want to handle the changed signals
1519 self
.ignore_events
= False
1520 self
.need_relogin
= False
1521 self
.resend_presence
= False
1523 self
.update_proxy_list()
1524 self
.xml
.connect_signals(self
)
1525 self
.init_accounts()
1526 self
.window
.show_all()
1529 st
= gajim
.config
.get('mergeaccounts')
1530 checkbutton
= self
.xml
.get_object('merge_checkbutton')
1531 checkbutton
.set_active(st
)
1532 # prevent roster redraws by connecting the signal after button state is
1534 checkbutton
.connect('toggled', self
.on_merge_checkbutton_toggled
)
1536 self
.avahi_available
= True
1540 self
.avahi_available
= False
1542 def on_accounts_window_key_press_event(self
, widget
, event
):
1543 if event
.keyval
== gtk
.keysyms
.Escape
:
1544 self
.check_resend_relog()
1545 self
.window
.destroy()
1547 def select_account(self
, account
):
1548 model
= self
.accounts_treeview
.get_model()
1549 iter_
= model
.get_iter_root()
1551 acct
= model
[iter_
][0].decode('utf-8')
1553 self
.accounts_treeview
.set_cursor(model
.get_path(iter_
))
1555 iter_
= model
.iter_next(iter_
)
1557 def init_accounts(self
):
1559 Initialize listStore with existing accounts
1561 self
.remove_button
.set_sensitive(False)
1562 self
.rename_button
.set_sensitive(False)
1563 self
.current_account
= None
1564 model
= self
.accounts_treeview
.get_model()
1566 for account
in gajim
.config
.get_per('accounts'):
1567 iter_
= model
.append()
1568 model
.set(iter_
, 0, account
)
1570 def resend(self
, account
):
1571 if not account
in gajim
.connections
:
1573 show
= gajim
.SHOW_LIST
[gajim
.connections
[account
].connected
]
1574 status
= gajim
.connections
[account
].status
1575 gajim
.connections
[account
].change_status(show
, status
)
1577 def check_resend_relog(self
):
1578 if self
.need_relogin
and self
.current_account
== gajim
.ZEROCONF_ACC_NAME
:
1579 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
:
1580 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].update_details()
1583 elif self
.need_relogin
and self
.current_account
and \
1584 gajim
.connections
[self
.current_account
].connected
> 0:
1585 def login(account
, show_before
, status_before
):
1587 Login with previous status
1589 # first make sure connection is really closed,
1590 # 0.5 may not be enough
1591 gajim
.connections
[account
].disconnect(True)
1592 gajim
.interface
.roster
.send_status(account
, show_before
,
1596 self
.dialog
.destroy()
1597 show_before
= gajim
.SHOW_LIST
[gajim
.connections
[account
].connected
]
1598 status_before
= gajim
.connections
[account
].status
1599 gajim
.interface
.roster
.send_status(account
, 'offline',
1600 _('Be right back.'))
1601 gobject
.timeout_add(500, login
, account
, show_before
, status_before
)
1603 def on_yes(checked
, account
):
1606 if self
.resend_presence
:
1607 self
.resend(account
)
1608 if self
.current_account
in gajim
.connections
:
1609 self
.dialog
= dialogs
.YesNoDialog(_('Relogin now?'),
1610 _('If you want all the changes to apply instantly, '
1611 'you must relogin.'), on_response_yes
=(on_yes
,
1612 self
.current_account
), on_response_no
=(on_no
,
1613 self
.current_account
))
1614 elif self
.resend_presence
:
1615 self
.resend(self
.current_account
)
1617 self
.need_relogin
= False
1618 self
.resend_presence
= False
1620 def on_accounts_treeview_cursor_changed(self
, widget
):
1622 Activate modify buttons when a row is selected, update accounts info
1624 sel
= self
.accounts_treeview
.get_selection()
1625 (model
, iter_
) = sel
.get_selected()
1627 account
= model
[iter_
][0].decode('utf-8')
1630 if self
.current_account
and self
.current_account
== account
:
1631 # We're comming back to our current account, no need to update widgets
1633 # Save config for previous account if needed cause focus_out event is
1634 # called after the changed event
1635 if self
.current_account
and self
.window
.get_focus():
1636 focused_widget
= self
.window
.get_focus()
1637 focused_widget_name
= focused_widget
.get_name()
1638 if focused_widget_name
in ('jid_entry1', 'resource_entry1',
1639 'custom_port_entry', 'cert_entry1'):
1640 if focused_widget_name
== 'jid_entry1':
1641 func
= self
.on_jid_entry1_focus_out_event
1642 elif focused_widget_name
== 'resource_entry1':
1643 func
= self
.on_resource_entry1_focus_out_event
1644 elif focused_widget_name
== 'custom_port_entry':
1645 func
= self
.on_custom_port_entry_focus_out_event
1646 elif focused_widget_name
== 'cert_entry1':
1647 func
= self
.on_cert_entry1_focus_out_event
1648 if func(focused_widget
, None):
1649 # Error detected in entry, don't change account, re-put cursor on
1651 self
.select_account(self
.current_account
)
1653 self
.window
.set_focus(widget
)
1655 self
.check_resend_relog()
1658 self
.remove_button
.set_sensitive(True)
1659 self
.rename_button
.set_sensitive(True)
1661 self
.remove_button
.set_sensitive(False)
1662 self
.rename_button
.set_sensitive(False)
1664 self
.current_account
= account
1665 if account
== gajim
.ZEROCONF_ACC_NAME
:
1666 self
.remove_button
.set_sensitive(False)
1668 self
.update_proxy_list()
1670 def on_browse_for_client_cert_button_clicked(self
, widget
, data
=None):
1671 def on_ok(widget
, path_to_clientcert_file
):
1672 self
.dialog
.destroy()
1673 if not path_to_clientcert_file
:
1675 self
.xml
.get_object('cert_entry1').set_text(path_to_clientcert_file
)
1676 gajim
.config
.set_per('accounts', self
.current_account
,
1677 'client_cert', path_to_clientcert_file
)
1679 def on_cancel(widget
):
1680 self
.dialog
.destroy()
1682 path_to_clientcert_file
= self
.xml
.get_object('cert_entry1').get_text()
1683 self
.dialog
= dialogs
.ClientCertChooserDialog(path_to_clientcert_file
,
1686 def update_proxy_list(self
):
1687 if self
.current_account
:
1688 our_proxy
= gajim
.config
.get_per('accounts', self
.current_account
,
1694 our_proxy
= _('None')
1695 proxy_combobox
= self
.xml
.get_object('proxies_combobox1')
1696 model
= gtk
.ListStore(str)
1697 proxy_combobox
.set_model(model
)
1698 l
= gajim
.config
.get_per('proxies')
1699 l
.insert(0, _('None'))
1700 for i
in xrange(len(l
)):
1701 model
.append([l
[i
]])
1702 if our_proxy
== l
[i
]:
1703 proxy_combobox
.set_active(i
)
1705 def init_account(self
):
1706 if not self
.current_account
:
1707 self
.notebook
.set_current_page(0)
1709 if gajim
.config
.get_per('accounts', self
.current_account
, 'is_zeroconf'):
1710 self
.ignore_events
= True
1711 self
.init_zeroconf_account()
1712 self
.ignore_events
= False
1713 self
.notebook
.set_current_page(2)
1715 self
.ignore_events
= True
1716 self
.init_normal_account()
1717 self
.ignore_events
= False
1718 self
.notebook
.set_current_page(1)
1720 def init_zeroconf_account(self
):
1721 active
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1723 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_active(active
)
1724 if not gajim
.HAVE_ZEROCONF
:
1725 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_sensitive(
1727 self
.xml
.get_object('zeroconf_notebook').set_sensitive(active
)
1729 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1731 self
.xml
.get_object('autoconnect_checkbutton2').set_active(st
)
1733 list_no_log_for
= gajim
.config
.get_per('accounts',
1734 gajim
.ZEROCONF_ACC_NAME
, 'no_log_for').split()
1735 if gajim
.ZEROCONF_ACC_NAME
in list_no_log_for
:
1736 self
.xml
.get_object('log_history_checkbutton2').set_active(0)
1738 self
.xml
.get_object('log_history_checkbutton2').set_active(1)
1740 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1741 'sync_with_global_status')
1742 self
.xml
.get_object('sync_with_global_status_checkbutton2').set_active(st
)
1744 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1746 self
.xml
.get_object('custom_port_checkbutton2').set_active(st
)
1747 self
.xml
.get_object('custom_port_entry2').set_sensitive(st
)
1749 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1752 gajim
.config
.set_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1753 'custom_port', '5298')
1755 self
.xml
.get_object('custom_port_entry2').set_text(str(st
))
1758 gpg_key_label
= self
.xml
.get_object('gpg_key_label2')
1759 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
and \
1760 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].gpg
:
1761 self
.xml
.get_object('gpg_choose_button2').set_sensitive(True)
1762 self
.init_account_gpg()
1764 gpg_key_label
.set_text(_('OpenPGP is not usable on this computer'))
1765 self
.xml
.get_object('gpg_choose_button2').set_sensitive(False)
1767 for opt
in ('first_name', 'last_name', 'jabber_id', 'email'):
1768 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1770 self
.xml
.get_object(opt
+ '_entry2').set_text(st
)
1772 def init_account_gpg(self
):
1773 account
= self
.current_account
1774 keyid
= gajim
.config
.get_per('accounts', account
, 'keyid')
1775 keyname
= gajim
.config
.get_per('accounts', account
, 'keyname')
1776 use_gpg_agent
= gajim
.config
.get('use_gpg_agent')
1778 if account
== gajim
.ZEROCONF_ACC_NAME
:
1779 widget_name_add
= '2'
1781 widget_name_add
= '1'
1783 gpg_key_label
= self
.xml
.get_object('gpg_key_label' + widget_name_add
)
1784 gpg_name_label
= self
.xml
.get_object('gpg_name_label' + widget_name_add
)
1785 use_gpg_agent_checkbutton
= self
.xml
.get_object(
1786 'use_gpg_agent_checkbutton' + widget_name_add
)
1789 use_gpg_agent_checkbutton
.set_sensitive(False)
1790 gpg_key_label
.set_text(_('No key selected'))
1791 gpg_name_label
.set_text('')
1794 gpg_key_label
.set_text(keyid
)
1795 gpg_name_label
.set_text(keyname
)
1796 use_gpg_agent_checkbutton
.set_sensitive(True)
1797 use_gpg_agent_checkbutton
.set_active(use_gpg_agent
)
1799 def draw_normal_jid(self
):
1800 account
= self
.current_account
1801 self
.ignore_events
= True
1802 active
= gajim
.config
.get_per('accounts', account
, 'active')
1803 self
.xml
.get_object('enable_checkbutton1').set_active(active
)
1804 self
.xml
.get_object('normal_notebook1').set_sensitive(active
)
1805 if gajim
.config
.get_per('accounts', account
, 'anonymous_auth'):
1806 self
.xml
.get_object('anonymous_checkbutton1').set_active(True)
1807 self
.xml
.get_object('jid_label1').set_text(_('Server:'))
1808 save_password
= self
.xml
.get_object('save_password_checkbutton1')
1809 save_password
.set_active(False)
1810 save_password
.set_sensitive(False)
1811 password_entry
= self
.xml
.get_object('password_entry1')
1812 password_entry
.set_text('')
1813 password_entry
.set_sensitive(False)
1814 jid
= gajim
.config
.get_per('accounts', account
, 'hostname')
1816 self
.xml
.get_object('anonymous_checkbutton1').set_active(False)
1817 self
.xml
.get_object('jid_label1').set_text(_('Jabber ID:'))
1818 savepass
= gajim
.config
.get_per('accounts', account
, 'savepass')
1819 save_password
= self
.xml
.get_object('save_password_checkbutton1')
1820 save_password
.set_sensitive(True)
1821 save_password
.set_active(savepass
)
1822 password_entry
= self
.xml
.get_object('password_entry1')
1824 passstr
= passwords
.get_password(account
) or ''
1825 password_entry
.set_sensitive(True)
1828 password_entry
.set_sensitive(False)
1829 password_entry
.set_text(passstr
)
1831 jid
= gajim
.config
.get_per('accounts', account
, 'name') \
1832 + '@' + gajim
.config
.get_per('accounts', account
, 'hostname')
1833 self
.xml
.get_object('jid_entry1').set_text(jid
)
1834 self
.ignore_events
= False
1836 def init_normal_account(self
):
1837 account
= self
.current_account
1839 self
.draw_normal_jid()
1840 self
.xml
.get_object('resource_entry1').set_text(gajim
.config
.get_per(
1841 'accounts', account
, 'resource'))
1843 client_cert
= gajim
.config
.get_per('accounts', account
, 'client_cert')
1844 self
.xml
.get_object('cert_entry1').set_text(client_cert
)
1846 self
.xml
.get_object('adjust_priority_with_status_checkbutton1').\
1847 set_active(gajim
.config
.get_per('accounts', account
,
1848 'adjust_priority_with_status'))
1849 spinbutton
= self
.xml
.get_object('priority_spinbutton1')
1850 if gajim
.config
.get('enable_negative_priority'):
1851 spinbutton
.set_range(-128, 127)
1853 spinbutton
.set_range(0, 127)
1854 spinbutton
.set_value(gajim
.config
.get_per('accounts', account
,
1858 use_env_http_proxy
= gajim
.config
.get_per('accounts', account
,
1859 'use_env_http_proxy')
1860 self
.xml
.get_object('use_env_http_proxy_checkbutton1').set_active(
1862 self
.xml
.get_object('proxy_hbox1').set_sensitive(not use_env_http_proxy
)
1864 warn_when_insecure_ssl
= gajim
.config
.get_per('accounts', account
,
1865 'warn_when_insecure_ssl_connection')
1866 self
.xml
.get_object('warn_when_insecure_connection_checkbutton1').\
1867 set_active(warn_when_insecure_ssl
)
1869 self
.xml
.get_object('send_keepalive_checkbutton1').set_active(
1870 gajim
.config
.get_per('accounts', account
, 'keep_alives_enabled'))
1872 use_custom_host
= gajim
.config
.get_per('accounts', account
,
1874 self
.xml
.get_object('custom_host_port_checkbutton1').set_active(
1876 custom_host
= gajim
.config
.get_per('accounts', account
, 'custom_host')
1878 custom_host
= gajim
.config
.get_per('accounts', account
, 'hostname')
1879 gajim
.config
.set_per('accounts', account
, 'custom_host', custom_host
)
1880 self
.xml
.get_object('custom_host_entry1').set_text(custom_host
)
1881 custom_port
= gajim
.config
.get_per('accounts', account
, 'custom_port')
1884 gajim
.config
.set_per('accounts', account
, 'custom_port', custom_port
)
1885 self
.xml
.get_object('custom_port_entry1').set_text(unicode(custom_port
))
1888 gpg_key_label
= self
.xml
.get_object('gpg_key_label1')
1890 self
.xml
.get_object('gpg_choose_button1').set_sensitive(True)
1891 self
.init_account_gpg()
1893 gpg_key_label
.set_text(_('OpenPGP is not usable on this computer'))
1894 self
.xml
.get_object('gpg_choose_button1').set_sensitive(False)
1897 self
.xml
.get_object('autoconnect_checkbutton1').set_active(gajim
.config
.\
1898 get_per('accounts', account
, 'autoconnect'))
1899 self
.xml
.get_object('autoreconnect_checkbutton1').set_active(gajim
.
1900 config
.get_per('accounts', account
, 'autoreconnect'))
1902 list_no_log_for
= gajim
.config
.get_per('accounts', account
,
1903 'no_log_for').split()
1904 if account
in list_no_log_for
:
1905 self
.xml
.get_object('log_history_checkbutton1').set_active(False)
1907 self
.xml
.get_object('log_history_checkbutton1').set_active(True)
1909 self
.xml
.get_object('sync_with_global_status_checkbutton1').set_active(
1910 gajim
.config
.get_per('accounts', account
, 'sync_with_global_status'))
1911 self
.xml
.get_object('use_ft_proxies_checkbutton1').set_active(
1912 gajim
.config
.get_per('accounts', account
, 'use_ft_proxies'))
1914 def on_add_button_clicked(self
, widget
):
1916 When add button is clicked: open an account information window
1918 if 'account_creation_wizard' in gajim
.interface
.instances
:
1919 gajim
.interface
.instances
['account_creation_wizard'].window
.present()
1921 gajim
.interface
.instances
['account_creation_wizard'] = \
1922 AccountCreationWizardWindow()
1924 def on_remove_button_clicked(self
, widget
):
1926 When delete button is clicked: Remove an account from the listStore and
1927 from the config file
1929 if not self
.current_account
:
1931 account
= self
.current_account
1932 if len(gajim
.events
.get_events(account
)):
1933 dialogs
.ErrorDialog(_('Unread events'),
1934 _('Read all pending events before removing this account.'))
1937 if gajim
.config
.get_per('accounts', account
, 'is_zeroconf'):
1938 # Should never happen as button is insensitive
1942 if gajim
.interface
.msg_win_mgr
.get_controls(acct
=account
):
1944 elif account
in gajim
.interface
.instances
:
1945 for key
in gajim
.interface
.instances
[account
]:
1946 if gajim
.interface
.instances
[account
][key
] and key
!= \
1950 # Detect if we have opened windows for this account
1951 def remove(account
):
1952 if account
in gajim
.interface
.instances
and \
1953 'remove_account' in gajim
.interface
.instances
[account
]:
1954 gajim
.interface
.instances
[account
]['remove_account'].window
.\
1957 if not account
in gajim
.interface
.instances
:
1958 gajim
.interface
.instances
[account
] = {}
1959 gajim
.interface
.instances
[account
]['remove_account'] = \
1960 RemoveAccountWindow(account
)
1962 dialogs
.ConfirmationDialog(
1963 _('You have opened chat in account %s') % account
,
1964 _('All chat and groupchat windows will be closed. Do you want to '
1966 on_response_ok
= (remove
, account
))
1970 def on_rename_button_clicked(self
, widget
):
1971 if not self
.current_account
:
1973 active
= gajim
.config
.get_per('accounts', self
.current_account
, 'active')
1974 if active
and gajim
.connections
[self
.current_account
].connected
!= 0:
1975 dialogs
.ErrorDialog(
1976 _('You are currently connected to the server'),
1977 _('To change the account name, you must be disconnected.'))
1979 if len(gajim
.events
.get_events(self
.current_account
)):
1980 dialogs
.ErrorDialog(_('Unread events'),
1981 _('To change the account name, you must read all pending '
1985 def on_renamed(new_name
, old_name
):
1986 if new_name
in gajim
.connections
:
1987 dialogs
.ErrorDialog(_('Account Name Already Used'),
1988 _('This name is already used by another of your accounts. '
1989 'Please choose another name.'))
1991 if (new_name
== ''):
1992 dialogs
.ErrorDialog(_('Invalid account name'),
1993 _('Account name cannot be empty.'))
1995 if new_name
.find(' ') != -1:
1996 dialogs
.ErrorDialog(_('Invalid account name'),
1997 _('Account name cannot contain spaces.'))
2001 gajim
.interface
.instances
[new_name
] = gajim
.interface
.instances
[
2003 gajim
.interface
.minimized_controls
[new_name
] = \
2004 gajim
.interface
.minimized_controls
[old_name
]
2005 gajim
.nicks
[new_name
] = gajim
.nicks
[old_name
]
2006 gajim
.block_signed_in_notifications
[new_name
] = \
2007 gajim
.block_signed_in_notifications
[old_name
]
2008 gajim
.groups
[new_name
] = gajim
.groups
[old_name
]
2009 gajim
.gc_connected
[new_name
] = gajim
.gc_connected
[old_name
]
2010 gajim
.automatic_rooms
[new_name
] = gajim
.automatic_rooms
[old_name
]
2011 gajim
.newly_added
[new_name
] = gajim
.newly_added
[old_name
]
2012 gajim
.to_be_removed
[new_name
] = gajim
.to_be_removed
[old_name
]
2013 gajim
.sleeper_state
[new_name
] = gajim
.sleeper_state
[old_name
]
2014 gajim
.encrypted_chats
[new_name
] = gajim
.encrypted_chats
[old_name
]
2015 gajim
.last_message_time
[new_name
] = \
2016 gajim
.last_message_time
[old_name
]
2017 gajim
.status_before_autoaway
[new_name
] = \
2018 gajim
.status_before_autoaway
[old_name
]
2019 gajim
.transport_avatar
[new_name
] = gajim
.transport_avatar
[old_name
]
2020 gajim
.gajim_optional_features
[new_name
] = \
2021 gajim
.gajim_optional_features
[old_name
]
2022 gajim
.caps_hash
[new_name
] = gajim
.caps_hash
[old_name
]
2024 gajim
.contacts
.change_account_name(old_name
, new_name
)
2025 gajim
.events
.change_account_name(old_name
, new_name
)
2027 # change account variable for chat / gc controls
2028 gajim
.interface
.msg_win_mgr
.change_account_name(old_name
, new_name
)
2029 # upgrade account variable in opened windows
2030 for kind
in ('infos', 'disco', 'gc_config', 'search',
2032 for j
in gajim
.interface
.instances
[new_name
][kind
]:
2033 gajim
.interface
.instances
[new_name
][kind
][j
].account
= \
2036 # ServiceCache object keep old property account
2037 if hasattr(gajim
.connections
[old_name
], 'services_cache'):
2038 gajim
.connections
[old_name
].services_cache
.account
= new_name
2039 del gajim
.interface
.instances
[old_name
]
2040 del gajim
.interface
.minimized_controls
[old_name
]
2041 del gajim
.nicks
[old_name
]
2042 del gajim
.block_signed_in_notifications
[old_name
]
2043 del gajim
.groups
[old_name
]
2044 del gajim
.gc_connected
[old_name
]
2045 del gajim
.automatic_rooms
[old_name
]
2046 del gajim
.newly_added
[old_name
]
2047 del gajim
.to_be_removed
[old_name
]
2048 del gajim
.sleeper_state
[old_name
]
2049 del gajim
.encrypted_chats
[old_name
]
2050 del gajim
.last_message_time
[old_name
]
2051 del gajim
.status_before_autoaway
[old_name
]
2052 del gajim
.transport_avatar
[old_name
]
2053 del gajim
.gajim_optional_features
[old_name
]
2054 del gajim
.caps_hash
[old_name
]
2055 gajim
.connections
[old_name
].name
= new_name
2056 gajim
.connections
[old_name
].pep_change_account_name(new_name
)
2057 gajim
.connections
[old_name
].caps_change_account_name(new_name
)
2058 gajim
.connections
[new_name
] = gajim
.connections
[old_name
]
2059 del gajim
.connections
[old_name
]
2060 gajim
.config
.add_per('accounts', new_name
)
2061 old_config
= gajim
.config
.get_per('accounts', old_name
)
2062 for opt
in old_config
:
2063 gajim
.config
.set_per('accounts', new_name
, opt
, old_config
[opt
][1])
2064 gajim
.config
.del_per('accounts', old_name
)
2065 if self
.current_account
== old_name
:
2066 self
.current_account
= new_name
2067 if old_name
== gajim
.ZEROCONF_ACC_NAME
:
2068 gajim
.ZEROCONF_ACC_NAME
= new_name
2070 gajim
.interface
.roster
.setup_and_draw_roster()
2071 self
.init_accounts()
2072 self
.select_account(new_name
)
2074 title
= _('Rename Account')
2075 message
= _('Enter a new name for account %s') % self
.current_account
2076 old_text
= self
.current_account
2077 dialogs
.InputDialog(title
, message
, old_text
, is_modal
=False,
2078 ok_handler
=(on_renamed
, self
.current_account
))
2080 def option_changed(self
, option
, value
):
2081 return gajim
.config
.get_per('accounts', self
.current_account
, option
) != \
2084 def on_jid_entry1_focus_out_event(self
, widget
, event
):
2085 if self
.ignore_events
:
2087 jid
= widget
.get_text()
2088 # check if jid is conform to RFC and stringprep it
2090 jid
= helpers
.parse_jid(jid
)
2091 except helpers
.InvalidFormat
, s
:
2092 if not widget
.is_focus():
2093 pritext
= _('Invalid Jabber ID')
2094 dialogs
.ErrorDialog(pritext
, str(s
))
2095 gobject
.idle_add(lambda: widget
.grab_focus())
2098 jid_splited
= jid
.split('@', 1)
2099 if len(jid_splited
) != 2 and not gajim
.config
.get_per('accounts',
2100 self
.current_account
, 'anonymous_auth'):
2101 if not widget
.is_focus():
2102 pritext
= _('Invalid Jabber ID')
2103 sectext
= _('A Jabber ID must be in the form "user@servername".')
2104 dialogs
.ErrorDialog(pritext
, sectext
)
2105 gobject
.idle_add(lambda: widget
.grab_focus())
2109 if gajim
.config
.get_per('accounts', self
.current_account
,
2111 gajim
.config
.set_per('accounts', self
.current_account
, 'hostname',
2113 if self
.option_changed('hostname', jid_splited
[0]):
2114 self
.need_relogin
= True
2116 if self
.option_changed('name', jid_splited
[0]) or \
2117 self
.option_changed('hostname', jid_splited
[1]):
2118 self
.need_relogin
= True
2120 gajim
.config
.set_per('accounts', self
.current_account
, 'name',
2122 gajim
.config
.set_per('accounts', self
.current_account
, 'hostname',
2125 def on_cert_entry1_focus_out_event(self
, widget
, event
):
2126 if self
.ignore_events
:
2128 client_cert
= widget
.get_text()
2129 if self
.option_changed('client_cert', client_cert
):
2130 self
.need_relogin
= True
2131 gajim
.config
.set_per('accounts', self
.current_account
, 'client_cert',
2134 def on_anonymous_checkbutton1_toggled(self
, widget
):
2135 if self
.ignore_events
:
2137 active
= widget
.get_active()
2138 gajim
.config
.set_per('accounts', self
.current_account
, 'anonymous_auth',
2140 self
.draw_normal_jid()
2142 def on_password_entry1_changed(self
, widget
):
2143 if self
.ignore_events
:
2145 passwords
.save_password(self
.current_account
, widget
.get_text().decode(
2148 def on_save_password_checkbutton1_toggled(self
, widget
):
2149 if self
.ignore_events
:
2151 active
= widget
.get_active()
2152 password_entry
= self
.xml
.get_object('password_entry1')
2153 password_entry
.set_sensitive(active
)
2154 gajim
.config
.set_per('accounts', self
.current_account
, 'savepass', active
)
2156 password
= password_entry
.get_text()
2157 passwords
.save_password(self
.current_account
, password
)
2159 passwords
.save_password(self
.current_account
, '')
2161 def on_resource_entry1_focus_out_event(self
, widget
, event
):
2162 if self
.ignore_events
:
2164 resource
= self
.xml
.get_object('resource_entry1').get_text().decode(
2167 resource
= helpers
.parse_resource(resource
)
2168 except helpers
.InvalidFormat
, s
:
2169 if not widget
.is_focus():
2170 pritext
= _('Invalid Jabber ID')
2171 dialogs
.ErrorDialog(pritext
, str(s
))
2172 gobject
.idle_add(lambda: widget
.grab_focus())
2175 if self
.option_changed('resource', resource
):
2176 self
.need_relogin
= True
2178 gajim
.config
.set_per('accounts', self
.current_account
, 'resource',
2181 def on_adjust_priority_with_status_checkbutton1_toggled(self
, widget
):
2182 self
.xml
.get_object('priority_spinbutton1').set_sensitive(
2183 not widget
.get_active())
2184 self
.on_checkbutton_toggled(widget
, 'adjust_priority_with_status',
2185 account
= self
.current_account
)
2187 def on_priority_spinbutton1_value_changed(self
, widget
):
2188 prio
= widget
.get_value_as_int()
2190 if self
.option_changed('priority', prio
):
2191 self
.resend_presence
= True
2193 gajim
.config
.set_per('accounts', self
.current_account
, 'priority', prio
)
2195 def on_synchronise_contacts_button1_clicked(self
, widget
):
2197 dialogs
.SynchroniseSelectAccountDialog(self
.current_account
)
2198 except GajimGeneralException
:
2199 # If we showed ErrorDialog, there will not be dialog instance
2202 def on_change_password_button1_clicked(self
, widget
):
2203 def on_changed(new_password
):
2204 if new_password
is not None:
2205 gajim
.connections
[self
.current_account
].change_password(
2207 if self
.xml
.get_object('save_password_checkbutton1').get_active():
2208 self
.xml
.get_object('password_entry1').set_text(new_password
)
2211 dialogs
.ChangePasswordDialog(self
.current_account
, on_changed
)
2212 except GajimGeneralException
:
2213 # if we showed ErrorDialog, there will not be dialog instance
2216 def on_autoconnect_checkbutton_toggled(self
, widget
):
2217 if self
.ignore_events
:
2219 self
.on_checkbutton_toggled(widget
, 'autoconnect',
2220 account
=self
.current_account
)
2222 def on_autoreconnect_checkbutton_toggled(self
, widget
):
2223 if self
.ignore_events
:
2225 self
.on_checkbutton_toggled(widget
, 'autoreconnect',
2226 account
=self
.current_account
)
2228 def on_log_history_checkbutton_toggled(self
, widget
):
2229 if self
.ignore_events
:
2231 list_no_log_for
= gajim
.config
.get_per('accounts', self
.current_account
,
2232 'no_log_for').split()
2233 if self
.current_account
in list_no_log_for
:
2234 list_no_log_for
.remove(self
.current_account
)
2236 if not widget
.get_active():
2237 list_no_log_for
.append(self
.current_account
)
2238 gajim
.config
.set_per('accounts', self
.current_account
, 'no_log_for',
2239 ' '.join(list_no_log_for
))
2241 def on_sync_with_global_status_checkbutton_toggled(self
, widget
):
2242 if self
.ignore_events
:
2244 self
.on_checkbutton_toggled(widget
, 'sync_with_global_status',
2245 account
=self
.current_account
)
2246 gajim
.interface
.roster
.update_status_combobox()
2248 def on_use_ft_proxies_checkbutton1_toggled(self
, widget
):
2249 if self
.ignore_events
:
2251 self
.on_checkbutton_toggled(widget
, 'use_ft_proxies',
2252 account
=self
.current_account
)
2254 def on_use_env_http_proxy_checkbutton1_toggled(self
, widget
):
2255 if self
.ignore_events
:
2257 self
.on_checkbutton_toggled(widget
, 'use_env_http_proxy',
2258 account
=self
.current_account
)
2259 hbox
= self
.xml
.get_object('proxy_hbox1')
2260 hbox
.set_sensitive(not widget
.get_active())
2262 def on_proxies_combobox1_changed(self
, widget
):
2263 active
= widget
.get_active()
2264 proxy
= widget
.get_model()[active
][0].decode('utf-8')
2265 if proxy
== _('None'):
2268 if self
.option_changed('proxy', proxy
):
2269 self
.need_relogin
= True
2271 gajim
.config
.set_per('accounts', self
.current_account
, 'proxy', proxy
)
2273 def on_manage_proxies_button1_clicked(self
, widget
):
2274 if 'manage_proxies' in gajim
.interface
.instances
:
2275 gajim
.interface
.instances
['manage_proxies'].window
.present()
2277 gajim
.interface
.instances
['manage_proxies'] = ManageProxiesWindow()
2279 def on_warn_when_insecure_connection_checkbutton1_toggled(self
, widget
):
2280 if self
.ignore_events
:
2283 self
.on_checkbutton_toggled(widget
, 'warn_when_insecure_ssl_connection',
2284 account
=self
.current_account
)
2286 def on_send_keepalive_checkbutton1_toggled(self
, widget
):
2287 if self
.ignore_events
:
2289 self
.on_checkbutton_toggled(widget
, 'keep_alives_enabled',
2290 account
=self
.current_account
)
2291 gajim
.config
.set_per('accounts', self
.current_account
,
2292 'ping_alives_enabled', widget
.get_active())
2294 def on_custom_host_port_checkbutton1_toggled(self
, widget
):
2295 if self
.option_changed('use_custom_host', widget
.get_active()):
2296 self
.need_relogin
= True
2298 self
.on_checkbutton_toggled(widget
, 'use_custom_host',
2299 account
=self
.current_account
)
2300 active
= widget
.get_active()
2301 self
.xml
.get_object('custom_host_port_hbox1').set_sensitive(active
)
2303 def on_custom_host_entry1_changed(self
, widget
):
2304 if self
.ignore_events
:
2306 host
= widget
.get_text().decode('utf-8')
2307 if self
.option_changed('custom_host', host
):
2308 self
.need_relogin
= True
2309 gajim
.config
.set_per('accounts', self
.current_account
, 'custom_host',
2312 def on_custom_port_entry_focus_out_event(self
, widget
, event
):
2313 if self
.ignore_events
:
2315 custom_port
= widget
.get_text()
2317 custom_port
= int(custom_port
)
2319 if not widget
.is_focus():
2320 dialogs
.ErrorDialog(_('Invalid entry'),
2321 _('Custom port must be a port number.'))
2322 gobject
.idle_add(lambda: widget
.grab_focus())
2324 if self
.option_changed('custom_port', custom_port
):
2325 self
.need_relogin
= True
2326 gajim
.config
.set_per('accounts', self
.current_account
, 'custom_port',
2329 def on_gpg_choose_button_clicked(self
, widget
, data
= None):
2330 if self
.current_account
in gajim
.connections
and \
2331 gajim
.connections
[self
.current_account
].gpg
:
2332 secret_keys
= gajim
.connections
[self
.current_account
].\
2333 ask_gpg_secrete_keys()
2335 # self.current_account is None and/or gajim.connections is {}
2338 secret_keys
= gpg
.GnuPG().get_secret_keys()
2342 dialogs
.ErrorDialog(_('Failed to get secret keys'),
2343 _('There is no OpenPGP secret key available.'))
2344 secret_keys
[_('None')] = _('None')
2346 def on_key_selected(keyID
):
2349 if self
.current_account
== gajim
.ZEROCONF_ACC_NAME
:
2350 wiget_name_ext
= '2'
2352 wiget_name_ext
= '1'
2353 gpg_key_label
= self
.xml
.get_object('gpg_key_label' + wiget_name_ext
)
2354 gpg_name_label
= self
.xml
.get_object('gpg_name_label' + wiget_name_ext
)
2355 use_gpg_agent_checkbutton
= self
.xml
.get_object(
2356 'use_gpg_agent_checkbutton' + wiget_name_ext
)
2357 if keyID
[0] == _('None'):
2358 gpg_key_label
.set_text(_('No key selected'))
2359 gpg_name_label
.set_text('')
2360 use_gpg_agent_checkbutton
.set_sensitive(False)
2361 if self
.option_changed('keyid', ''):
2362 self
.need_relogin
= True
2363 gajim
.config
.set_per('accounts', self
.current_account
, 'keyname',
2365 gajim
.config
.set_per('accounts', self
.current_account
, 'keyid', '')
2367 gpg_key_label
.set_text(keyID
[0])
2368 gpg_name_label
.set_text(keyID
[1])
2369 use_gpg_agent_checkbutton
.set_sensitive(True)
2370 if self
.option_changed('keyid', keyID
[0]):
2371 self
.need_relogin
= True
2372 gajim
.config
.set_per('accounts', self
.current_account
, 'keyname',
2374 gajim
.config
.set_per('accounts', self
.current_account
, 'keyid',
2377 dialogs
.ChooseGPGKeyDialog(_('OpenPGP Key Selection'),
2378 _('Choose your OpenPGP key'), secret_keys
, on_key_selected
)
2380 def on_use_gpg_agent_checkbutton_toggled(self
, widget
):
2381 self
.on_checkbutton_toggled(widget
, 'use_gpg_agent')
2383 def on_edit_details_button1_clicked(self
, widget
):
2384 if self
.current_account
not in gajim
.interface
.instances
:
2385 dialogs
.ErrorDialog(_('No such account available'),
2386 _('You must create your account before editing your personal '
2390 # show error dialog if account is newly created (not in gajim.connections)
2391 if self
.current_account
not in gajim
.connections
or \
2392 gajim
.connections
[self
.current_account
].connected
< 2:
2393 dialogs
.ErrorDialog(_('You are not connected to the server'),
2394 _('Without a connection, you can not edit your personal information.'))
2397 if not gajim
.connections
[self
.current_account
].vcard_supported
:
2398 dialogs
.ErrorDialog(_("Your server doesn't support Vcard"),
2399 _("Your server can't save your personal information."))
2402 gajim
.interface
.edit_own_details(self
.current_account
)
2404 def on_checkbutton_toggled(self
, widget
, config_name
,
2405 change_sensitivity_widgets
= None, account
= None):
2407 gajim
.config
.set_per('accounts', account
, config_name
,
2408 widget
.get_active())
2410 gajim
.config
.set(config_name
, widget
.get_active())
2411 if change_sensitivity_widgets
:
2412 for w
in change_sensitivity_widgets
:
2413 w
.set_sensitive(widget
.get_active())
2414 gajim
.interface
.save_config()
2416 def on_merge_checkbutton_toggled(self
, widget
):
2417 self
.on_checkbutton_toggled(widget
, 'mergeaccounts')
2418 if len(gajim
.connections
) >= 2: # Do not merge accounts if only one active
2419 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2421 gajim
.interface
.roster
.regroup
= False
2422 gajim
.interface
.roster
.setup_and_draw_roster()
2424 def _disable_account(self
, account
):
2425 gajim
.interface
.roster
.close_all(account
)
2426 if account
== gajim
.ZEROCONF_ACC_NAME
:
2427 gajim
.connections
[account
].disable_account()
2428 del gajim
.connections
[account
]
2429 gajim
.interface
.save_config()
2430 del gajim
.interface
.instances
[account
]
2431 del gajim
.interface
.minimized_controls
[account
]
2432 del gajim
.nicks
[account
]
2433 del gajim
.block_signed_in_notifications
[account
]
2434 del gajim
.groups
[account
]
2435 gajim
.contacts
.remove_account(account
)
2436 del gajim
.gc_connected
[account
]
2437 del gajim
.automatic_rooms
[account
]
2438 del gajim
.to_be_removed
[account
]
2439 del gajim
.newly_added
[account
]
2440 del gajim
.sleeper_state
[account
]
2441 del gajim
.encrypted_chats
[account
]
2442 del gajim
.last_message_time
[account
]
2443 del gajim
.status_before_autoaway
[account
]
2444 del gajim
.transport_avatar
[account
]
2445 del gajim
.gajim_optional_features
[account
]
2446 del gajim
.caps_hash
[account
]
2447 if len(gajim
.connections
) >= 2:
2448 # Do not merge accounts if only one exists
2449 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2451 gajim
.interface
.roster
.regroup
= False
2452 gajim
.interface
.roster
.setup_and_draw_roster()
2453 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
2455 def _enable_account(self
, account
):
2456 if account
== gajim
.ZEROCONF_ACC_NAME
:
2457 gajim
.connections
[account
] = connection_zeroconf
.ConnectionZeroconf(
2459 if gajim
.connections
[account
].gpg
:
2460 self
.xml
.get_object('gpg_choose_button2').set_sensitive(True)
2462 gajim
.connections
[account
] = common
.connection
.Connection(account
)
2463 if gajim
.connections
[account
].gpg
:
2464 self
.xml
.get_object('gpg_choose_button1').set_sensitive(True)
2465 self
.init_account_gpg()
2467 gajim
.interface
.instances
[account
] = {'infos': {},
2468 'disco': {}, 'gc_config': {}, 'search': {}, 'online_dialog': {}}
2469 gajim
.interface
.minimized_controls
[account
] = {}
2470 gajim
.connections
[account
].connected
= 0
2471 gajim
.groups
[account
] = {}
2472 gajim
.contacts
.add_account(account
)
2473 gajim
.gc_connected
[account
] = {}
2474 gajim
.automatic_rooms
[account
] = {}
2475 gajim
.newly_added
[account
] = []
2476 gajim
.to_be_removed
[account
] = []
2477 if account
== gajim
.ZEROCONF_ACC_NAME
:
2478 gajim
.nicks
[account
] = gajim
.ZEROCONF_ACC_NAME
2480 gajim
.nicks
[account
] = gajim
.config
.get_per('accounts', account
,
2482 gajim
.block_signed_in_notifications
[account
] = True
2483 gajim
.sleeper_state
[account
] = 'off'
2484 gajim
.encrypted_chats
[account
] = []
2485 gajim
.last_message_time
[account
] = {}
2486 gajim
.status_before_autoaway
[account
] = ''
2487 gajim
.transport_avatar
[account
] = {}
2488 gajim
.gajim_optional_features
[account
] = []
2489 gajim
.caps_hash
[account
] = ''
2491 if len(gajim
.connections
) >= 2:
2492 # Do not merge accounts if only one exists
2493 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2495 gajim
.interface
.roster
.regroup
= False
2496 gajim
.interface
.roster
.setup_and_draw_roster()
2497 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
2498 gajim
.interface
.save_config()
2500 def on_enable_zeroconf_checkbutton2_toggled(self
, widget
):
2501 # don't do anything if there is an account with the local name but is a
2503 if self
.ignore_events
:
2505 if self
.current_account
in gajim
.connections
and \
2506 gajim
.connections
[self
.current_account
].connected
> 0:
2507 self
.ignore_events
= True
2508 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_active(True)
2509 self
.ignore_events
= False
2510 dialogs
.ErrorDialog(
2511 _('You are currently connected to the server'),
2512 _('To disable the account, you must be disconnected.'))
2514 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
and not \
2515 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].is_zeroconf
:
2516 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].dispatch('ERROR',
2517 (_('Account Local already exists.'),
2518 _('Please rename or remove it before enabling link-local messaging'
2522 if gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
, 'active') \
2523 and not widget
.get_active():
2524 self
.xml
.get_object('zeroconf_notebook').set_sensitive(False)
2526 self
._disable
_account
(gajim
.ZEROCONF_ACC_NAME
)
2528 elif not gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
2529 'active') and widget
.get_active():
2530 self
.xml
.get_object('zeroconf_notebook').set_sensitive(True)
2531 # enable (will create new account if not present)
2532 self
._enable
_account
(gajim
.ZEROCONF_ACC_NAME
)
2534 self
.on_checkbutton_toggled(widget
, 'active',
2535 account
=gajim
.ZEROCONF_ACC_NAME
)
2537 def on_enable_checkbutton1_toggled(self
, widget
):
2538 if self
.ignore_events
:
2540 if self
.current_account
in gajim
.connections
and \
2541 gajim
.connections
[self
.current_account
].connected
> 0:
2542 # connecting or connected
2543 self
.ignore_events
= True
2544 self
.xml
.get_object('enable_checkbutton1').set_active(True)
2545 self
.ignore_events
= False
2546 dialogs
.ErrorDialog(
2547 _('You are currently connected to the server'),
2548 _('To disable the account, you must be disconnected.'))
2550 # add/remove account in roster and all variables
2551 if widget
.get_active():
2553 self
._enable
_account
(self
.current_account
)
2556 self
._disable
_account
(self
.current_account
)
2557 self
.on_checkbutton_toggled(widget
, 'active',
2558 account
=self
.current_account
, change_sensitivity_widgets
=[
2559 self
.xml
.get_object('normal_notebook1')])
2561 def on_custom_port_checkbutton2_toggled(self
, widget
):
2562 self
.xml
.get_object('custom_port_entry2').set_sensitive(
2563 widget
.get_active())
2564 self
.on_checkbutton_toggled(widget
, 'use_custom_host',
2565 account
= self
.current_account
)
2566 if not widget
.get_active():
2567 self
.xml
.get_object('custom_port_entry2').set_text('5298')
2569 def on_first_name_entry2_changed(self
, widget
):
2570 if self
.ignore_events
:
2572 name
= widget
.get_text().decode('utf-8')
2573 if self
.option_changed('zeroconf_first_name', name
):
2574 self
.need_relogin
= True
2575 gajim
.config
.set_per('accounts', self
.current_account
,
2576 'zeroconf_first_name', name
)
2578 def on_last_name_entry2_changed(self
, widget
):
2579 if self
.ignore_events
:
2581 name
= widget
.get_text().decode('utf-8')
2582 if self
.option_changed('zeroconf_last_name', name
):
2583 self
.need_relogin
= True
2584 gajim
.config
.set_per('accounts', self
.current_account
,
2585 'zeroconf_last_name', name
)
2587 def on_jabber_id_entry2_changed(self
, widget
):
2588 if self
.ignore_events
:
2590 id_
= widget
.get_text().decode('utf-8')
2591 if self
.option_changed('zeroconf_jabber_id', id_
):
2592 self
.need_relogin
= True
2593 gajim
.config
.set_per('accounts', self
.current_account
,
2594 'zeroconf_jabber_id', id_
)
2596 def on_email_entry2_changed(self
, widget
):
2597 if self
.ignore_events
:
2599 email
= widget
.get_text().decode('utf-8')
2600 if self
.option_changed('zeroconf_email', email
):
2601 self
.need_relogin
= True
2602 gajim
.config
.set_per('accounts', self
.current_account
,
2603 'zeroconf_email', email
)
2605 class FakeDataForm(gtk
.Table
, object):
2607 Class for forms that are in XML format <entry1>value1</entry1> infos in a
2608 table {entry1: value1}
2611 def __init__(self
, infos
):
2612 gtk
.Table
.__init
__(self
)
2617 def _draw_table(self
):
2622 if 'instructions' in self
.infos
:
2624 self
.resize(rows
= nbrow
, columns
= 2)
2625 label
= gtk
.Label(self
.infos
['instructions'])
2626 self
.attach(label
, 0, 2, 0, 1, 0, 0, 0, 0)
2627 for name
in self
.infos
.keys():
2628 if name
in ('key', 'instructions', 'x', 'registered'):
2634 self
.resize(rows
= nbrow
, columns
= 2)
2635 label
= gtk
.Label(name
.capitalize() + ':')
2636 self
.attach(label
, 0, 1, nbrow
- 1, nbrow
, 0, 0, 0, 0)
2638 entry
.set_activates_default(True)
2639 if self
.infos
[name
]:
2640 entry
.set_text(self
.infos
[name
])
2641 if name
== 'password':
2642 entry
.set_visibility(False)
2643 self
.attach(entry
, 1, 2, nbrow
- 1, nbrow
, 0, 0, 0, 0)
2644 self
.entries
[name
] = entry
2648 def get_infos(self
):
2649 for name
in self
.entries
.keys():
2650 self
.infos
[name
] = self
.entries
[name
].get_text().decode('utf-8')
2653 class ServiceRegistrationWindow
:
2655 Class for Service registration window. Window that appears when we want to
2656 subscribe to a service if is_form we use dataforms_widget else we use
2657 service_registarion_window
2659 def __init__(self
, service
, infos
, account
, is_form
):
2660 self
.service
= service
2661 self
.account
= account
2662 self
.is_form
= is_form
2663 self
.xml
= gtkgui_helpers
.get_gtk_builder('service_registration_window.ui')
2664 self
.window
= self
.xml
.get_object('service_registration_window')
2665 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2667 dataform
= dataforms
.ExtendForm(node
= infos
)
2668 self
.data_form_widget
= dataforms_widget
.DataFormWidget(dataform
)
2669 if self
.data_form_widget
.title
:
2670 self
.window
.set_title('%s - Gajim' % self
.data_form_widget
.title
)
2671 table
= self
.xml
.get_object('table')
2672 table
.attach(self
.data_form_widget
, 0, 2, 0, 1)
2674 if 'registered' in infos
:
2675 self
.window
.set_title(_('Edit %s') % service
)
2677 self
.window
.set_title(_('Register to %s') % service
)
2678 self
.data_form_widget
= FakeDataForm(infos
)
2679 table
= self
.xml
.get_object('table')
2680 table
.attach(self
.data_form_widget
, 0, 2, 0, 1)
2682 self
.xml
.connect_signals(self
)
2683 self
.window
.show_all()
2685 def on_cancel_button_clicked(self
, widget
):
2686 self
.window
.destroy()
2688 def on_ok_button_clicked(self
, widget
):
2689 # send registration info to the core
2691 form
= self
.data_form_widget
.data_form
2692 gajim
.connections
[self
.account
].register_agent(self
.service
,
2693 form
, True) # True is for is_form
2695 infos
= self
.data_form_widget
.get_infos()
2696 if 'instructions' in infos
:
2697 del infos
['instructions']
2698 if 'registered' in infos
:
2699 del infos
['registered']
2700 gajim
.connections
[self
.account
].register_agent(self
.service
, infos
)
2702 self
.window
.destroy()
2704 class GroupchatConfigWindow
:
2706 def __init__(self
, account
, room_jid
, form
=None):
2707 self
.account
= account
2708 self
.room_jid
= room_jid
2710 self
.remove_button
= {}
2711 self
.affiliation_treeview
= {}
2712 self
.start_users_dict
= {} # list at the beginning
2713 self
.affiliation_labels
= {'outcast': _('Ban List'),
2714 'member': _('Member List'), 'owner': _('Owner List'),
2715 'admin':_('Administrator List')}
2717 self
.xml
= gtkgui_helpers
.get_gtk_builder('data_form_window.ui',
2719 self
.window
= self
.xml
.get_object('data_form_window')
2720 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2723 config_vbox
= self
.xml
.get_object('config_vbox')
2724 self
.data_form_widget
= dataforms_widget
.DataFormWidget(self
.form
)
2725 # hide scrollbar of this data_form_widget, we already have in this
2727 sw
= self
.data_form_widget
.xml
.get_object(
2728 'single_form_scrolledwindow')
2729 sw
.set_policy(gtk
.POLICY_NEVER
, gtk
.POLICY_NEVER
)
2731 self
.xml
.get_object('title_label').set_text(self
.form
.title
)
2733 self
.xml
.get_object('title_hseparator').set_no_show_all(True)
2734 self
.xml
.get_object('title_hseparator').hide()
2736 self
.data_form_widget
.show()
2737 config_vbox
.pack_start(self
.data_form_widget
)
2739 self
.xml
.get_object('title_label').set_no_show_all(True)
2740 self
.xml
.get_object('title_label').hide()
2741 self
.xml
.get_object('title_hseparator').set_no_show_all(True)
2742 self
.xml
.get_object('title_hseparator').hide()
2743 self
.xml
.get_object('config_hseparator').set_no_show_all(True)
2744 self
.xml
.get_object('config_hseparator').hide()
2746 # Draw the edit affiliation list things
2747 add_on_vbox
= self
.xml
.get_object('add_on_vbox')
2749 for affiliation
in self
.affiliation_labels
.keys():
2750 self
.start_users_dict
[affiliation
] = {}
2751 hbox
= gtk
.HBox(spacing
=5)
2752 add_on_vbox
.pack_start(hbox
, False)
2754 label
= gtk
.Label(self
.affiliation_labels
[affiliation
])
2755 hbox
.pack_start(label
, False)
2757 bb
= gtk
.HButtonBox()
2758 bb
.set_layout(gtk
.BUTTONBOX_END
)
2761 add_button
= gtk
.Button(stock
=gtk
.STOCK_ADD
)
2762 add_button
.connect('clicked', self
.on_add_button_clicked
,
2764 bb
.pack_start(add_button
)
2765 self
.remove_button
[affiliation
] = gtk
.Button(stock
=gtk
.STOCK_REMOVE
)
2766 self
.remove_button
[affiliation
].set_sensitive(False)
2767 self
.remove_button
[affiliation
].connect('clicked',
2768 self
.on_remove_button_clicked
, affiliation
)
2769 bb
.pack_start(self
.remove_button
[affiliation
])
2771 # jid, reason, nick, role
2772 liststore
= gtk
.ListStore(str, str, str, str)
2773 self
.affiliation_treeview
[affiliation
] = gtk
.TreeView(liststore
)
2774 self
.affiliation_treeview
[affiliation
].get_selection().set_mode(
2775 gtk
.SELECTION_MULTIPLE
)
2776 self
.affiliation_treeview
[affiliation
].connect('cursor-changed',
2777 self
.on_affiliation_treeview_cursor_changed
, affiliation
)
2778 renderer
= gtk
.CellRendererText()
2779 col
= gtk
.TreeViewColumn(_('JID'), renderer
)
2780 col
.add_attribute(renderer
, 'text', 0)
2781 col
.set_resizable(True)
2782 col
.set_sort_column_id(0)
2783 self
.affiliation_treeview
[affiliation
].append_column(col
)
2785 if affiliation
== 'outcast':
2786 renderer
= gtk
.CellRendererText()
2787 renderer
.set_property('editable', True)
2788 renderer
.connect('edited', self
.on_cell_edited
)
2789 col
= gtk
.TreeViewColumn(_('Reason'), renderer
)
2790 col
.add_attribute(renderer
, 'text', 1)
2791 col
.set_resizable(True)
2792 col
.set_sort_column_id(1)
2793 self
.affiliation_treeview
[affiliation
].append_column(col
)
2794 elif affiliation
== 'member':
2795 renderer
= gtk
.CellRendererText()
2796 col
= gtk
.TreeViewColumn(_('Nick'), renderer
)
2797 col
.add_attribute(renderer
, 'text', 2)
2798 col
.set_resizable(True)
2799 col
.set_sort_column_id(2)
2800 self
.affiliation_treeview
[affiliation
].append_column(col
)
2801 renderer
= gtk
.CellRendererText()
2802 col
= gtk
.TreeViewColumn(_('Role'), renderer
)
2803 col
.add_attribute(renderer
, 'text', 3)
2804 col
.set_resizable(True)
2805 col
.set_sort_column_id(3)
2806 self
.affiliation_treeview
[affiliation
].append_column(col
)
2808 sw
= gtk
.ScrolledWindow()
2809 sw
.set_policy(gtk
.POLICY_AUTOMATIC
, gtk
.POLICY_NEVER
)
2810 sw
.add(self
.affiliation_treeview
[affiliation
])
2811 add_on_vbox
.pack_start(sw
)
2812 gajim
.connections
[self
.account
].get_affiliation_list(self
.room_jid
,
2815 self
.xml
.connect_signals(self
)
2816 self
.window
.show_all()
2818 def on_cancel_button_clicked(self
, widget
):
2819 self
.window
.destroy()
2821 def on_cell_edited(self
, cell
, path
, new_text
):
2822 model
= self
.affiliation_treeview
['outcast'].get_model()
2823 new_text
= new_text
.decode('utf-8')
2824 iter_
= model
.get_iter(path
)
2825 model
[iter_
][1] = new_text
2827 def on_add_button_clicked(self
, widget
, affiliation
):
2828 if affiliation
== 'outcast':
2829 title
= _('Banning...')
2830 #You can move '\n' before user@domain if that line is TOO BIG
2831 prompt
= _('<b>Whom do you want to ban?</b>\n\n')
2832 elif affiliation
== 'member':
2833 title
= _('Adding Member...')
2834 prompt
= _('<b>Whom do you want to make a member?</b>\n\n')
2835 elif affiliation
== 'owner':
2836 title
= _('Adding Owner...')
2837 prompt
= _('<b>Whom do you want to make an owner?</b>\n\n')
2839 title
= _('Adding Administrator...')
2840 prompt
= _('<b>Whom do you want to make an administrator?</b>\n\n')
2841 prompt
+= _('Can be one of the following:\n'
2842 '1. user@domain/resource (only that resource matches).\n'
2843 '2. user@domain (any resource matches).\n'
2844 '3. domain/resource (only that resource matches).\n'
2845 '4. domain (the domain itself matches, as does any user@domain,\n'
2846 'domain/resource, or address containing a subdomain).')
2851 model
= self
.affiliation_treeview
[affiliation
].get_model()
2852 model
.append((jid
, '', '', ''))
2853 dialogs
.InputDialog(title
, prompt
, ok_handler
=on_ok
)
2855 def on_remove_button_clicked(self
, widget
, affiliation
):
2856 selection
= self
.affiliation_treeview
[affiliation
].get_selection()
2857 model
, paths
= selection
.get_selected_rows()
2860 row_refs
.append(gtk
.TreeRowReference(model
, path
))
2861 for row_ref
in row_refs
:
2862 path
= row_ref
.get_path()
2863 iter_
= model
.get_iter(path
)
2865 self
.remove_button
[affiliation
].set_sensitive(False)
2867 def on_affiliation_treeview_cursor_changed(self
, widget
, affiliation
):
2868 self
.remove_button
[affiliation
].set_sensitive(True)
2870 def affiliation_list_received(self
, users_dict
):
2872 Fill the affiliation treeview
2874 for jid
in users_dict
:
2875 affiliation
= users_dict
[jid
]['affiliation']
2876 if affiliation
not in self
.affiliation_labels
.keys():
2877 # Unknown affiliation or 'none' affiliation, do not show it
2879 self
.start_users_dict
[affiliation
][jid
] = users_dict
[jid
]
2880 tv
= self
.affiliation_treeview
[affiliation
]
2881 model
= tv
.get_model()
2882 reason
= users_dict
[jid
].get('reason', '')
2883 nick
= users_dict
[jid
].get('nick', '')
2884 role
= users_dict
[jid
].get('role', '')
2885 model
.append((jid
, reason
, nick
, role
))
2887 def on_data_form_window_destroy(self
, widget
):
2888 del gajim
.interface
.instances
[self
.account
]['gc_config'][self
.room_jid
]
2890 def on_ok_button_clicked(self
, widget
):
2892 form
= self
.data_form_widget
.data_form
2893 gajim
.connections
[self
.account
].send_gc_config(self
.room_jid
, form
)
2894 for affiliation
in self
.affiliation_labels
.keys():
2896 actual_jid_list
= []
2897 model
= self
.affiliation_treeview
[affiliation
].get_model()
2898 iter_
= model
.get_iter_first()
2901 jid
= model
[iter_
][0].decode('utf-8')
2902 actual_jid_list
.append(jid
)
2903 if jid
not in self
.start_users_dict
[affiliation
] or \
2904 (affiliation
== 'outcast' and 'reason' in self
.start_users_dict
[
2905 affiliation
][jid
] and self
.start_users_dict
[affiliation
][jid
]\
2906 ['reason'] != model
[iter_
][1].decode('utf-8')):
2907 users_dict
[jid
] = {'affiliation': affiliation
}
2908 if affiliation
== 'outcast':
2909 users_dict
[jid
]['reason'] = model
[iter_
][1].decode(
2911 iter_
= model
.iter_next(iter_
)
2912 # remove removed one
2913 for jid
in self
.start_users_dict
[affiliation
]:
2914 if jid
not in actual_jid_list
:
2915 users_dict
[jid
] = {'affiliation': 'none'}
2917 gajim
.connections
[self
.account
].send_gc_affiliation_list(
2918 self
.room_jid
, users_dict
)
2919 self
.window
.destroy()
2921 #---------- RemoveAccountWindow class -------------#
2922 class RemoveAccountWindow
:
2924 Ask for removing from gajim only or from gajim and server too and do
2925 removing of the account given
2928 def on_remove_account_window_destroy(self
, widget
):
2929 if self
.account
in gajim
.interface
.instances
:
2930 del gajim
.interface
.instances
[self
.account
]['remove_account']
2932 def on_cancel_button_clicked(self
, widget
):
2933 self
.window
.destroy()
2935 def __init__(self
, account
):
2936 self
.account
= account
2937 xml
= gtkgui_helpers
.get_gtk_builder('remove_account_window.ui')
2938 self
.window
= xml
.get_object('remove_account_window')
2939 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2940 self
.remove_and_unregister_radiobutton
= xml
.get_object(
2941 'remove_and_unregister_radiobutton')
2942 self
.window
.set_title(_('Removing %s account') % self
.account
)
2943 xml
.connect_signals(self
)
2944 self
.window
.show_all()
2946 def on_remove_button_clicked(self
, widget
):
2948 if self
.account
in gajim
.connections
and \
2949 gajim
.connections
[self
.account
].connected
and \
2950 not self
.remove_and_unregister_radiobutton
.get_active():
2951 # change status to offline only if we will not remove this JID from
2953 gajim
.connections
[self
.account
].change_status('offline', 'offline')
2954 if self
.remove_and_unregister_radiobutton
.get_active():
2955 if not self
.account
in gajim
.connections
:
2956 dialogs
.ErrorDialog(
2957 _('Account is disabled'),
2958 _('To unregister from a server, account must be '
2961 if not gajim
.connections
[self
.account
].password
:
2962 def on_ok(passphrase
, checked
):
2963 if passphrase
== -1:
2964 # We don't remove account cause we canceled pw window
2966 gajim
.connections
[self
.account
].password
= passphrase
2967 gajim
.connections
[self
.account
].unregister_account(
2968 self
._on
_remove
_success
)
2970 dialogs
.PassphraseDialog(
2971 _('Password Required'),
2972 _('Enter your password for account %s') % self
.account
,
2973 _('Save password'), ok_handler
=on_ok
)
2975 gajim
.connections
[self
.account
].unregister_account(
2976 self
._on
_remove
_success
)
2978 self
._on
_remove
_success
(True)
2980 if self
.account
in gajim
.connections
and \
2981 gajim
.connections
[self
.account
].connected
:
2982 dialogs
.ConfirmationDialog(
2983 _('Account "%s" is connected to the server') % self
.account
,
2984 _('If you remove it, the connection will be lost.'),
2985 on_response_ok
=remove
)
2989 def on_remove_responce_ok(self
, is_checked
):
2991 self
._on
_remove
_success
(True)
2993 def _on_remove_success(self
, res
):
2994 # action of unregistration has failed, we don't remove the account
2995 # Error message is send by connect_and_auth()
2997 dialogs
.ConfirmationDialogDoubleRadio(
2998 _('Connection to server %s failed') % self
.account
,
2999 _('What would you like to do?'),
3000 _('Remove only from Gajim'),
3001 _('Don\'t remove anything. I\'ll try again later'),
3002 on_response_ok
=self
.on_remove_responce_ok
, is_modal
=False)
3004 # Close all opened windows
3005 gajim
.interface
.roster
.close_all(self
.account
, force
=True)
3006 if self
.account
in gajim
.connections
:
3007 gajim
.connections
[self
.account
].disconnect(on_purpose
=True)
3008 del gajim
.connections
[self
.account
]
3009 gajim
.logger
.remove_roster(gajim
.get_jid_from_account(self
.account
))
3010 gajim
.config
.del_per('accounts', self
.account
)
3011 gajim
.interface
.save_config()
3012 del gajim
.interface
.instances
[self
.account
]
3013 if self
.account
in gajim
.nicks
:
3014 del gajim
.interface
.minimized_controls
[self
.account
]
3015 del gajim
.nicks
[self
.account
]
3016 del gajim
.block_signed_in_notifications
[self
.account
]
3017 del gajim
.groups
[self
.account
]
3018 gajim
.contacts
.remove_account(self
.account
)
3019 del gajim
.gc_connected
[self
.account
]
3020 del gajim
.automatic_rooms
[self
.account
]
3021 del gajim
.to_be_removed
[self
.account
]
3022 del gajim
.newly_added
[self
.account
]
3023 del gajim
.sleeper_state
[self
.account
]
3024 del gajim
.encrypted_chats
[self
.account
]
3025 del gajim
.last_message_time
[self
.account
]
3026 del gajim
.status_before_autoaway
[self
.account
]
3027 del gajim
.transport_avatar
[self
.account
]
3028 del gajim
.gajim_optional_features
[self
.account
]
3029 del gajim
.caps_hash
[self
.account
]
3030 if len(gajim
.connections
) >= 2: # Do not merge accounts if only one exists
3031 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
3033 gajim
.interface
.roster
.regroup
= False
3034 gajim
.interface
.roster
.setup_and_draw_roster()
3035 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3036 if 'accounts' in gajim
.interface
.instances
:
3037 gajim
.interface
.instances
['accounts'].init_accounts()
3038 gajim
.interface
.instances
['accounts'].init_account()
3039 self
.window
.destroy()
3041 #---------- ManageBookmarksWindow class -------------#
3042 class ManageBookmarksWindow
:
3044 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_bookmarks_window.ui')
3045 self
.window
= self
.xml
.get_object('manage_bookmarks_window')
3046 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3048 # Account-JID, RoomName, Room-JID, Autojoin, Minimize, Passowrd, Nick,
3050 self
.treestore
= gtk
.TreeStore(str, str, str, bool, bool, str, str, str)
3051 self
.treestore
.set_sort_column_id(1, gtk
.SORT_ASCENDING
)
3053 # Store bookmarks in treeview.
3054 for account
in gajim
.connections
:
3055 if gajim
.connections
[account
].connected
<= 1:
3057 if gajim
.connections
[account
].is_zeroconf
:
3059 if not gajim
.connections
[account
].private_storage_supported
:
3061 iter_
= self
.treestore
.append(None, [None, account
, None, None,
3062 None, None, None, None])
3064 for bookmark
in gajim
.connections
[account
].bookmarks
:
3065 if bookmark
['name'] == '':
3066 # No name was given for this bookmark.
3067 # Use the first part of JID instead...
3068 name
= bookmark
['jid'].split("@")[0]
3069 bookmark
['name'] = name
3071 # make '1', '0', 'true', 'false' (or other) to True/False
3072 autojoin
= helpers
.from_xs_boolean_to_python_boolean(
3073 bookmark
['autojoin'])
3075 minimize
= helpers
.from_xs_boolean_to_python_boolean(
3076 bookmark
['minimize'])
3078 print_status
= bookmark
.get('print_status', '')
3079 if print_status
not in ('', 'all', 'in_and_out', 'none'):
3081 self
.treestore
.append(iter_
, [
3087 bookmark
['password'],
3091 self
.print_status_combobox
= self
.xml
.get_object('print_status_combobox')
3092 model
= gtk
.ListStore(str, str)
3094 self
.option_list
= {'': _('Default'), 'all': Q_('?print_status:All'),
3095 'in_and_out': _('Enter and leave only'),
3096 'none': Q_('?print_status:None')}
3097 opts
= sorted(self
.option_list
.keys())
3099 model
.append([self
.option_list
[opt
], opt
])
3101 self
.print_status_combobox
.set_model(model
)
3102 self
.print_status_combobox
.set_active(1)
3104 self
.view
= self
.xml
.get_object('bookmarks_treeview')
3105 self
.view
.set_model(self
.treestore
)
3106 self
.view
.expand_all()
3108 renderer
= gtk
.CellRendererText()
3109 column
= gtk
.TreeViewColumn('Bookmarks', renderer
, text
=1)
3110 self
.view
.append_column(column
)
3112 self
.selection
= self
.view
.get_selection()
3113 self
.selection
.connect('changed', self
.bookmark_selected
)
3115 #Prepare input fields
3116 self
.title_entry
= self
.xml
.get_object('title_entry')
3117 self
.title_entry
.connect('changed', self
.on_title_entry_changed
)
3118 self
.nick_entry
= self
.xml
.get_object('nick_entry')
3119 self
.nick_entry
.connect('changed', self
.on_nick_entry_changed
)
3120 self
.server_entry
= self
.xml
.get_object('server_entry')
3121 self
.server_entry
.connect('changed', self
.on_server_entry_changed
)
3122 self
.room_entry
= self
.xml
.get_object('room_entry')
3123 self
.room_entry
.connect('changed', self
.on_room_entry_changed
)
3124 self
.pass_entry
= self
.xml
.get_object('pass_entry')
3125 self
.pass_entry
.connect('changed', self
.on_pass_entry_changed
)
3126 self
.autojoin_checkbutton
= self
.xml
.get_object('autojoin_checkbutton')
3127 self
.minimize_checkbutton
= self
.xml
.get_object('minimize_checkbutton')
3129 self
.xml
.connect_signals(self
)
3130 self
.window
.show_all()
3132 self
.selection
.select_iter(self
.treestore
.get_iter_root())
3134 def on_bookmarks_treeview_button_press_event(self
, widget
, event
):
3135 (model
, iter_
) = self
.selection
.get_selected()
3137 # Removed a bookmark before
3140 if model
.iter_parent(iter_
):
3141 # The currently selected node is a bookmark
3142 return not self
.check_valid_bookmark()
3144 def on_manage_bookmarks_window_destroy(self
, widget
, event
):
3145 del gajim
.interface
.instances
['manage_bookmarks']
3147 def on_add_bookmark_button_clicked(self
, widget
):
3151 # Get the account that is currently used
3152 # (the parent of the currently selected item)
3153 (model
, iter_
) = self
.selection
.get_selected()
3154 if not iter_
: # Nothing selected, do nothing
3157 parent
= model
.iter_parent(iter_
)
3160 # We got a bookmark selected, so we add_to the parent
3163 # No parent, so we got an account -> add to this.
3166 account
= model
[add_to
][1].decode('utf-8')
3167 nick
= gajim
.nicks
[account
]
3168 iter_
= self
.treestore
.append(add_to
, [account
, _('New Group Chat'),
3169 '@', False, False, '', nick
, 'in_and_out'])
3171 self
.view
.expand_row(model
.get_path(add_to
), True)
3172 self
.view
.set_cursor(model
.get_path(iter_
))
3174 def on_remove_bookmark_button_clicked(self
, widget
):
3176 Remove selected bookmark
3178 (model
, iter_
) = self
.selection
.get_selected()
3179 if not iter_
: # Nothing selected
3182 if not model
.iter_parent(iter_
):
3183 # Don't remove account iters
3189 def check_valid_bookmark(self
):
3191 Check if all neccessary fields are entered correctly
3193 (model
, iter_
) = self
.selection
.get_selected()
3195 if not model
.iter_parent(iter_
):
3196 #Account data can't be changed
3199 if self
.server_entry
.get_text().decode('utf-8') == '' or \
3200 self
.room_entry
.get_text().decode('utf-8') == '':
3201 dialogs
.ErrorDialog(_('This bookmark has invalid data'),
3202 _('Please be sure to fill out server and room fields or remove this'
3208 def on_ok_button_clicked(self
, widget
):
3210 Parse the treestore data into our new bookmarks array, then send the new
3211 bookmarks to the server.
3213 (model
, iter_
) = self
.selection
.get_selected()
3214 if iter_
and model
.iter_parent(iter_
):
3215 #bookmark selected, check it
3216 if not self
.check_valid_bookmark():
3219 for account
in self
.treestore
:
3220 account_unicode
= account
[1].decode('utf-8')
3221 gajim
.connections
[account_unicode
].bookmarks
= []
3223 for bm
in account
.iterchildren():
3224 #Convert True/False/None to '1' or '0'
3225 autojoin
= unicode(int(bm
[3]))
3226 minimize
= unicode(int(bm
[4]))
3228 #create the bookmark-dict
3229 bmdict
= { 'name': bm
[1], 'jid': bm
[2], 'autojoin': autojoin
,
3230 'minimize': minimize
, 'password': bm
[5], 'nick': bm
[6],
3231 'print_status': bm
[7]}
3233 gajim
.connections
[account_unicode
].bookmarks
.append(bmdict
)
3235 gajim
.connections
[account_unicode
].store_bookmarks()
3236 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3237 self
.window
.destroy()
3239 def on_cancel_button_clicked(self
, widget
):
3240 self
.window
.destroy()
3242 def bookmark_selected(self
, selection
):
3244 Fill in the bookmark's data into the fields.
3246 (model
, iter_
) = selection
.get_selected()
3249 # After removing the last bookmark for one account
3250 # this will be None, so we will just:
3253 widgets
= [ self
.title_entry
, self
.nick_entry
, self
.room_entry
,
3254 self
.server_entry
, self
.pass_entry
, self
.autojoin_checkbutton
,
3255 self
.minimize_checkbutton
, self
.print_status_combobox
]
3257 if model
.iter_parent(iter_
):
3258 # make the fields sensitive
3259 for field
in widgets
:
3260 field
.set_sensitive(True)
3262 # Top-level has no data (it's the account fields)
3263 # clear fields & make them insensitive
3265 for field
in widgets
:
3266 field
.set_sensitive(False)
3269 # Fill in the data for childs
3270 self
.title_entry
.set_text(model
[iter_
][1])
3271 room_jid
= model
[iter_
][2].decode('utf-8')
3272 (room
, server
) = room_jid
.split('@')
3273 self
.room_entry
.set_text(room
)
3274 self
.server_entry
.set_text(server
)
3276 self
.autojoin_checkbutton
.set_active(model
[iter_
][3])
3277 self
.minimize_checkbutton
.set_active(model
[iter_
][4])
3278 # sensitive only if auto join is checked
3279 self
.minimize_checkbutton
.set_sensitive(model
[iter_
][3])
3281 if model
[iter_
][5] is not None:
3282 password
= model
[iter_
][5].decode('utf-8')
3287 self
.pass_entry
.set_text(password
)
3289 self
.pass_entry
.set_text('')
3290 nick
= model
[iter_
][6]
3292 nick
= nick
.decode('utf-8')
3293 self
.nick_entry
.set_text(nick
)
3295 self
.nick_entry
.set_text('')
3297 print_status
= model
[iter_
][7]
3298 opts
= sorted(self
.option_list
.keys())
3299 self
.print_status_combobox
.set_active(opts
.index(print_status
))
3301 def on_title_entry_changed(self
, widget
):
3302 (model
, iter_
) = self
.selection
.get_selected()
3303 if iter_
: # After removing a bookmark, we got nothing selected
3304 if model
.iter_parent(iter_
):
3305 # Don't clear the title field for account nodes
3306 model
[iter_
][1] = self
.title_entry
.get_text()
3308 def on_nick_entry_changed(self
, widget
):
3309 (model
, iter_
) = self
.selection
.get_selected()
3311 nick
= self
.nick_entry
.get_text().decode('utf-8')
3313 nick
= helpers
.parse_resource(nick
)
3314 except helpers
.InvalidFormat
, e
:
3315 dialogs
.ErrorDialog(_('Invalid nickname'),
3316 _('Character not allowed'))
3317 self
.nick_entry
.set_text(model
[iter_
][6])
3319 model
[iter_
][6] = nick
3321 def on_server_entry_changed(self
, widget
):
3322 (model
, iter_
) = self
.selection
.get_selected()
3325 server
= widget
.get_text().decode('utf-8')
3327 dialogs
.ErrorDialog(_('Invalid server'), _('Character not allowed'))
3328 widget
.set_text(server
.replace('@', ''))
3330 room_jid
= self
.room_entry
.get_text().decode('utf-8').strip() + '@' + \
3333 room_jid
= helpers
.parse_resource(room_jid
)
3334 except helpers
.InvalidFormat
, e
:
3335 dialogs
.ErrorDialog(_('Invalid server'),
3336 _('Character not allowed'))
3337 self
.server_entry
.set_text(model
[iter_
][2].split('@')[1])
3339 model
[iter_
][2] = room_jid
3341 def on_room_entry_changed(self
, widget
):
3342 (model
, iter_
) = self
.selection
.get_selected()
3345 room
= widget
.get_text().decode('utf-8')
3347 dialogs
.ErrorDialog(_('Invalid server'), _('Character not allowed'))
3348 widget
.set_text(room
.replace('@', ''))
3349 room_jid
= self
.room_entry
.get_text().decode('utf-8').strip() + '@' + \
3352 room_jid
= helpers
.parse_resource(room_jid
)
3353 except helpers
.InvalidFormat
, e
:
3354 dialogs
.ErrorDialog(_('Invalid room'),
3355 _('Character not allowed'))
3356 self
.room_entry
.set_text(model
[iter_
][2].split('@')[0])
3358 model
[iter_
][2] = room_jid
3360 def on_pass_entry_changed(self
, widget
):
3361 (model
, iter_
) = self
.selection
.get_selected()
3363 model
[iter_
][5] = self
.pass_entry
.get_text()
3365 def on_autojoin_checkbutton_toggled(self
, widget
):
3366 (model
, iter_
) = self
.selection
.get_selected()
3368 model
[iter_
][3] = self
.autojoin_checkbutton
.get_active()
3369 self
.minimize_checkbutton
.set_sensitive(model
[iter_
][3])
3371 def on_minimize_checkbutton_toggled(self
, widget
):
3372 (model
, iter_
) = self
.selection
.get_selected()
3374 model
[iter_
][4] = self
.minimize_checkbutton
.get_active()
3376 def on_print_status_combobox_changed(self
, widget
):
3377 active
= widget
.get_active()
3378 model
= widget
.get_model()
3379 print_status
= model
[active
][1]
3380 (model2
, iter_
) = self
.selection
.get_selected()
3382 model2
[iter_
][7] = print_status
3384 def clear_fields(self
):
3385 widgets
= [ self
.title_entry
, self
.nick_entry
, self
.room_entry
,
3386 self
.server_entry
, self
.pass_entry
]
3387 for field
in widgets
:
3389 self
.autojoin_checkbutton
.set_active(False)
3390 self
.minimize_checkbutton
.set_active(False)
3391 self
.print_status_combobox
.set_active(1)
3393 class AccountCreationWizardWindow
:
3395 self
.xml
= gtkgui_helpers
.get_gtk_builder(
3396 'account_creation_wizard_window.ui')
3397 self
.window
= self
.xml
.get_object('account_creation_wizard_window')
3398 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3400 completion
= gtk
.EntryCompletion()
3401 completion1
= gtk
.EntryCompletion()
3402 # Connect events from comboboxentry.child
3403 server_comboboxentry
= self
.xml
.get_object('server_comboboxentry')
3404 entry
= server_comboboxentry
.child
3405 entry
.connect('key_press_event',
3406 self
.on_server_comboboxentry_key_press_event
, server_comboboxentry
)
3407 entry
.set_completion(completion
)
3408 # Do the same for the other server comboboxentry
3409 server_comboboxentry1
= self
.xml
.get_object('server_comboboxentry1')
3410 entry
= server_comboboxentry1
.child
3411 entry
.set_completion(completion1
)
3413 self
.update_proxy_list()
3416 servers_xml
= os
.path
.join(gajim
.DATA_DIR
, 'other', 'servers.xml')
3417 servers
= gtkgui_helpers
.parse_server_xml(servers_xml
)
3418 servers_model
= gtk
.ListStore(str)
3419 for server
in servers
:
3420 servers_model
.append((server
,))
3422 completion
.set_model(servers_model
)
3423 completion
.set_text_column(0)
3424 completion1
.set_model(servers_model
)
3425 completion1
.set_text_column(0)
3427 # Put servers into comboboxentries
3428 server_comboboxentry
.set_model(servers_model
)
3429 server_comboboxentry
.set_text_column(0)
3430 server_comboboxentry1
.set_model(servers_model
)
3431 server_comboboxentry1
.set_text_column(0)
3434 self
.notebook
= self
.xml
.get_object('notebook')
3435 self
.cancel_button
= self
.xml
.get_object('cancel_button')
3436 self
.back_button
= self
.xml
.get_object('back_button')
3437 self
.forward_button
= self
.xml
.get_object('forward_button')
3438 self
.finish_button
= self
.xml
.get_object('finish_button')
3439 self
.advanced_button
= self
.xml
.get_object('advanced_button')
3440 self
.finish_label
= self
.xml
.get_object('finish_label')
3441 self
.go_online_checkbutton
= self
.xml
.get_object(
3442 'go_online_checkbutton')
3443 self
.show_vcard_checkbutton
= self
.xml
.get_object(
3444 'show_vcard_checkbutton')
3445 self
.progressbar
= self
.xml
.get_object('progressbar')
3448 self
.update_progressbar_timeout_id
= None
3450 self
.notebook
.set_current_page(0)
3451 self
.xml
.connect_signals(self
)
3452 self
.window
.show_all()
3453 gajim
.ged
.register_event_handler('new-account-connected', ged
.GUI1
,
3454 self
._nec
_new
_acc
_connected
)
3455 gajim
.ged
.register_event_handler('new-account-not-connected', ged
.GUI1
,
3456 self
._nec
_new
_acc
_not
_connected
)
3457 gajim
.ged
.register_event_handler('account-created', ged
.GUI1
,
3458 self
._nec
_acc
_is
_ok
)
3459 gajim
.ged
.register_event_handler('account-not-created', ged
.GUI1
,
3460 self
._nec
_acc
_is
_not
_ok
)
3462 def on_wizard_window_destroy(self
, widget
):
3463 page
= self
.notebook
.get_current_page()
3464 if page
in (4, 5) and self
.account
in gajim
.connections
:
3465 # connection instance is saved in gajim.connections and we canceled
3466 # the addition of the account
3467 del gajim
.connections
[self
.account
]
3468 if self
.account
in gajim
.config
.get_per('accounts'):
3469 gajim
.config
.del_per('accounts', self
.account
)
3470 gajim
.ged
.remove_event_handler('new-account-connected', ged
.GUI1
,
3471 self
._nec
_new
_acc
_connected
)
3472 gajim
.ged
.remove_event_handler('new-account-not-connected', ged
.GUI1
,
3473 self
._nec
_new
_acc
_not
_connected
)
3474 gajim
.ged
.remove_event_handler('account-created', ged
.GUI1
,
3475 self
._nec
_acc
_is
_ok
)
3476 gajim
.ged
.remove_event_handler('account-not-created', ged
.GUI1
,
3477 self
._nec
_acc
_is
_not
_ok
)
3478 del gajim
.interface
.instances
['account_creation_wizard']
3480 def on_register_server_features_button_clicked(self
, widget
):
3481 helpers
.launch_browser_mailer('url',
3482 'http://www.jabber.org/network/oldnetwork.shtml')
3484 def on_save_password_checkbutton_toggled(self
, widget
):
3485 self
.xml
.get_object('password_entry').grab_focus()
3487 def on_cancel_button_clicked(self
, widget
):
3488 self
.window
.destroy()
3490 def on_back_button_clicked(self
, widget
):
3491 cur_page
= self
.notebook
.get_current_page()
3492 if cur_page
in (1, 2):
3493 self
.notebook
.set_current_page(0)
3494 self
.back_button
.set_sensitive(False)
3496 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3497 self
.notebook
.set_current_page(2) # show server page
3499 if self
.account
in gajim
.connections
:
3500 del gajim
.connections
[self
.account
]
3501 self
.notebook
.set_current_page(2)
3502 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3503 elif cur_page
== 6: # finish page
3504 self
.forward_button
.show()
3506 self
.notebook
.set_current_page(1) # Go to parameters page
3508 self
.notebook
.set_current_page(2) # Go to server page
3510 def on_anonymous_checkbutton1_toggled(self
, widget
):
3511 active
= widget
.get_active()
3512 self
.xml
.get_object('username_entry').set_sensitive(not active
)
3513 self
.xml
.get_object('password_entry').set_sensitive(not active
)
3514 self
.xml
.get_object('save_password_checkbutton').set_sensitive(
3517 def show_finish_page(self
):
3518 self
.cancel_button
.hide()
3519 self
.back_button
.hide()
3520 self
.forward_button
.hide()
3522 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3523 _('Account has been added successfully'),
3524 _('You can set advanced account options by pressing the '
3525 'Advanced button, or later by choosing the Accounts menu item '
3526 'under the Edit menu from the main window.'))
3528 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3529 _('Your new account has been created successfully'),
3530 _('You can set advanced account options by pressing the '
3531 'Advanced button, or later by choosing the Accounts menu item '
3532 'under the Edit menu from the main window.'))
3533 self
.finish_label
.set_markup(finish_text
)
3534 self
.finish_button
.show()
3535 self
.finish_button
.set_property('has-default', True)
3536 self
.advanced_button
.show()
3537 self
.go_online_checkbutton
.show()
3538 img
= self
.xml
.get_object('finish_image')
3540 img
.set_from_stock(gtk
.STOCK_APPLY
, gtk
.ICON_SIZE_DIALOG
)
3542 path_to_file
= gtkgui_helpers
.get_icon_path('gajim', 48)
3543 img
.set_from_file(path_to_file
)
3544 self
.show_vcard_checkbutton
.set_active(not self
.modify
)
3545 self
.notebook
.set_current_page(6) # show finish page
3547 def on_forward_button_clicked(self
, widget
):
3548 cur_page
= self
.notebook
.get_current_page()
3551 widget
= self
.xml
.get_object('use_existing_account_radiobutton')
3552 if widget
.get_active():
3554 self
.notebook
.set_current_page(1)
3557 self
.notebook
.set_current_page(2)
3558 self
.back_button
.set_sensitive(True)
3562 # We are adding an existing account
3563 anonymous
= self
.xml
.get_object('anonymous_checkbutton1').\
3565 username
= self
.xml
.get_object('username_entry').get_text().decode(
3567 if not username
and not anonymous
:
3568 pritext
= _('Invalid username')
3570 'You must provide a username to configure this account.')
3571 dialogs
.ErrorDialog(pritext
, sectext
)
3573 server
= self
.xml
.get_object('server_comboboxentry').child
.\
3574 get_text().decode('utf-8').strip()
3575 savepass
= self
.xml
.get_object('save_password_checkbutton').\
3577 password
= self
.xml
.get_object('password_entry').get_text().decode(
3580 jid
= username
+ '@' + server
3581 # check if jid is conform to RFC and stringprep it
3583 jid
= helpers
.parse_jid(jid
)
3584 except helpers
.InvalidFormat
, s
:
3585 pritext
= _('Invalid Jabber ID')
3586 dialogs
.ErrorDialog(pritext
, str(s
))
3589 self
.account
= server
3591 while self
.account
in gajim
.connections
:
3592 self
.account
= server
+ str(i
)
3595 username
, server
= gajim
.get_name_and_server_from_jid(jid
)
3596 if self
.xml
.get_object('anonymous_checkbutton1').get_active():
3597 self
.save_account('', server
, False, '', anonymous
=True)
3599 self
.save_account(username
, server
, savepass
, password
)
3600 self
.show_finish_page()
3602 # We are creating a new account
3603 server
= self
.xml
.get_object('server_comboboxentry1').child
.\
3604 get_text().decode('utf-8')
3607 dialogs
.ErrorDialog(_('Invalid server'),
3608 _('Please provide a server on which you want to register.'))
3610 self
.account
= server
3612 while self
.account
in gajim
.connections
:
3613 self
.account
= server
+ str(i
)
3616 config
= self
.get_config('', server
, '', '')
3617 # Get advanced options
3618 proxies_combobox
= self
.xml
.get_object('proxies_combobox')
3619 active
= proxies_combobox
.get_active()
3620 proxy
= proxies_combobox
.get_model()[active
][0].decode('utf-8')
3621 if proxy
== _('None'):
3623 config
['proxy'] = proxy
3625 config
['use_custom_host'] = self
.xml
.get_object(
3626 'custom_host_port_checkbutton').get_active()
3627 custom_port
= self
.xml
.get_object('custom_port_entry').get_text()
3629 custom_port
= int(custom_port
)
3631 dialogs
.ErrorDialog(_('Invalid entry'),
3632 _('Custom port must be a port number.'))
3634 config
['custom_port'] = custom_port
3635 config
['custom_host'] = self
.xml
.get_object(
3636 'custom_host_entry').get_text().decode('utf-8')
3638 if self
.xml
.get_object('anonymous_checkbutton2').get_active():
3640 self
.save_account('', server
, False, '', anonymous
=True)
3641 self
.show_finish_page()
3643 self
.notebook
.set_current_page(5) # show creating page
3644 self
.back_button
.hide()
3645 self
.forward_button
.hide()
3646 self
.update_progressbar_timeout_id
= gobject
.timeout_add(100,
3647 self
.update_progressbar
)
3648 # Get form from serveur
3649 con
= connection
.Connection(self
.account
)
3650 gajim
.connections
[self
.account
] = con
3651 con
.new_account(self
.account
, config
)
3653 checked
= self
.xml
.get_object('ssl_checkbutton').get_active()
3655 hostname
= gajim
.connections
[self
.account
].new_account_info
[
3657 # Check if cert is already in file
3659 if os
.path
.isfile(gajim
.MY_CACERTS
):
3660 f
= open(gajim
.MY_CACERTS
)
3663 if self
.ssl_cert
in certs
:
3664 dialogs
.ErrorDialog(_('Certificate Already in File'),
3665 _('This certificate is already in file %s, so it\'s '
3666 'not added again.') % gajim
.MY_CACERTS
)
3668 f
= open(gajim
.MY_CACERTS
, 'a')
3669 f
.write(hostname
+ '\n')
3670 f
.write(self
.ssl_cert
+ '\n\n')
3672 gajim
.connections
[self
.account
].new_account_info
[
3673 'ssl_fingerprint_sha1'] = self
.ssl_fingerprint
3674 self
.notebook
.set_current_page(4) # show fom page
3677 form
= self
.data_form_widget
.data_form
3679 form
= self
.data_form_widget
.get_infos()
3680 gajim
.connections
[self
.account
].send_new_account_infos(form
,
3682 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3683 self
.xml
.get_object('progressbar_label').set_markup(
3684 '<b>Account is being created</b>\n\nPlease wait...')
3685 self
.notebook
.set_current_page(5) # show creating page
3686 self
.back_button
.hide()
3687 self
.forward_button
.hide()
3688 self
.update_progressbar_timeout_id
= gobject
.timeout_add(100,
3689 self
.update_progressbar
)
3691 def update_proxy_list(self
):
3692 proxies_combobox
= self
.xml
.get_object('proxies_combobox')
3693 model
= gtk
.ListStore(str)
3694 proxies_combobox
.set_model(model
)
3695 l
= gajim
.config
.get_per('proxies')
3696 l
.insert(0, _('None'))
3697 for i
in xrange(len(l
)):
3698 model
.append([l
[i
]])
3699 proxies_combobox
.set_active(0)
3701 def on_manage_proxies_button_clicked(self
, widget
):
3702 if 'manage_proxies' in gajim
.interface
.instances
:
3703 gajim
.interface
.instances
['manage_proxies'].window
.present()
3705 gajim
.interface
.instances
['manage_proxies'] = \
3706 ManageProxiesWindow()
3708 def on_custom_host_port_checkbutton_toggled(self
, widget
):
3709 self
.xml
.get_object('custom_host_hbox').set_sensitive(widget
.\
3712 def update_progressbar(self
):
3713 self
.progressbar
.pulse()
3714 return True # loop forever
3716 def _nec_new_acc_connected(self
, obj
):
3718 Connection to server succeded, present the form to the user
3720 # We receive events from all accounts from GED
3721 if obj
.conn
.name
!= self
.account
:
3723 if self
.update_progressbar_timeout_id
is not None:
3724 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3725 self
.back_button
.show()
3726 self
.forward_button
.show()
3727 self
.is_form
= obj
.is_form
3729 dataform
= dataforms
.ExtendForm(node
=obj
.config
)
3730 self
.data_form_widget
= dataforms_widget
.DataFormWidget(dataform
)
3732 self
.data_form_widget
= FakeDataForm(obj
.config
)
3733 self
.data_form_widget
.show_all()
3734 self
.xml
.get_object('form_vbox').pack_start(self
.data_form_widget
)
3735 self
.ssl_fingerprint
= obj
.ssl_fingerprint
3736 self
.ssl_cert
= obj
.ssl_cert
3738 # An SSL warning occured, show it
3739 hostname
= gajim
.connections
[self
.account
].new_account_info
[
3741 self
.xml
.get_object('ssl_label').set_markup(_(
3742 '<b>Security Warning</b>'
3743 '\n\nThe authenticity of the %(hostname)s SSL certificate could'
3744 ' be invalid.\nSSL Error: %(error)s\n'
3745 'Do you still want to connect to this server?') % {
3746 'hostname': hostname
, 'error': obj
.ssl_msg
})
3747 if obj
.ssl_err
in (18, 27):
3748 text
= _('Add this certificate to the list of trusted '
3749 'certificates.\nSHA1 fingerprint of the certificate:\n%s') \
3750 % obj
.ssl_fingerprint
3751 self
.xml
.get_object('ssl_checkbutton').set_label(text
)
3753 self
.xml
.get_object('ssl_checkbutton').set_no_show_all(True)
3754 self
.xml
.get_object('ssl_checkbutton').hide()
3755 self
.notebook
.set_current_page(3) # show SSL page
3757 self
.notebook
.set_current_page(4) # show form page
3759 def _nec_new_acc_not_connected(self
, obj
):
3761 Account creation failed: connection to server failed
3763 # We receive events from all accounts from GED
3764 if obj
.conn
.name
!= self
.account
:
3766 if self
.account
not in gajim
.connections
:
3768 if self
.update_progressbar_timeout_id
is not None:
3769 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3770 del gajim
.connections
[self
.account
]
3771 if self
.account
in gajim
.config
.get_per('accounts'):
3772 gajim
.config
.del_per('accounts', self
.account
)
3773 self
.back_button
.show()
3774 self
.cancel_button
.show()
3775 self
.go_online_checkbutton
.hide()
3776 self
.show_vcard_checkbutton
.hide()
3777 img
= self
.xml
.get_object('finish_image')
3778 img
.set_from_stock(gtk
.STOCK_DIALOG_ERROR
, gtk
.ICON_SIZE_DIALOG
)
3779 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3780 _('An error occurred during account creation'), obj
.reason
)
3781 self
.finish_label
.set_markup(finish_text
)
3782 self
.notebook
.set_current_page(6) # show finish page
3784 def _nec_acc_is_ok(self
, obj
):
3786 Account creation succeeded
3788 # We receive events from all accounts from GED
3789 if obj
.conn
.name
!= self
.account
:
3791 self
.create_vars(obj
.account_info
)
3792 self
.show_finish_page()
3794 if self
.update_progressbar_timeout_id
is not None:
3795 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3797 def _nec_acc_is_not_ok(self
, obj
):
3799 Account creation failed
3801 # We receive events from all accounts from GED
3802 if obj
.conn
.name
!= self
.account
:
3804 self
.back_button
.show()
3805 self
.cancel_button
.show()
3806 self
.go_online_checkbutton
.hide()
3807 self
.show_vcard_checkbutton
.hide()
3808 del gajim
.connections
[self
.account
]
3809 if self
.account
in gajim
.config
.get_per('accounts'):
3810 gajim
.config
.del_per('accounts', self
.account
)
3811 img
= self
.xml
.get_object('finish_image')
3812 img
.set_from_stock(gtk
.STOCK_DIALOG_ERROR
, gtk
.ICON_SIZE_DIALOG
)
3813 finish_text
= '<big><b>%s</b></big>\n\n%s' % (_(
3814 'An error occurred during account creation'), obj
.reason
)
3815 self
.finish_label
.set_markup(finish_text
)
3816 self
.notebook
.set_current_page(6) # show finish page
3818 if self
.update_progressbar_timeout_id
is not None:
3819 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3821 def on_advanced_button_clicked(self
, widget
):
3822 if 'accounts' in gajim
.interface
.instances
:
3823 gajim
.interface
.instances
['accounts'].window
.present()
3825 gajim
.interface
.instances
['accounts'] = AccountsWindow()
3826 gajim
.interface
.instances
['accounts'].select_account(self
.account
)
3827 self
.window
.destroy()
3829 def on_finish_button_clicked(self
, widget
):
3830 go_online
= self
.xml
.get_object('go_online_checkbutton').get_active()
3831 show_vcard
= self
.xml
.get_object('show_vcard_checkbutton').get_active()
3832 self
.window
.destroy()
3834 gajim
.interface
.show_vcard_when_connect
.append(self
.account
)
3836 gajim
.interface
.roster
.send_status(self
.account
, 'online', '')
3838 def on_username_entry_key_press_event(self
, widget
, event
):
3839 # Check for pressed @ and jump to combobox if found
3840 if event
.keyval
== gtk
.keysyms
.at
:
3841 combobox
= self
.xml
.get_object('server_comboboxentry')
3842 combobox
.grab_focus()
3843 combobox
.child
.set_position(-1)
3846 def on_server_comboboxentry_key_press_event(self
, widget
, event
, combobox
):
3847 # If backspace is pressed in empty field, return to the nick entry field
3848 backspace
= event
.keyval
== gtk
.keysyms
.BackSpace
3849 empty
= len(combobox
.get_active_text()) == 0
3850 if backspace
and empty
and self
.modify
:
3851 username_entry
= self
.xml
.get_object('username_entry')
3852 username_entry
.grab_focus()
3853 username_entry
.set_position(-1)
3856 def get_config(self
, login
, server
, savepass
, password
, anonymous
=False):
3858 config
['name'] = login
3859 config
['hostname'] = server
3860 config
['savepass'] = savepass
3861 config
['password'] = password
3862 config
['resource'] = 'Gajim'
3863 config
['anonymous_auth'] = anonymous
3864 config
['priority'] = 5
3865 config
['autoconnect'] = True
3866 config
['no_log_for'] = ''
3867 config
['sync_with_global_status'] = True
3868 config
['proxy'] = ''
3869 config
['usessl'] = False
3870 config
['use_custom_host'] = False
3871 config
['custom_port'] = 0
3872 config
['custom_host'] = ''
3873 config
['keyname'] = ''
3874 config
['keyid'] = ''
3877 def save_account(self
, login
, server
, savepass
, password
, anonymous
=False):
3878 if self
.account
in gajim
.connections
:
3879 dialogs
.ErrorDialog(_('Account name is in use'),
3880 _('You already have an account using this name.'))
3882 con
= connection
.Connection(self
.account
)
3883 con
.password
= password
3885 config
= self
.get_config(login
, server
, savepass
, password
, anonymous
)
3888 con
.new_account(self
.account
, config
)
3890 gajim
.connections
[self
.account
] = con
3891 self
.create_vars(config
)
3893 def create_vars(self
, config
):
3894 gajim
.config
.add_per('accounts', self
.account
)
3896 if not config
['savepass']:
3897 config
['password'] = ''
3900 gajim
.config
.set_per('accounts', self
.account
, opt
, config
[opt
])
3903 gajim
.interface
.instances
[self
.account
] = {'infos': {}, 'disco': {},
3904 'gc_config': {}, 'search': {}, 'online_dialog': {}}
3905 gajim
.interface
.minimized_controls
[self
.account
] = {}
3906 gajim
.connections
[self
.account
].connected
= 0
3907 gajim
.connections
[self
.account
].keepalives
= gajim
.config
.get_per(
3908 'accounts', self
.account
, 'keep_alive_every_foo_secs')
3909 gajim
.groups
[self
.account
] = {}
3910 gajim
.contacts
.add_account(self
.account
)
3911 gajim
.gc_connected
[self
.account
] = {}
3912 gajim
.automatic_rooms
[self
.account
] = {}
3913 gajim
.newly_added
[self
.account
] = []
3914 gajim
.to_be_removed
[self
.account
] = []
3915 gajim
.nicks
[self
.account
] = config
['name']
3916 gajim
.block_signed_in_notifications
[self
.account
] = True
3917 gajim
.sleeper_state
[self
.account
] = 'off'
3918 gajim
.encrypted_chats
[self
.account
] = []
3919 gajim
.last_message_time
[self
.account
] = {}
3920 gajim
.status_before_autoaway
[self
.account
] = ''
3921 gajim
.transport_avatar
[self
.account
] = {}
3922 gajim
.gajim_optional_features
[self
.account
] = []
3923 gajim
.caps_hash
[self
.account
] = ''
3924 # refresh accounts window
3925 if 'accounts' in gajim
.interface
.instances
:
3926 gajim
.interface
.instances
['accounts'].init_accounts()
3928 if len(gajim
.connections
) >= 2:
3929 # Do not merge accounts if only one exists
3930 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
3932 gajim
.interface
.roster
.regroup
= False
3933 gajim
.interface
.roster
.setup_and_draw_roster()
3934 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3935 gajim
.interface
.save_config()
3937 class ManagePEPServicesWindow
:
3938 def __init__(self
, account
):
3939 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_pep_services_window.ui')
3940 self
.window
= self
.xml
.get_object('manage_pep_services_window')
3941 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3942 self
.xml
.get_object('configure_button').set_sensitive(False)
3943 self
.xml
.get_object('delete_button').set_sensitive(False)
3944 self
.xml
.connect_signals(self
)
3945 self
.account
= account
3947 self
.init_services()
3948 self
.xml
.get_object('services_treeview').get_selection().connect(
3949 'changed', self
.on_services_selection_changed
)
3951 gajim
.ged
.register_event_handler('pep-config-received', ged
.GUI1
,
3952 self
._nec
_pep
_config
_received
)
3953 gajim
.ged
.register_event_handler('agent-items-received', ged
.GUI1
,
3954 self
._nec
_agent
_items
_received
)
3956 self
.window
.show_all()
3958 def on_manage_pep_services_window_destroy(self
, widget
):
3960 del gajim
.interface
.instances
[self
.account
]['pep_services']
3961 gajim
.ged
.remove_event_handler('pep-config-received', ged
.GUI1
,
3962 self
._nec
_pep
_config
_received
)
3963 gajim
.ged
.remove_event_handler('agent-items-received', ged
.GUI1
,
3964 self
._nec
_agent
_items
_received
)
3966 def on_close_button_clicked(self
, widget
):
3967 self
.window
.destroy()
3969 def on_services_selection_changed(self
, sel
):
3970 self
.xml
.get_object('configure_button').set_sensitive(True)
3971 self
.xml
.get_object('delete_button').set_sensitive(True)
3973 def init_services(self
):
3974 self
.treeview
= self
.xml
.get_object('services_treeview')
3975 # service, access_model, group
3976 self
.treestore
= gtk
.ListStore(str)
3977 self
.treeview
.set_model(self
.treestore
)
3979 col
= gtk
.TreeViewColumn('Service')
3980 self
.treeview
.append_column(col
)
3982 cellrenderer_text
= gtk
.CellRendererText()
3983 col
.pack_start(cellrenderer_text
)
3984 col
.add_attribute(cellrenderer_text
, 'text', 0)
3986 our_jid
= gajim
.get_jid_from_account(self
.account
)
3987 gajim
.connections
[self
.account
].discoverItems(our_jid
)
3989 def _nec_agent_items_received(self
, obj
):
3990 our_jid
= gajim
.get_jid_from_account(self
.account
)
3991 for item
in obj
.items
:
3992 if 'jid' in item
and item
['jid'] == our_jid
and 'node' in item
:
3993 self
.treestore
.append([item
['node']])
3995 def node_removed(self
, jid
, node
):
3996 if jid
!= gajim
.get_jid_from_account(self
.account
):
3998 model
= self
.treeview
.get_model()
3999 iter_
= model
.get_iter_root()
4001 if model
[iter_
][0] == node
:
4004 iter_
= model
.iter_next(iter_
)
4006 def node_not_removed(self
, jid
, node
, msg
):
4007 if jid
!= gajim
.get_jid_from_account(self
.account
):
4009 dialogs
.WarningDialog(_('PEP node was not removed'),
4010 _('PEP node %(node)s was not removed: %(message)s') % {'node': node
,
4013 def on_delete_button_clicked(self
, widget
):
4014 selection
= self
.treeview
.get_selection()
4017 model
, iter_
= selection
.get_selected()
4018 node
= model
[iter_
][0]
4019 our_jid
= gajim
.get_jid_from_account(self
.account
)
4020 gajim
.connections
[self
.account
].send_pb_delete(our_jid
, node
,
4021 on_ok
=self
.node_removed
, on_fail
=self
.node_not_removed
)
4023 def on_configure_button_clicked(self
, widget
):
4024 selection
= self
.treeview
.get_selection()
4027 model
, iter_
= selection
.get_selected()
4028 node
= model
[iter_
][0]
4029 our_jid
= gajim
.get_jid_from_account(self
.account
)
4030 gajim
.connections
[self
.account
].request_pb_configuration(our_jid
, node
)
4032 def _nec_pep_config_received(self
, obj
):
4033 def on_ok(form
, node
):
4034 form
.type = 'submit'
4035 our_jid
= gajim
.get_jid_from_account(self
.account
)
4036 gajim
.connections
[self
.account
].send_pb_configure(our_jid
, node
, form
)
4037 window
= dialogs
.DataFormWindow(obj
.form
, (on_ok
, obj
.node
))
4038 title
= _('Configure %s') % obj
.node
4039 window
.set_title(title
)
4042 class ManageSoundsWindow
:
4044 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_sounds_window.ui')
4045 self
.window
= self
.xml
.get_object('manage_sounds_window')
4048 self
.sound_tree
= self
.xml
.get_object('sounds_treeview')
4050 # active, event ui name, path to sound file, event_config_name
4051 model
= gtk
.ListStore(bool, str, str, str)
4052 self
.sound_tree
.set_model(model
)
4054 col
= gtk
.TreeViewColumn(_('Active'))
4055 self
.sound_tree
.append_column(col
)
4056 renderer
= gtk
.CellRendererToggle()
4057 renderer
.set_property('activatable', True)
4058 renderer
.connect('toggled', self
.sound_toggled_cb
)
4059 col
.pack_start(renderer
)
4060 col
.set_attributes(renderer
, active
= 0)
4062 col
= gtk
.TreeViewColumn(_('Event'))
4063 self
.sound_tree
.append_column(col
)
4064 renderer
= gtk
.CellRendererText()
4065 col
.pack_start(renderer
)
4066 col
.set_attributes(renderer
, text
= 1)
4068 self
.fill_sound_treeview()
4070 self
.xml
.connect_signals(self
)
4072 self
.sound_tree
.get_model().connect('row-changed',
4073 self
.on_sounds_treemodel_row_changed
)
4075 self
.window
.show_all()
4077 def on_sounds_treemodel_row_changed(self
, model
, path
, iter_
):
4078 sound_event
= model
[iter_
][3].decode('utf-8')
4079 gajim
.config
.set_per('soundevents', sound_event
, 'enabled',
4080 bool(model
[path
][0]))
4081 gajim
.config
.set_per('soundevents', sound_event
, 'path',
4082 model
[iter_
][2].decode('utf-8'))
4083 gajim
.interface
.save_config()
4085 def sound_toggled_cb(self
, cell
, path
):
4086 model
= self
.sound_tree
.get_model()
4087 model
[path
][0] = not model
[path
][0]
4089 def fill_sound_treeview(self
):
4090 model
= self
.sound_tree
.get_model()
4092 model
.set_sort_column_id(1, gtk
.SORT_ASCENDING
)
4094 # NOTE: sounds_ui_names MUST have all items of
4095 # sounds = gajim.config.get_per('soundevents') as keys
4097 'first_message_received': _('First Message Received'),
4098 'next_message_received_focused': _('Next Message Received Focused'),
4099 'next_message_received_unfocused':
4100 _('Next Message Received Unfocused'),
4101 'contact_connected': _('Contact Connected'),
4102 'contact_disconnected': _('Contact Disconnected'),
4103 'message_sent': _('Message Sent'),
4104 'muc_message_highlight': _('Group Chat Message Highlight'),
4105 'muc_message_received': _('Group Chat Message Received'),
4106 'gmail_received': _('GMail Email Received')
4109 for sound_event_config_name
, sound_ui_name
in sounds_dict
.items():
4110 enabled
= gajim
.config
.get_per('soundevents',
4111 sound_event_config_name
, 'enabled')
4112 path
= gajim
.config
.get_per('soundevents',
4113 sound_event_config_name
, 'path')
4114 model
.append((enabled
, sound_ui_name
, path
, sound_event_config_name
))
4116 def on_treeview_sounds_cursor_changed(self
, widget
, data
= None):
4117 (model
, iter_
) = self
.sound_tree
.get_selection().get_selected()
4118 sounds_entry
= self
.xml
.get_object('sounds_entry')
4120 sounds_entry
.set_text('')
4122 path_to_snd_file
= model
[iter_
][2]
4123 sounds_entry
.set_text(path_to_snd_file
)
4125 def on_browse_for_sounds_button_clicked(self
, widget
, data
= None):
4126 (model
, iter_
) = self
.sound_tree
.get_selection().get_selected()
4129 def on_ok(widget
, path_to_snd_file
):
4130 self
.dialog
.destroy()
4131 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4132 if not path_to_snd_file
:
4133 model
[iter_
][2] = ''
4134 self
.xml
.get_object('sounds_entry').set_text('')
4135 model
[iter_
][0] = False
4137 directory
= os
.path
.dirname(path_to_snd_file
)
4138 gajim
.config
.set('last_sounds_dir', directory
)
4139 path_to_snd_file
= helpers
.strip_soundfile_path(path_to_snd_file
)
4140 self
.xml
.get_object('sounds_entry').set_text(path_to_snd_file
)
4142 model
[iter_
][2] = path_to_snd_file
# set new path to sounds_model
4143 model
[iter_
][0] = True # set the sound to enabled
4145 def on_cancel(widget
):
4146 self
.dialog
.destroy()
4148 path_to_snd_file
= model
[iter_
][2].decode('utf-8')
4149 self
.dialog
= dialogs
.SoundChooserDialog(path_to_snd_file
, on_ok
,
4152 def on_sounds_entry_changed(self
, widget
):
4153 path_to_snd_file
= widget
.get_text()
4154 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4155 model
[iter_
][2] = path_to_snd_file
# set new path to sounds_model
4157 def on_play_button_clicked(self
, widget
):
4158 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4161 snd_event_config_name
= model
[iter_
][3]
4162 helpers
.play_sound(snd_event_config_name
)
4164 def on_close_button_clicked(self
, widget
):
4167 def on_manage_sounds_window_delete_event(self
, widget
, event
):
4169 return True # do NOT destroy the window