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)
186 # Show roster on startup
187 show_roster_combobox
= self
.xml
.get_object('show_roster_on_startup')
188 choices
= common
.config
.opt_show_roster_on_startup
189 type_
= gajim
.config
.get('show_roster_on_startup')
191 show_roster_combobox
.set_active(choices
.index(type_
))
193 show_roster_combobox
.set_active(0)
196 st
= gajim
.config
.get('compact_view')
197 self
.xml
.get_object('compact_view_checkbutton').set_active(st
)
200 st
= gajim
.config
.get('ignore_incoming_xhtml')
201 self
.xml
.get_object('xhtml_checkbutton').set_active(st
)
205 st
= gajim
.config
.get('use_speller')
206 self
.xml
.get_object('speller_checkbutton').set_active(st
)
208 self
.xml
.get_object('speller_checkbutton').set_sensitive(False)
212 theme_combobox
= self
.xml
.get_object('theme_combobox')
213 cell
= gtk
.CellRendererText()
214 theme_combobox
.pack_start(cell
, True)
215 theme_combobox
.add_attribute(cell
, 'text', 0)
216 self
.update_theme_list()
219 iconsets_list
= os
.listdir(os
.path
.join(gajim
.DATA_DIR
, 'iconsets'))
220 if os
.path
.isdir(gajim
.MY_ICONSETS_PATH
):
221 iconsets_list
+= os
.listdir(gajim
.MY_ICONSETS_PATH
)
222 # new model, image in 0, string in 1
223 model
= gtk
.ListStore(gtk
.Image
, str)
224 renderer_image
= cell_renderer_image
.CellRendererImage(0, 0)
225 renderer_text
= gtk
.CellRendererText()
226 renderer_text
.set_property('xpad', 5)
227 self
.iconset_combobox
.pack_start(renderer_image
, expand
= False)
228 self
.iconset_combobox
.pack_start(renderer_text
, expand
= True)
229 self
.iconset_combobox
.set_attributes(renderer_text
, text
= 1)
230 self
.iconset_combobox
.add_attribute(renderer_image
, 'image', 0)
231 self
.iconset_combobox
.set_model(model
)
233 for dir in iconsets_list
:
234 if not os
.path
.isdir(os
.path
.join(gajim
.DATA_DIR
, 'iconsets', dir)) \
235 and not os
.path
.isdir(os
.path
.join(gajim
.MY_ICONSETS_PATH
, dir)):
237 if dir != '.svn' and dir != 'transports':
241 for i
in xrange(len(l
)):
242 preview
= gtk
.Image()
244 files
.append(os
.path
.join(helpers
.get_iconset_path(l
[i
]), '16x16',
246 files
.append(os
.path
.join(helpers
.get_iconset_path(l
[i
]), '16x16',
249 if os
.path
.exists(file_
):
250 preview
.set_from_file(file_
)
251 model
.append([preview
, l
[i
]])
252 if gajim
.config
.get('iconset') == l
[i
]:
253 self
.iconset_combobox
.set_active(i
)
255 # Use transports iconsets
256 st
= gajim
.config
.get('use_transports_iconsets')
257 self
.xml
.get_object('transports_iconsets_checkbutton').set_active(st
)
260 self
.draw_color_widgets()
263 font
= gajim
.config
.get('conversation_font')
264 # try to set default font for the current desktop env
265 fontbutton
= self
.xml
.get_object('conversation_fontbutton')
267 fontbutton
.set_sensitive(False)
268 self
.xml
.get_object('default_chat_font').set_active(True)
270 fontbutton
.set_font_name(font
)
272 ### Personal Events tab ###
273 # outgoing send chat state notifications
274 st
= gajim
.config
.get('outgoing_chat_state_notifications')
275 combo
= self
.xml
.get_object('outgoing_chat_states_combobox')
278 elif st
== 'composing_only':
283 # displayed send chat state notifications
284 st
= gajim
.config
.get('displayed_chat_state_notifications')
285 combo
= self
.xml
.get_object('displayed_chat_states_combobox')
288 elif st
== 'composing_only':
294 ### Notifications tab ###
296 on_event_combobox
= self
.xml
.get_object('on_event_combobox')
297 if gajim
.config
.get('autopopup'):
298 on_event_combobox
.set_active(0)
299 elif gajim
.config
.get('notify_on_new_message'):
300 on_event_combobox
.set_active(1)
302 on_event_combobox
.set_active(2)
304 # notify on online statuses
305 st
= gajim
.config
.get('notify_on_signin')
306 self
.notify_on_signin_checkbutton
.set_active(st
)
308 # notify on offline statuses
309 st
= gajim
.config
.get('notify_on_signout')
310 self
.notify_on_signout_checkbutton
.set_active(st
)
313 st
= gajim
.config
.get('autopopupaway')
314 self
.auto_popup_away_checkbutton
.set_active(st
)
317 st
= gajim
.config
.get('sounddnd')
318 self
.sound_dnd_checkbutton
.set_active(st
)
321 systray_combobox
= self
.xml
.get_object('systray_combobox')
322 if gajim
.config
.get('trayicon') == 'never':
323 systray_combobox
.set_active(0)
324 elif gajim
.config
.get('trayicon') == 'on_event':
325 systray_combobox
.set_active(1)
327 systray_combobox
.set_active(2)
330 if gajim
.config
.get('sounds_on'):
331 self
.xml
.get_object('play_sounds_checkbutton').set_active(True)
333 self
.xml
.get_object('manage_sounds_button').set_sensitive(False)
335 # Notify user of new gmail e-mail messages,
336 # make checkbox sensitive if user has a gtalk account
337 frame_gmail
= self
.xml
.get_object('frame_gmail')
338 notify_gmail_checkbutton
= self
.xml
.get_object('notify_gmail_checkbutton')
339 notify_gmail_extra_checkbutton
= self
.xml
.get_object(
340 'notify_gmail_extra_checkbutton')
342 for account
in gajim
.config
.get_per('accounts'):
343 jid
= gajim
.get_jid_from_account(account
)
344 if gajim
.get_server_from_jid(jid
) in gajim
.gmail_domains
:
345 frame_gmail
.set_sensitive(True)
346 st
= gajim
.config
.get('notify_on_new_gmail_email')
347 notify_gmail_checkbutton
.set_active(st
)
348 st
= gajim
.config
.get('notify_on_new_gmail_email_extra')
349 notify_gmail_extra_checkbutton
.set_active(st
)
354 st
= gajim
.config
.get('autoaway')
355 self
.auto_away_checkbutton
.set_active(st
)
358 st
= gajim
.config
.get('autoawaytime')
359 self
.auto_away_time_spinbutton
.set_value(st
)
360 self
.auto_away_time_spinbutton
.set_sensitive(gajim
.config
.get('autoaway'))
363 st
= gajim
.config
.get('autoaway_message')
364 self
.auto_away_message_entry
.set_text(st
)
365 self
.auto_away_message_entry
.set_sensitive(gajim
.config
.get('autoaway'))
368 st
= gajim
.config
.get('autoxa')
369 self
.auto_xa_checkbutton
.set_active(st
)
372 st
= gajim
.config
.get('autoxatime')
373 self
.auto_xa_time_spinbutton
.set_value(st
)
374 self
.auto_xa_time_spinbutton
.set_sensitive(gajim
.config
.get('autoxa'))
377 st
= gajim
.config
.get('autoxa_message')
378 self
.auto_xa_message_entry
.set_text(st
)
379 self
.auto_xa_message_entry
.set_sensitive(gajim
.config
.get('autoxa'))
381 from common
import sleepy
382 if not sleepy
.SUPPORTED
:
383 self
.xml
.get_object('autoaway_table').set_sensitive(False)
385 # ask_status when online / offline
386 st
= gajim
.config
.get('ask_online_status')
387 self
.xml
.get_object('prompt_online_status_message_checkbutton').\
389 st
= gajim
.config
.get('ask_offline_status')
390 self
.xml
.get_object('prompt_offline_status_message_checkbutton').\
393 # Default Status messages
394 self
.default_msg_tree
= self
.xml
.get_object('default_msg_treeview')
395 col2
= self
.default_msg_tree
.rc_get_style().bg
[gtk
.STATE_ACTIVE
].\
397 # (status, translated_status, message, enabled)
398 model
= gtk
.ListStore(str, str, str, bool)
399 self
.default_msg_tree
.set_model(model
)
400 col
= gtk
.TreeViewColumn(_('Status'))
401 col
.set_resizable(True)
402 self
.default_msg_tree
.append_column(col
)
403 renderer
= gtk
.CellRendererText()
404 col
.pack_start(renderer
, False)
405 col
.set_attributes(renderer
, text
= 1)
406 col
= gtk
.TreeViewColumn(_('Default Message'))
407 col
.set_resizable(True)
408 self
.default_msg_tree
.append_column(col
)
409 renderer
= gtk
.CellRendererText()
410 col
.pack_start(renderer
, True)
411 col
.set_attributes(renderer
, text
= 2)
412 renderer
.connect('edited', self
.on_default_msg_cell_edited
)
413 renderer
.set_property('editable', True)
414 renderer
.set_property('cell-background', col2
)
415 col
= gtk
.TreeViewColumn(_('Enabled'))
416 col
.set_resizable(True)
417 self
.default_msg_tree
.append_column(col
)
418 renderer
= gtk
.CellRendererToggle()
419 col
.pack_start(renderer
, False)
420 col
.set_attributes(renderer
, active
= 3)
421 renderer
.set_property('activatable', True)
422 renderer
.connect('toggled', self
.default_msg_toggled_cb
)
423 self
.fill_default_msg_treeview()
426 self
.msg_tree
= self
.xml
.get_object('msg_treeview')
427 model
= gtk
.ListStore(str, str, str, str, str, str, str)
428 self
.msg_tree
.set_model(model
)
429 col
= gtk
.TreeViewColumn('name')
430 self
.msg_tree
.append_column(col
)
431 renderer
= gtk
.CellRendererText()
432 col
.pack_start(renderer
, True)
433 col
.set_attributes(renderer
, text
= 0)
434 renderer
.connect('edited', self
.on_msg_cell_edited
)
435 renderer
.set_property('editable', True)
436 self
.fill_msg_treeview()
437 buf
= self
.xml
.get_object('msg_textview').get_buffer()
438 buf
.connect('changed', self
.on_msg_textview_changed
)
440 ### Audio / Video tab ###
441 def create_av_combobox(opt_name
, device_dict
, config_name
=None,
443 combobox
= self
.xml
.get_object(opt_name
+ '_combobox')
444 cell
= gtk
.CellRendererText()
445 combobox
.pack_start(cell
, True)
446 combobox
.add_attribute(cell
, 'text', 0)
447 model
= gtk
.ListStore(str, str)
448 combobox
.set_model(model
)
450 config
= gajim
.config
.get(config_name
)
452 config
= gajim
.config
.get(opt_name
+ '_device')
454 for index
, (name
, value
) in enumerate(sorted(device_dict
.\
455 iteritems(), key
=key
)):
456 model
.append((name
, value
))
458 combobox
.set_active(index
)
461 create_av_combobox('audio_input', AudioInputManager().get_devices())
462 create_av_combobox('audio_output', AudioOutputManager().get_devices(
464 create_av_combobox('video_input', VideoInputManager().get_devices())
465 create_av_combobox('video_output', VideoOutputManager().get_devices(
468 create_av_combobox('video_framerate', {_('Default'): '',
469 '15fps': '15/1', '10fps': '10/1', '5fps': '5/1',
470 '2.5fps': '5/2'}, 'video_framerate', key
=lambda x
: -1 if \
471 not x
[1] else float(x
[0][:-3]))
472 create_av_combobox('video_size', {_('Default'): '',
473 '800x600': '800x600', '640x480': '640x480',
474 '320x240': '320x240'}, 'video_size', key
=lambda x
: -1 if \
475 not x
[1] else int(x
[0][:3]))
478 for opt_name
in ('audio_input', 'audio_output', 'video_input',
479 'video_output', 'video_framerate', 'video_size'):
480 combobox
= self
.xml
.get_object(opt_name
+ '_combobox')
481 combobox
.set_sensitive(False)
484 cb
= self
.xml
.get_object('stun_checkbutton')
485 st
= gajim
.config
.get('use_stun_server')
488 entry
= self
.xml
.get_object('stun_server_entry')
489 entry
.set_text(gajim
.config
.get('stun_server'))
491 entry
.set_sensitive(False)
496 applications_frame
= self
.xml
.get_object('applications_frame')
497 applications_frame
.set_no_show_all(True)
498 applications_frame
.hide()
500 self
.applications_combobox
= self
.xml
.get_object(
501 'applications_combobox')
502 self
.xml
.get_object('custom_apps_frame').hide()
503 self
.xml
.get_object('custom_apps_frame').set_no_show_all(True)
505 if gajim
.config
.get('autodetect_browser_mailer'):
506 self
.applications_combobox
.set_active(0)
507 # else autodetect_browser_mailer is False.
508 # so user has 'Always Use GNOME/KDE/Xfce' or Custom
509 elif gajim
.config
.get('openwith') == 'custom':
510 self
.applications_combobox
.set_active(1)
511 self
.xml
.get_object('custom_apps_frame').show()
513 self
.xml
.get_object('custom_browser_entry').set_text(
514 gajim
.config
.get('custombrowser'))
515 self
.xml
.get_object('custom_mail_client_entry').set_text(
516 gajim
.config
.get('custommailapp'))
517 self
.xml
.get_object('custom_file_manager_entry').set_text(
518 gajim
.config
.get('custom_file_manager'))
520 # log status changes of contacts
521 st
= gajim
.config
.get('log_contact_status_changes')
522 self
.xml
.get_object('log_show_changes_checkbutton').set_active(st
)
524 # log encrypted chat sessions
525 w
= self
.xml
.get_object('log_encrypted_chats_checkbutton')
526 st
= self
.get_per_account_option('log_encrypted_sessions')
528 w
.set_inconsistent(True)
533 w
= self
.xml
.get_object('send_os_info_checkbutton')
534 st
= self
.get_per_account_option('send_os_info')
536 w
.set_inconsistent(True)
541 w
= self
.xml
.get_object('send_idle_time_checkbutton')
542 st
= self
.get_per_account_option('send_idle_time')
544 w
.set_inconsistent(True)
548 # check if gajm is default
549 st
= gajim
.config
.get('check_if_gajim_is_default')
550 self
.xml
.get_object('check_default_client_checkbutton').set_active(st
)
552 # Ignore messages from unknown contacts
553 w
= self
.xml
.get_object('ignore_events_from_unknown_contacts_checkbutton')
554 st
= self
.get_per_account_option('ignore_unknown_contacts')
556 w
.set_inconsistent(True)
560 self
.xml
.connect_signals(self
)
562 self
.msg_tree
.get_model().connect('row-changed',
563 self
.on_msg_treemodel_row_changed
)
564 self
.msg_tree
.get_model().connect('row-deleted',
565 self
.on_msg_treemodel_row_deleted
)
566 self
.default_msg_tree
.get_model().connect('row-changed',
567 self
.on_default_msg_treemodel_row_changed
)
569 self
.theme_preferences
= None
570 self
.sounds_preferences
= None
572 self
.notebook
.set_current_page(0)
574 self
.window
.show_all()
575 gtkgui_helpers
.possibly_move_window_in_current_desktop(self
.window
)
577 def on_preferences_window_key_press_event(self
, widget
, event
):
578 if event
.keyval
== gtk
.keysyms
.Escape
:
581 def get_per_account_option(self
, opt
):
583 Return the value of the option opt if it's the same in all accounts else
586 if len(gajim
.connections
) == 0:
587 # a non existant key return default value
588 return gajim
.config
.get_per('accounts', '__default__', opt
)
590 for account
in gajim
.connections
:
591 v
= gajim
.config
.get_per('accounts', account
, opt
)
598 def on_checkbutton_toggled(self
, widget
, config_name
,
599 change_sensitivity_widgets
=None):
600 gajim
.config
.set(config_name
, widget
.get_active())
601 if change_sensitivity_widgets
:
602 for w
in change_sensitivity_widgets
:
603 w
.set_sensitive(widget
.get_active())
604 gajim
.interface
.save_config()
606 def on_per_account_checkbutton_toggled(self
, widget
, config_name
,
607 change_sensitivity_widgets
=None):
608 for account
in gajim
.connections
:
609 gajim
.config
.set_per('accounts', account
, config_name
,
611 if change_sensitivity_widgets
:
612 for w
in change_sensitivity_widgets
:
613 w
.set_sensitive(widget
.get_active())
614 gajim
.interface
.save_config()
616 def _get_all_controls(self
):
617 for ctrl
in gajim
.interface
.msg_win_mgr
.get_controls():
619 for account
in gajim
.connections
:
620 for ctrl
in gajim
.interface
.minimized_controls
[account
].values():
623 def _get_all_muc_controls(self
):
624 for ctrl
in gajim
.interface
.msg_win_mgr
.get_controls(
625 message_control
.TYPE_GC
):
627 for account
in gajim
.connections
:
628 for ctrl
in gajim
.interface
.minimized_controls
[account
].values():
631 def on_sort_by_show_in_roster_checkbutton_toggled(self
, widget
):
632 self
.on_checkbutton_toggled(widget
, 'sort_by_show_in_roster')
633 gajim
.interface
.roster
.setup_and_draw_roster()
635 def on_sort_by_show_in_muc_checkbutton_toggled(self
, widget
):
636 self
.on_checkbutton_toggled(widget
, 'sort_by_show_in_muc')
638 for ctrl
in self
._get
_all
_muc
_controls
():
641 def on_show_avatars_in_roster_checkbutton_toggled(self
, widget
):
642 self
.on_checkbutton_toggled(widget
, 'show_avatars_in_roster')
643 gajim
.interface
.roster
.setup_and_draw_roster()
644 # Redraw groupchats (in an ugly way)
645 for ctrl
in self
._get
_all
_muc
_controls
():
648 def on_show_status_msgs_in_roster_checkbutton_toggled(self
, widget
):
649 self
.on_checkbutton_toggled(widget
, 'show_status_msgs_in_roster')
650 gajim
.interface
.roster
.setup_and_draw_roster()
651 for ctrl
in self
._get
_all
_muc
_controls
():
654 def on_show_mood_in_roster_checkbutton_toggled(self
, widget
):
655 self
.on_checkbutton_toggled(widget
, 'show_mood_in_roster')
656 gajim
.interface
.roster
.setup_and_draw_roster()
658 def on_show_activity_in_roster_checkbutton_toggled(self
, widget
):
659 self
.on_checkbutton_toggled(widget
, 'show_activity_in_roster')
660 gajim
.interface
.roster
.setup_and_draw_roster()
662 def on_show_tunes_in_roster_checkbutton_toggled(self
, widget
):
663 self
.on_checkbutton_toggled(widget
, 'show_tunes_in_roster')
664 gajim
.interface
.roster
.setup_and_draw_roster()
666 def on_show_location_in_roster_checkbutton_toggled(self
, widget
):
667 self
.on_checkbutton_toggled(widget
, 'show_location_in_roster')
668 gajim
.interface
.roster
.setup_and_draw_roster()
670 def on_emoticons_combobox_changed(self
, widget
):
671 active
= widget
.get_active()
672 model
= widget
.get_model()
673 emot_theme
= model
[active
][0].decode('utf-8')
674 if emot_theme
== _('Disabled'):
675 gajim
.config
.set('emoticons_theme', '')
677 gajim
.config
.set('emoticons_theme', emot_theme
)
679 gajim
.interface
.init_emoticons(need_reload
= True)
680 gajim
.interface
.make_regexps()
681 self
.toggle_emoticons()
683 def toggle_emoticons(self
):
685 Update emoticons state in Opened Chat Windows
687 for ctrl
in self
._get
_all
_controls
():
688 ctrl
.toggle_emoticons()
690 def on_one_window_type_combo_changed(self
, widget
):
691 active
= widget
.get_active()
692 config_type
= common
.config
.opt_one_window_types
[active
]
693 gajim
.config
.set('one_message_window', config_type
)
694 gajim
.interface
.save_config()
695 gajim
.interface
.msg_win_mgr
.reconfig()
697 def on_show_roster_on_startup_changed(self
, widget
):
698 active
= widget
.get_active()
699 config_type
= common
.config
.opt_show_roster_on_startup
[active
]
700 gajim
.config
.set('show_roster_on_startup', config_type
)
701 gajim
.interface
.save_config()
703 def on_compact_view_checkbutton_toggled(self
, widget
):
704 active
= widget
.get_active()
705 for ctrl
in self
._get
_all
_controls
():
706 ctrl
.chat_buttons_set_visible(active
)
707 gajim
.config
.set('compact_view', active
)
708 gajim
.interface
.save_config()
710 def on_xhtml_checkbutton_toggled(self
, widget
):
711 self
.on_checkbutton_toggled(widget
, 'ignore_incoming_xhtml')
712 helpers
.update_optional_features()
714 def apply_speller(self
):
715 for ctrl
in self
._get
_all
_controls
():
716 if isinstance(ctrl
, chat_control
.ChatControlBase
):
718 spell_obj
= gtkspell
.get_from_text_view(ctrl
.msg_textview
)
719 except (TypeError, RuntimeError, OSError):
725 def remove_speller(self
):
726 for ctrl
in self
._get
_all
_controls
():
727 if isinstance(ctrl
, chat_control
.ChatControlBase
):
729 spell_obj
= gtkspell
.get_from_text_view(ctrl
.msg_textview
)
730 except (TypeError, RuntimeError):
735 def on_speller_checkbutton_toggled(self
, widget
):
736 active
= widget
.get_active()
737 gajim
.config
.set('use_speller', active
)
738 gajim
.interface
.save_config()
740 lang
= gajim
.config
.get('speller_language')
745 gtkspell
.Spell(tv
, lang
)
746 except (TypeError, RuntimeError, OSError):
748 _('Dictionary for lang %s not available') % lang
,
749 _('You have to install %s dictionary to use spellchecking, or '
750 'choose another language by setting the speller_language option.'
752 gajim
.config
.set('use_speller', False)
753 widget
.set_active(False)
755 gajim
.config
.set('speller_language', lang
)
758 self
.remove_speller()
760 def on_theme_combobox_changed(self
, widget
):
761 model
= widget
.get_model()
762 active
= widget
.get_active()
763 config_theme
= model
[active
][0].decode('utf-8').replace(' ', '_')
765 gajim
.config
.set('roster_theme', config_theme
)
767 # begin repainting themed widgets throughout
768 gajim
.interface
.roster
.repaint_themed_widgets()
769 gajim
.interface
.roster
.change_roster_style(None)
770 gajim
.interface
.save_config()
772 def update_theme_list(self
):
773 theme_combobox
= self
.xml
.get_object('theme_combobox')
774 model
= gtk
.ListStore(str)
775 theme_combobox
.set_model(model
)
777 for config_theme
in gajim
.config
.get_per('themes'):
778 theme
= config_theme
.replace('_', ' ')
779 model
.append([theme
])
780 if gajim
.config
.get('roster_theme') == config_theme
:
781 theme_combobox
.set_active(i
)
784 def on_manage_theme_button_clicked(self
, widget
):
785 if self
.theme_preferences
is None:
786 self
.theme_preferences
= dialogs
.GajimThemesWindow()
788 self
.theme_preferences
.window
.present()
789 self
.theme_preferences
.select_active_theme()
791 def on_iconset_combobox_changed(self
, widget
):
792 model
= widget
.get_model()
793 active
= widget
.get_active()
794 icon_string
= model
[active
][1].decode('utf-8')
795 gajim
.config
.set('iconset', icon_string
)
796 gtkgui_helpers
.reload_jabber_state_images()
797 gajim
.interface
.save_config()
799 def on_transports_iconsets_checkbutton_toggled(self
, widget
):
800 self
.on_checkbutton_toggled(widget
, 'use_transports_iconsets')
801 gtkgui_helpers
.reload_jabber_state_images()
803 def on_outgoing_chat_states_combobox_changed(self
, widget
):
804 active
= widget
.get_active()
805 old_value
= gajim
.config
.get('outgoing_chat_state_notifications')
806 if active
== 0: # all
807 gajim
.config
.set('outgoing_chat_state_notifications', 'all')
808 elif active
== 1: # only composing
809 gajim
.config
.set('outgoing_chat_state_notifications', 'composing_only')
811 gajim
.config
.set('outgoing_chat_state_notifications', 'disabled')
812 new_value
= gajim
.config
.get('outgoing_chat_state_notifications')
813 if 'disabled' in (old_value
, new_value
):
814 # we changed from disabled to sth else or vice versa
815 helpers
.update_optional_features()
817 def on_displayed_chat_states_combobox_changed(self
, widget
):
818 active
= widget
.get_active()
819 if active
== 0: # all
820 gajim
.config
.set('displayed_chat_state_notifications', 'all')
821 elif active
== 1: # only composing
822 gajim
.config
.set('displayed_chat_state_notifications',
825 gajim
.config
.set('displayed_chat_state_notifications', 'disabled')
827 def on_ignore_events_from_unknown_contacts_checkbutton_toggled(self
, widget
):
828 widget
.set_inconsistent(False)
829 self
.on_per_account_checkbutton_toggled(widget
, 'ignore_unknown_contacts')
831 def on_on_event_combobox_changed(self
, widget
):
832 active
= widget
.get_active()
834 gajim
.config
.set('autopopup', True)
835 gajim
.config
.set('notify_on_new_message', False)
837 gajim
.config
.set('autopopup', False)
838 gajim
.config
.set('notify_on_new_message', True)
840 gajim
.config
.set('autopopup', False)
841 gajim
.config
.set('notify_on_new_message', False)
843 def on_notify_on_signin_checkbutton_toggled(self
, widget
):
844 self
.on_checkbutton_toggled(widget
, 'notify_on_signin')
846 def on_notify_on_signout_checkbutton_toggled(self
, widget
):
847 self
.on_checkbutton_toggled(widget
, 'notify_on_signout')
849 def on_auto_popup_away_checkbutton_toggled(self
, widget
):
850 self
.on_checkbutton_toggled(widget
, 'autopopupaway')
852 def on_sound_dnd_checkbutton_toggled(self
, widget
):
853 self
.on_checkbutton_toggled(widget
, 'sounddnd')
855 def on_systray_combobox_changed(self
, widget
):
856 active
= widget
.get_active()
858 gajim
.config
.set('trayicon', 'never')
859 gajim
.interface
.systray_enabled
= False
860 gajim
.interface
.systray
.hide_icon()
862 gajim
.config
.set('trayicon', 'on_event')
863 gajim
.interface
.systray_enabled
= True
864 gajim
.interface
.systray
.show_icon()
866 gajim
.config
.set('trayicon', 'always')
867 gajim
.interface
.systray_enabled
= True
868 gajim
.interface
.systray
.show_icon()
870 def on_advanced_notifications_button_clicked(self
, widget
):
871 dialogs
.AdvancedNotificationsWindow()
873 def on_play_sounds_checkbutton_toggled(self
, widget
):
874 self
.on_checkbutton_toggled(widget
, 'sounds_on',
875 [self
.xml
.get_object('manage_sounds_button')])
877 def on_manage_sounds_button_clicked(self
, widget
):
878 if self
.sounds_preferences
is None:
879 self
.sounds_preferences
= ManageSoundsWindow()
881 self
.sounds_preferences
.window
.present()
883 def update_text_tags(self
):
885 Update color tags in opened chat windows
887 for ctrl
in self
._get
_all
_controls
():
890 def on_preference_widget_color_set(self
, widget
, text
):
891 color
= widget
.get_color()
892 color_string
= gtkgui_helpers
.make_color_string(color
)
893 gajim
.config
.set(text
, color_string
)
894 self
.update_text_tags()
895 gajim
.interface
.save_config()
897 def on_preference_widget_font_set(self
, widget
, text
):
899 font
= widget
.get_font_name()
902 gajim
.config
.set(text
, font
)
903 self
.update_text_font()
904 gajim
.interface
.save_config()
906 def update_text_font(self
):
908 Update text font in opened chat windows
910 for ctrl
in self
._get
_all
_controls
():
913 def on_incoming_nick_colorbutton_color_set(self
, widget
):
914 self
.on_preference_widget_color_set(widget
, 'inmsgcolor')
916 def on_outgoing_nick_colorbutton_color_set(self
, widget
):
917 self
.on_preference_widget_color_set(widget
, 'outmsgcolor')
919 def on_incoming_msg_colorbutton_color_set(self
, widget
):
920 self
.on_preference_widget_color_set(widget
, 'inmsgtxtcolor')
922 def on_outgoing_msg_colorbutton_color_set(self
, widget
):
923 self
.on_preference_widget_color_set(widget
, 'outmsgtxtcolor')
925 def on_url_msg_colorbutton_color_set(self
, widget
):
926 self
.on_preference_widget_color_set(widget
, 'urlmsgcolor')
928 def on_status_msg_colorbutton_color_set(self
, widget
):
929 self
.on_preference_widget_color_set(widget
, 'statusmsgcolor')
931 def on_conversation_fontbutton_font_set(self
, widget
):
932 self
.on_preference_widget_font_set(widget
, 'conversation_font')
934 def on_default_chat_font_toggled(self
, widget
):
935 font_widget
= self
.xml
.get_object('conversation_fontbutton')
936 if widget
.get_active():
937 font_widget
.set_sensitive(False)
940 font_widget
.set_sensitive(True)
941 self
.on_preference_widget_font_set(font_widget
, 'conversation_font')
943 def draw_color_widgets(self
):
944 col_to_widget
= {'inmsgcolor': 'incoming_nick_colorbutton',
945 'outmsgcolor': 'outgoing_nick_colorbutton',
946 'inmsgtxtcolor': ['incoming_msg_colorbutton',
947 'incoming_msg_checkbutton'],
948 'outmsgtxtcolor': ['outgoing_msg_colorbutton',
949 'outgoing_msg_checkbutton'],
950 'statusmsgcolor': 'status_msg_colorbutton',
951 'urlmsgcolor': 'url_msg_colorbutton'}
952 for c
in col_to_widget
:
953 col
= gajim
.config
.get(c
)
955 if isinstance(col_to_widget
[c
], list):
956 self
.xml
.get_object(col_to_widget
[c
][0]).set_color(
957 gtk
.gdk
.color_parse(col
))
958 self
.xml
.get_object(col_to_widget
[c
][0]).set_sensitive(True)
959 self
.xml
.get_object(col_to_widget
[c
][1]).set_active(True)
961 self
.xml
.get_object(col_to_widget
[c
]).set_color(
962 gtk
.gdk
.color_parse(col
))
964 if isinstance(col_to_widget
[c
], list):
965 self
.xml
.get_object(col_to_widget
[c
][0]).set_color(
966 gtk
.gdk
.color_parse('#000000'))
967 self
.xml
.get_object(col_to_widget
[c
][0]).set_sensitive(False)
968 self
.xml
.get_object(col_to_widget
[c
][1]).set_active(False)
970 self
.xml
.get_object(col_to_widget
[c
]).set_color(
971 gtk
.gdk
.color_parse('#000000'))
973 def on_reset_colors_button_clicked(self
, widget
):
974 col_to_widget
= {'inmsgcolor': 'incoming_nick_colorbutton',
975 'outmsgcolor': 'outgoing_nick_colorbutton',
976 'inmsgtxtcolor': 'incoming_msg_colorbutton',
977 'outmsgtxtcolor': 'outgoing_msg_colorbutton',
978 'statusmsgcolor': 'status_msg_colorbutton',
979 'urlmsgcolor': 'url_msg_colorbutton'}
980 for c
in col_to_widget
:
981 gajim
.config
.set(c
, gajim
.interface
.default_colors
[c
])
982 self
.draw_color_widgets()
984 self
.update_text_tags()
985 gajim
.interface
.save_config()
987 def _set_color(self
, state
, widget_name
, option
):
989 Set color value in prefs and update the UI
992 color
= self
.xml
.get_object(widget_name
).get_color()
993 color_string
= gtkgui_helpers
.make_color_string(color
)
996 gajim
.config
.set(option
, color_string
)
997 gajim
.interface
.save_config()
999 def on_incoming_msg_checkbutton_toggled(self
, widget
):
1000 state
= widget
.get_active()
1001 self
.xml
.get_object('incoming_msg_colorbutton').set_sensitive(state
)
1002 self
._set
_color
(state
, 'incoming_msg_colorbutton', 'inmsgtxtcolor')
1004 def on_outgoing_msg_checkbutton_toggled(self
, widget
):
1005 state
= widget
.get_active()
1006 self
.xml
.get_object('outgoing_msg_colorbutton').set_sensitive(state
)
1007 self
._set
_color
(state
, 'outgoing_msg_colorbutton', 'outmsgtxtcolor')
1009 def on_auto_away_checkbutton_toggled(self
, widget
):
1010 self
.on_checkbutton_toggled(widget
, 'autoaway',
1011 [self
.auto_away_time_spinbutton
, self
.auto_away_message_entry
])
1013 def on_auto_away_time_spinbutton_value_changed(self
, widget
):
1014 aat
= widget
.get_value_as_int()
1015 gajim
.config
.set('autoawaytime', aat
)
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_away_message_entry_changed(self
, widget
):
1022 gajim
.config
.set('autoaway_message', widget
.get_text().decode('utf-8'))
1024 def on_auto_xa_checkbutton_toggled(self
, widget
):
1025 self
.on_checkbutton_toggled(widget
, 'autoxa',
1026 [self
.auto_xa_time_spinbutton
, self
.auto_xa_message_entry
])
1028 def on_auto_xa_time_spinbutton_value_changed(self
, widget
):
1029 axt
= widget
.get_value_as_int()
1030 gajim
.config
.set('autoxatime', axt
)
1031 gajim
.interface
.sleeper
= common
.sleepy
.Sleepy(
1032 gajim
.config
.get('autoawaytime') * 60,
1033 gajim
.config
.get('autoxatime') * 60)
1034 gajim
.interface
.save_config()
1036 def on_auto_xa_message_entry_changed(self
, widget
):
1037 gajim
.config
.set('autoxa_message', widget
.get_text().decode('utf-8'))
1039 def on_prompt_online_status_message_checkbutton_toggled(self
, widget
):
1040 self
.on_checkbutton_toggled(widget
, 'ask_online_status')
1042 def on_prompt_offline_status_message_checkbutton_toggled(self
, widget
):
1043 self
.on_checkbutton_toggled(widget
, 'ask_offline_status')
1045 def fill_default_msg_treeview(self
):
1046 model
= self
.default_msg_tree
.get_model()
1049 for status_
in gajim
.config
.get_per('defaultstatusmsg'):
1050 status
.append(status_
)
1052 for status_
in status
:
1053 msg
= gajim
.config
.get_per('defaultstatusmsg', status_
, 'message')
1054 msg
= helpers
.from_one_line(msg
)
1055 enabled
= gajim
.config
.get_per('defaultstatusmsg', status_
, 'enabled')
1056 iter_
= model
.append()
1057 uf_show
= helpers
.get_uf_show(status_
)
1058 model
.set(iter_
, 0, status_
, 1, uf_show
, 2, msg
, 3, enabled
)
1060 def on_default_msg_cell_edited(self
, cell
, row
, new_text
):
1061 model
= self
.default_msg_tree
.get_model()
1062 iter_
= model
.get_iter_from_string(row
)
1063 model
.set_value(iter_
, 2, new_text
)
1065 def default_msg_toggled_cb(self
, cell
, path
):
1066 model
= self
.default_msg_tree
.get_model()
1067 model
[path
][3] = not model
[path
][3]
1069 def on_default_msg_treemodel_row_changed(self
, model
, path
, iter_
):
1070 status
= model
[iter_
][0]
1071 message
= model
[iter_
][2].decode('utf-8')
1072 message
= helpers
.to_one_line(message
)
1073 gajim
.config
.set_per('defaultstatusmsg', status
, 'enabled',
1075 gajim
.config
.set_per('defaultstatusmsg', status
, 'message', message
)
1077 def on_default_status_expander_activate(self
, expander
):
1078 eventbox
= self
.xml
.get_object('default_status_eventbox')
1079 vbox
= self
.xml
.get_object('status_vbox')
1080 vbox
.set_child_packing(eventbox
, not expander
.get_expanded(), True, 0,
1083 def save_status_messages(self
, model
):
1084 for msg
in gajim
.config
.get_per('statusmsg'):
1085 gajim
.config
.del_per('statusmsg', msg
)
1086 iter_
= model
.get_iter_first()
1088 val
= model
[iter_
][0].decode('utf-8')
1089 if model
[iter_
][1]: # we have a preset message
1090 if not val
: # no title, use message text for title
1091 val
= model
[iter_
][1]
1092 gajim
.config
.add_per('statusmsg', val
)
1093 msg
= helpers
.to_one_line(model
[iter_
][1].decode('utf-8'))
1094 gajim
.config
.set_per('statusmsg', val
, 'message', msg
)
1096 # store mood / activity
1097 for subname
in ('activity', 'subactivity', 'activity_text',
1098 'mood', 'mood_text'):
1099 gajim
.config
.set_per('statusmsg', val
, subname
,
1100 model
[iter_
][i
].decode('utf-8'))
1102 iter_
= model
.iter_next(iter_
)
1103 gajim
.interface
.save_config()
1105 def on_msg_treemodel_row_changed(self
, model
, path
, iter_
):
1106 self
.save_status_messages(model
)
1108 def on_msg_treemodel_row_deleted(self
, model
, path
):
1109 self
.save_status_messages(model
)
1111 def on_av_combobox_changed(self
, combobox
, config_name
):
1112 model
= combobox
.get_model()
1113 active
= combobox
.get_active()
1114 device
= model
[active
][1].decode('utf-8')
1115 gajim
.config
.set(config_name
, device
)
1117 def on_audio_input_combobox_changed(self
, widget
):
1118 self
.on_av_combobox_changed(widget
, 'audio_input_device')
1120 def on_audio_output_combobox_changed(self
, widget
):
1121 self
.on_av_combobox_changed(widget
, 'audio_output_device')
1123 def on_video_input_combobox_changed(self
, widget
):
1124 self
.on_av_combobox_changed(widget
, 'video_input_device')
1126 def on_video_output_combobox_changed(self
, widget
):
1127 self
.on_av_combobox_changed(widget
, 'video_output_device')
1129 def on_video_framerate_combobox_changed(self
, widget
):
1130 self
.on_av_combobox_changed(widget
, 'video_framerate')
1132 def on_video_size_combobox_changed(self
, widget
):
1133 self
.on_av_combobox_changed(widget
, 'video_size')
1135 def on_stun_checkbutton_toggled(self
, widget
):
1136 self
.on_checkbutton_toggled(widget
, 'use_stun_server',
1137 [self
.xml
.get_object('stun_server_entry')])
1139 def stun_server_entry_changed(self
, widget
):
1140 gajim
.config
.set('stun_server', widget
.get_text().decode('utf-8'))
1142 def on_applications_combobox_changed(self
, widget
):
1143 if widget
.get_active() == 0:
1144 gajim
.config
.set('autodetect_browser_mailer', True)
1145 self
.xml
.get_object('custom_apps_frame').hide()
1146 elif widget
.get_active() == 1:
1147 gajim
.config
.set('autodetect_browser_mailer', False)
1148 self
.xml
.get_object('custom_apps_frame').show()
1149 gajim
.config
.set('openwith', 'custom')
1150 gajim
.interface
.save_config()
1152 def on_custom_browser_entry_changed(self
, widget
):
1153 gajim
.config
.set('custombrowser', widget
.get_text().decode('utf-8'))
1154 gajim
.interface
.save_config()
1156 def on_custom_mail_client_entry_changed(self
, widget
):
1157 gajim
.config
.set('custommailapp', widget
.get_text().decode('utf-8'))
1158 gajim
.interface
.save_config()
1160 def on_custom_file_manager_entry_changed(self
, widget
):
1161 gajim
.config
.set('custom_file_manager', widget
.get_text().decode('utf-8'))
1162 gajim
.interface
.save_config()
1164 def on_log_show_changes_checkbutton_toggled(self
, widget
):
1165 self
.on_checkbutton_toggled(widget
, 'log_contact_status_changes')
1167 def on_log_encrypted_chats_checkbutton_toggled(self
, widget
):
1168 widget
.set_inconsistent(False)
1169 self
.on_per_account_checkbutton_toggled(widget
, 'log_encrypted_sessions')
1171 def on_send_os_info_checkbutton_toggled(self
, widget
):
1172 widget
.set_inconsistent(False)
1173 self
.on_per_account_checkbutton_toggled(widget
, 'send_os_info')
1175 def on_send_idle_time_checkbutton_toggled(self
, widget
):
1176 widget
.set_inconsistent(False)
1177 self
.on_per_account_checkbutton_toggled(widget
, 'send_idle_time')
1179 def on_check_default_client_checkbutton_toggled(self
, widget
):
1180 self
.on_checkbutton_toggled(widget
, 'check_if_gajim_is_default')
1182 def on_notify_gmail_checkbutton_toggled(self
, widget
):
1183 self
.on_checkbutton_toggled(widget
, 'notify_on_new_gmail_email')
1185 def on_notify_gmail_extra_checkbutton_toggled(self
, widget
):
1186 self
.on_checkbutton_toggled(widget
, 'notify_on_new_gmail_email_extra')
1188 def fill_msg_treeview(self
):
1189 self
.xml
.get_object('delete_msg_button').set_sensitive(False)
1190 model
= self
.msg_tree
.get_model()
1193 for msg_name
in gajim
.config
.get_per('statusmsg'):
1194 if msg_name
.startswith('_last_'):
1196 preset_status
.append(msg_name
)
1197 preset_status
.sort()
1198 for msg_name
in preset_status
:
1199 msg_text
= gajim
.config
.get_per('statusmsg', msg_name
, 'message')
1200 msg_text
= helpers
.from_one_line(msg_text
)
1201 activity
= gajim
.config
.get_per('statusmsg', msg_name
, 'activity')
1202 subactivity
= gajim
.config
.get_per('statusmsg', msg_name
,
1204 activity_text
= gajim
.config
.get_per('statusmsg', msg_name
,
1206 mood
= gajim
.config
.get_per('statusmsg', msg_name
, 'mood')
1207 mood_text
= gajim
.config
.get_per('statusmsg', msg_name
, 'mood_text')
1208 iter_
= model
.append()
1209 model
.set(iter_
, 0, msg_name
, 1, msg_text
, 2, activity
, 3,
1210 subactivity
, 4, activity_text
, 5, mood
, 6, mood_text
)
1212 def on_msg_cell_edited(self
, cell
, row
, new_text
):
1213 model
= self
.msg_tree
.get_model()
1214 iter_
= model
.get_iter_from_string(row
)
1215 model
.set_value(iter_
, 0, new_text
)
1217 def on_msg_treeview_cursor_changed(self
, widget
, data
= None):
1218 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1221 self
.xml
.get_object('delete_msg_button').set_sensitive(True)
1222 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1223 msg
= model
[iter_
][1]
1226 def on_new_msg_button_clicked(self
, widget
, data
= None):
1227 model
= self
.msg_tree
.get_model()
1228 iter_
= model
.append()
1229 model
.set(iter_
, 0, _('status message title'), 1, _('status message text'))
1230 self
.msg_tree
.set_cursor(model
.get_path(iter_
))
1232 def on_delete_msg_button_clicked(self
, widget
, data
= None):
1233 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1236 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1239 self
.xml
.get_object('delete_msg_button').set_sensitive(False)
1241 def on_msg_textview_changed(self
, widget
, data
= None):
1242 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1245 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1246 first_iter
, end_iter
= buf
.get_bounds()
1247 model
.set_value(iter_
, 1, buf
.get_text(first_iter
, end_iter
))
1249 def on_msg_treeview_key_press_event(self
, widget
, event
):
1250 if event
.keyval
== gtk
.keysyms
.Delete
:
1251 self
.on_delete_msg_button_clicked(widget
)
1253 def on_open_advanced_editor_button_clicked(self
, widget
, data
= None):
1254 if 'advanced_config' in gajim
.interface
.instances
:
1255 gajim
.interface
.instances
['advanced_config'].window
.present()
1257 gajim
.interface
.instances
['advanced_config'] = \
1258 dialogs
.AdvancedConfigurationWindow()
1260 #---------- ManageProxiesWindow class -------------#
1261 class ManageProxiesWindow
:
1263 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_proxies_window.ui')
1264 self
.window
= self
.xml
.get_object('manage_proxies_window')
1265 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
1266 self
.proxies_treeview
= self
.xml
.get_object('proxies_treeview')
1267 self
.proxyname_entry
= self
.xml
.get_object('proxyname_entry')
1268 self
.proxytype_combobox
= self
.xml
.get_object('proxytype_combobox')
1271 self
.block_signal
= False
1272 self
.xml
.connect_signals(self
)
1273 self
.window
.show_all()
1274 # hide the BOSH fields by default
1275 self
.show_bosh_fields()
1277 def show_bosh_fields(self
, show
=True):
1279 self
.xml
.get_object('boshuri_entry').show()
1280 self
.xml
.get_object('boshuri_label').show()
1281 self
.xml
.get_object('boshuseproxy_checkbutton').show()
1283 cb
= self
.xml
.get_object('boshuseproxy_checkbutton')
1286 self
.on_boshuseproxy_checkbutton_toggled(cb
)
1287 self
.xml
.get_object('boshuri_entry').hide()
1288 self
.xml
.get_object('boshuri_label').hide()
1291 def fill_proxies_treeview(self
):
1292 model
= self
.proxies_treeview
.get_model()
1294 iter_
= model
.append()
1295 model
.set(iter_
, 0, _('None'))
1296 for p
in gajim
.config
.get_per('proxies'):
1297 iter_
= model
.append()
1298 model
.set(iter_
, 0, p
)
1300 def init_list(self
):
1301 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1302 self
.proxytype_combobox
.set_sensitive(False)
1303 self
.xml
.get_object('proxy_table').set_sensitive(False)
1304 model
= gtk
.ListStore(str)
1305 self
.proxies_treeview
.set_model(model
)
1306 col
= gtk
.TreeViewColumn('Proxies')
1307 self
.proxies_treeview
.append_column(col
)
1308 renderer
= gtk
.CellRendererText()
1309 col
.pack_start(renderer
, True)
1310 col
.set_attributes(renderer
, text
= 0)
1311 self
.fill_proxies_treeview()
1312 self
.xml
.get_object('proxytype_combobox').set_active(0)
1314 def on_manage_proxies_window_destroy(self
, widget
):
1315 if 'accounts' in gajim
.interface
.instances
:
1316 gajim
.interface
.instances
['accounts'].\
1318 del gajim
.interface
.instances
['manage_proxies']
1320 def on_add_proxy_button_clicked(self
, widget
):
1321 model
= self
.proxies_treeview
.get_model()
1322 proxies
= gajim
.config
.get_per('proxies')
1324 while ('proxy' + unicode(i
)) in proxies
:
1326 iter_
= model
.append()
1327 model
.set(iter_
, 0, 'proxy' + unicode(i
))
1328 gajim
.config
.add_per('proxies', 'proxy' + unicode(i
))
1329 self
.proxies_treeview
.set_cursor(model
.get_path(iter_
))
1331 def on_remove_proxy_button_clicked(self
, widget
):
1332 (model
, iter_
) = self
.proxies_treeview
.get_selection().get_selected()
1335 proxy
= model
[iter_
][0].decode('utf-8')
1337 gajim
.config
.del_per('proxies', proxy
)
1338 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1339 self
.block_signal
= True
1340 self
.on_proxies_treeview_cursor_changed(self
.proxies_treeview
)
1341 self
.block_signal
= False
1343 def on_close_button_clicked(self
, widget
):
1344 self
.window
.destroy()
1346 def on_useauth_checkbutton_toggled(self
, widget
):
1347 if self
.block_signal
:
1349 act
= widget
.get_active()
1350 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1351 gajim
.config
.set_per('proxies', proxy
, 'useauth', act
)
1352 self
.xml
.get_object('proxyuser_entry').set_sensitive(act
)
1353 self
.xml
.get_object('proxypass_entry').set_sensitive(act
)
1355 def on_boshuseproxy_checkbutton_toggled(self
, widget
):
1356 if self
.block_signal
:
1358 act
= widget
.get_active()
1359 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1360 gajim
.config
.set_per('proxies', proxy
, 'bosh_useproxy', act
)
1361 self
.xml
.get_object('proxyhost_entry').set_sensitive(act
)
1362 self
.xml
.get_object('proxyport_entry').set_sensitive(act
)
1364 def on_proxies_treeview_cursor_changed(self
, widget
):
1365 #FIXME: check if off proxy settings are correct (see
1366 # http://trac.gajim.org/changeset/1921#file2 line 1221
1367 proxyhost_entry
= self
.xml
.get_object('proxyhost_entry')
1368 proxyport_entry
= self
.xml
.get_object('proxyport_entry')
1369 proxyuser_entry
= self
.xml
.get_object('proxyuser_entry')
1370 proxypass_entry
= self
.xml
.get_object('proxypass_entry')
1371 boshuri_entry
= self
.xml
.get_object('boshuri_entry')
1372 useauth_checkbutton
= self
.xml
.get_object('useauth_checkbutton')
1373 boshuseproxy_checkbutton
= self
.xml
.get_object('boshuseproxy_checkbutton')
1374 self
.block_signal
= True
1375 proxyhost_entry
.set_text('')
1376 proxyport_entry
.set_text('')
1377 proxyuser_entry
.set_text('')
1378 proxypass_entry
.set_text('')
1379 boshuri_entry
.set_text('')
1381 #boshuseproxy_checkbutton.set_active(False)
1382 #self.on_boshuseproxy_checkbutton_toggled(boshuseproxy_checkbutton)
1384 #useauth_checkbutton.set_active(False)
1385 #self.on_useauth_checkbutton_toggled(useauth_checkbutton)
1387 (model
, iter_
) = widget
.get_selection().get_selected()
1389 self
.xml
.get_object('proxyname_entry').set_text('')
1390 self
.xml
.get_object('proxytype_combobox').set_sensitive(False)
1391 self
.xml
.get_object('proxy_table').set_sensitive(False)
1392 self
.block_signal
= False
1395 proxy
= model
[iter_
][0]
1396 self
.xml
.get_object('proxyname_entry').set_text(proxy
)
1398 if proxy
== _('None'): # special proxy None
1399 self
.show_bosh_fields(False)
1400 self
.proxyname_entry
.set_editable(False)
1401 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1402 self
.xml
.get_object('proxytype_combobox').set_sensitive(False)
1403 self
.xml
.get_object('proxy_table').set_sensitive(False)
1405 proxytype
= gajim
.config
.get_per('proxies', proxy
, 'type')
1407 self
.show_bosh_fields(proxytype
=='bosh')
1409 self
.proxyname_entry
.set_editable(True)
1410 self
.xml
.get_object('remove_proxy_button').set_sensitive(True)
1411 self
.xml
.get_object('proxytype_combobox').set_sensitive(True)
1412 self
.xml
.get_object('proxy_table').set_sensitive(True)
1413 proxyhost_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1415 proxyport_entry
.set_text(unicode(gajim
.config
.get_per('proxies',
1417 proxyuser_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1419 proxypass_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1421 boshuri_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1423 types
= ['http', 'socks5', 'bosh']
1424 self
.proxytype_combobox
.set_active(types
.index(proxytype
))
1425 boshuseproxy_checkbutton
.set_active(
1426 gajim
.config
.get_per('proxies', proxy
, 'bosh_useproxy'))
1427 useauth_checkbutton
.set_active(
1428 gajim
.config
.get_per('proxies', proxy
, 'useauth'))
1429 self
.block_signal
= False
1431 def on_proxies_treeview_key_press_event(self
, widget
, event
):
1432 if event
.keyval
== gtk
.keysyms
.Delete
:
1433 self
.on_remove_proxy_button_clicked(widget
)
1435 def on_proxyname_entry_changed(self
, widget
):
1436 if self
.block_signal
:
1438 (model
, iter_
) = self
.proxies_treeview
.get_selection().get_selected()
1441 old_name
= model
.get_value(iter_
, 0).decode('utf-8')
1442 new_name
= widget
.get_text().decode('utf-8')
1445 if new_name
== old_name
:
1447 config
= gajim
.config
.get_per('proxies', old_name
)
1448 gajim
.config
.del_per('proxies', old_name
)
1449 gajim
.config
.add_per('proxies', new_name
)
1450 for option
in config
:
1451 gajim
.config
.set_per('proxies', new_name
, option
,
1452 config
[option
][common
.config
.OPT_VAL
])
1453 model
.set_value(iter_
, 0, new_name
)
1455 def on_proxytype_combobox_changed(self
, widget
):
1456 if self
.block_signal
:
1458 types
= ['http', 'socks5', 'bosh']
1459 type_
= self
.proxytype_combobox
.get_active()
1460 self
.show_bosh_fields(types
[type_
]=='bosh')
1461 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1462 gajim
.config
.set_per('proxies', proxy
, 'type', types
[type_
])
1464 def on_proxyhost_entry_changed(self
, widget
):
1465 if self
.block_signal
:
1467 value
= widget
.get_text().decode('utf-8')
1468 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1469 gajim
.config
.set_per('proxies', proxy
, 'host', value
)
1471 def on_proxyport_entry_changed(self
, widget
):
1472 if self
.block_signal
:
1474 value
= widget
.get_text().decode('utf-8')
1475 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1476 gajim
.config
.set_per('proxies', proxy
, 'port', value
)
1478 def on_proxyuser_entry_changed(self
, widget
):
1479 if self
.block_signal
:
1481 value
= widget
.get_text().decode('utf-8')
1482 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1483 gajim
.config
.set_per('proxies', proxy
, 'user', value
)
1485 def on_boshuri_entry_changed(self
, widget
):
1486 if self
.block_signal
:
1488 value
= widget
.get_text().decode('utf-8')
1489 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1490 gajim
.config
.set_per('proxies', proxy
, 'bosh_uri', value
)
1492 def on_proxypass_entry_changed(self
, widget
):
1493 if self
.block_signal
:
1495 value
= widget
.get_text().decode('utf-8')
1496 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1497 gajim
.config
.set_per('proxies', proxy
, 'pass', value
)
1500 #---------- AccountsWindow class -------------#
1501 class AccountsWindow
:
1503 Class for accounts window: list of accounts
1506 def on_accounts_window_destroy(self
, widget
):
1507 del gajim
.interface
.instances
['accounts']
1509 def on_close_button_clicked(self
, widget
):
1510 self
.check_resend_relog()
1511 self
.window
.destroy()
1514 self
.xml
= gtkgui_helpers
.get_gtk_builder('accounts_window.ui')
1515 self
.window
= self
.xml
.get_object('accounts_window')
1516 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
1517 self
.accounts_treeview
= self
.xml
.get_object('accounts_treeview')
1518 self
.remove_button
= self
.xml
.get_object('remove_button')
1519 self
.rename_button
= self
.xml
.get_object('rename_button')
1520 path_to_kbd_input_img
= gtkgui_helpers
.get_icon_path('gajim-kbd_input')
1521 img
= self
.xml
.get_object('rename_image')
1522 img
.set_from_file(path_to_kbd_input_img
)
1523 self
.notebook
= self
.xml
.get_object('notebook')
1525 model
= gtk
.ListStore(str)
1526 self
.accounts_treeview
.set_model(model
)
1528 renderer
= gtk
.CellRendererText()
1529 self
.accounts_treeview
.insert_column_with_attributes(-1, _('Name'),
1532 self
.current_account
= None
1533 # When we fill info, we don't want to handle the changed signals
1534 self
.ignore_events
= False
1535 self
.need_relogin
= False
1536 self
.resend_presence
= False
1538 self
.update_proxy_list()
1539 self
.xml
.connect_signals(self
)
1540 self
.init_accounts()
1541 self
.window
.show_all()
1544 st
= gajim
.config
.get('mergeaccounts')
1545 checkbutton
= self
.xml
.get_object('merge_checkbutton')
1546 checkbutton
.set_active(st
)
1547 # prevent roster redraws by connecting the signal after button state is
1549 checkbutton
.connect('toggled', self
.on_merge_checkbutton_toggled
)
1551 self
.avahi_available
= True
1555 self
.avahi_available
= False
1557 def on_accounts_window_key_press_event(self
, widget
, event
):
1558 if event
.keyval
== gtk
.keysyms
.Escape
:
1559 self
.check_resend_relog()
1560 self
.window
.destroy()
1562 def select_account(self
, account
):
1563 model
= self
.accounts_treeview
.get_model()
1564 iter_
= model
.get_iter_root()
1566 acct
= model
[iter_
][0].decode('utf-8')
1568 self
.accounts_treeview
.set_cursor(model
.get_path(iter_
))
1570 iter_
= model
.iter_next(iter_
)
1572 def init_accounts(self
):
1574 Initialize listStore with existing accounts
1576 self
.remove_button
.set_sensitive(False)
1577 self
.rename_button
.set_sensitive(False)
1578 self
.current_account
= None
1579 model
= self
.accounts_treeview
.get_model()
1581 for account
in gajim
.config
.get_per('accounts'):
1582 iter_
= model
.append()
1583 model
.set(iter_
, 0, account
)
1585 def resend(self
, account
):
1586 if not account
in gajim
.connections
:
1588 show
= gajim
.SHOW_LIST
[gajim
.connections
[account
].connected
]
1589 status
= gajim
.connections
[account
].status
1590 gajim
.connections
[account
].change_status(show
, status
)
1592 def check_resend_relog(self
):
1593 if self
.need_relogin
and self
.current_account
== gajim
.ZEROCONF_ACC_NAME
:
1594 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
:
1595 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].update_details()
1598 elif self
.need_relogin
and self
.current_account
and \
1599 gajim
.connections
[self
.current_account
].connected
> 0:
1600 def login(account
, show_before
, status_before
):
1602 Login with previous status
1604 # first make sure connection is really closed,
1605 # 0.5 may not be enough
1606 gajim
.connections
[account
].disconnect(True)
1607 gajim
.interface
.roster
.send_status(account
, show_before
,
1611 self
.dialog
.destroy()
1612 show_before
= gajim
.SHOW_LIST
[gajim
.connections
[account
].connected
]
1613 status_before
= gajim
.connections
[account
].status
1614 gajim
.interface
.roster
.send_status(account
, 'offline',
1615 _('Be right back.'))
1616 gobject
.timeout_add(500, login
, account
, show_before
, status_before
)
1618 def on_yes(checked
, account
):
1621 if self
.resend_presence
:
1622 self
.resend(account
)
1623 if self
.current_account
in gajim
.connections
:
1624 self
.dialog
= dialogs
.YesNoDialog(_('Relogin now?'),
1625 _('If you want all the changes to apply instantly, '
1626 'you must relogin.'), on_response_yes
=(on_yes
,
1627 self
.current_account
), on_response_no
=(on_no
,
1628 self
.current_account
))
1629 elif self
.resend_presence
:
1630 self
.resend(self
.current_account
)
1632 self
.need_relogin
= False
1633 self
.resend_presence
= False
1635 def on_accounts_treeview_cursor_changed(self
, widget
):
1637 Activate modify buttons when a row is selected, update accounts info
1639 sel
= self
.accounts_treeview
.get_selection()
1640 (model
, iter_
) = sel
.get_selected()
1642 account
= model
[iter_
][0].decode('utf-8')
1645 if self
.current_account
and self
.current_account
== account
:
1646 # We're comming back to our current account, no need to update widgets
1648 # Save config for previous account if needed cause focus_out event is
1649 # called after the changed event
1650 if self
.current_account
and self
.window
.get_focus():
1651 focused_widget
= self
.window
.get_focus()
1652 focused_widget_name
= focused_widget
.get_name()
1653 if focused_widget_name
in ('jid_entry1', 'resource_entry1',
1654 'custom_port_entry', 'cert_entry1'):
1655 if focused_widget_name
== 'jid_entry1':
1656 func
= self
.on_jid_entry1_focus_out_event
1657 elif focused_widget_name
== 'resource_entry1':
1658 func
= self
.on_resource_entry1_focus_out_event
1659 elif focused_widget_name
== 'custom_port_entry':
1660 func
= self
.on_custom_port_entry_focus_out_event
1661 elif focused_widget_name
== 'cert_entry1':
1662 func
= self
.on_cert_entry1_focus_out_event
1663 if func(focused_widget
, None):
1664 # Error detected in entry, don't change account, re-put cursor on
1666 self
.select_account(self
.current_account
)
1668 self
.window
.set_focus(widget
)
1670 self
.check_resend_relog()
1673 self
.remove_button
.set_sensitive(True)
1674 self
.rename_button
.set_sensitive(True)
1676 self
.remove_button
.set_sensitive(False)
1677 self
.rename_button
.set_sensitive(False)
1679 self
.current_account
= account
1680 if account
== gajim
.ZEROCONF_ACC_NAME
:
1681 self
.remove_button
.set_sensitive(False)
1683 self
.update_proxy_list()
1685 def on_browse_for_client_cert_button_clicked(self
, widget
, data
=None):
1686 def on_ok(widget
, path_to_clientcert_file
):
1687 self
.dialog
.destroy()
1688 if not path_to_clientcert_file
:
1690 self
.xml
.get_object('cert_entry1').set_text(path_to_clientcert_file
)
1691 gajim
.config
.set_per('accounts', self
.current_account
,
1692 'client_cert', path_to_clientcert_file
)
1694 def on_cancel(widget
):
1695 self
.dialog
.destroy()
1697 path_to_clientcert_file
= self
.xml
.get_object('cert_entry1').get_text()
1698 self
.dialog
= dialogs
.ClientCertChooserDialog(path_to_clientcert_file
,
1701 def update_proxy_list(self
):
1702 if self
.current_account
:
1703 our_proxy
= gajim
.config
.get_per('accounts', self
.current_account
,
1709 our_proxy
= _('None')
1710 proxy_combobox
= self
.xml
.get_object('proxies_combobox1')
1711 model
= gtk
.ListStore(str)
1712 proxy_combobox
.set_model(model
)
1713 l
= gajim
.config
.get_per('proxies')
1714 l
.insert(0, _('None'))
1715 for i
in xrange(len(l
)):
1716 model
.append([l
[i
]])
1717 if our_proxy
== l
[i
]:
1718 proxy_combobox
.set_active(i
)
1720 def init_account(self
):
1721 if not self
.current_account
:
1722 self
.notebook
.set_current_page(0)
1724 if gajim
.config
.get_per('accounts', self
.current_account
, 'is_zeroconf'):
1725 self
.ignore_events
= True
1726 self
.init_zeroconf_account()
1727 self
.ignore_events
= False
1728 self
.notebook
.set_current_page(2)
1730 self
.ignore_events
= True
1731 self
.init_normal_account()
1732 self
.ignore_events
= False
1733 self
.notebook
.set_current_page(1)
1735 def init_zeroconf_account(self
):
1736 active
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1738 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_active(active
)
1739 if not gajim
.HAVE_ZEROCONF
:
1740 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_sensitive(
1742 self
.xml
.get_object('zeroconf_notebook').set_sensitive(active
)
1744 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1746 self
.xml
.get_object('autoconnect_checkbutton2').set_active(st
)
1748 list_no_log_for
= gajim
.config
.get_per('accounts',
1749 gajim
.ZEROCONF_ACC_NAME
, 'no_log_for').split()
1750 if gajim
.ZEROCONF_ACC_NAME
in list_no_log_for
:
1751 self
.xml
.get_object('log_history_checkbutton2').set_active(0)
1753 self
.xml
.get_object('log_history_checkbutton2').set_active(1)
1755 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1756 'sync_with_global_status')
1757 self
.xml
.get_object('sync_with_global_status_checkbutton2').set_active(st
)
1759 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1761 self
.xml
.get_object('custom_port_checkbutton2').set_active(st
)
1762 self
.xml
.get_object('custom_port_entry2').set_sensitive(st
)
1764 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1767 gajim
.config
.set_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1768 'custom_port', '5298')
1770 self
.xml
.get_object('custom_port_entry2').set_text(str(st
))
1773 gpg_key_label
= self
.xml
.get_object('gpg_key_label2')
1774 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
and \
1775 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].gpg
:
1776 self
.xml
.get_object('gpg_choose_button2').set_sensitive(True)
1777 self
.init_account_gpg()
1779 gpg_key_label
.set_text(_('OpenPGP is not usable on this computer'))
1780 self
.xml
.get_object('gpg_choose_button2').set_sensitive(False)
1782 for opt
in ('first_name', 'last_name', 'jabber_id', 'email'):
1783 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1785 self
.xml
.get_object(opt
+ '_entry2').set_text(st
)
1787 def init_account_gpg(self
):
1788 account
= self
.current_account
1789 keyid
= gajim
.config
.get_per('accounts', account
, 'keyid')
1790 keyname
= gajim
.config
.get_per('accounts', account
, 'keyname')
1791 use_gpg_agent
= gajim
.config
.get('use_gpg_agent')
1793 if account
== gajim
.ZEROCONF_ACC_NAME
:
1794 widget_name_add
= '2'
1796 widget_name_add
= '1'
1798 gpg_key_label
= self
.xml
.get_object('gpg_key_label' + widget_name_add
)
1799 gpg_name_label
= self
.xml
.get_object('gpg_name_label' + widget_name_add
)
1800 use_gpg_agent_checkbutton
= self
.xml
.get_object(
1801 'use_gpg_agent_checkbutton' + widget_name_add
)
1804 use_gpg_agent_checkbutton
.set_sensitive(False)
1805 gpg_key_label
.set_text(_('No key selected'))
1806 gpg_name_label
.set_text('')
1809 gpg_key_label
.set_text(keyid
)
1810 gpg_name_label
.set_text(keyname
)
1811 use_gpg_agent_checkbutton
.set_sensitive(True)
1812 use_gpg_agent_checkbutton
.set_active(use_gpg_agent
)
1814 def draw_normal_jid(self
):
1815 account
= self
.current_account
1816 self
.ignore_events
= True
1817 active
= gajim
.config
.get_per('accounts', account
, 'active')
1818 self
.xml
.get_object('enable_checkbutton1').set_active(active
)
1819 self
.xml
.get_object('normal_notebook1').set_sensitive(active
)
1820 if gajim
.config
.get_per('accounts', account
, 'anonymous_auth'):
1821 self
.xml
.get_object('anonymous_checkbutton1').set_active(True)
1822 self
.xml
.get_object('jid_label1').set_text(_('Server:'))
1823 save_password
= self
.xml
.get_object('save_password_checkbutton1')
1824 save_password
.set_active(False)
1825 save_password
.set_sensitive(False)
1826 password_entry
= self
.xml
.get_object('password_entry1')
1827 password_entry
.set_text('')
1828 password_entry
.set_sensitive(False)
1829 jid
= gajim
.config
.get_per('accounts', account
, 'hostname')
1831 self
.xml
.get_object('anonymous_checkbutton1').set_active(False)
1832 self
.xml
.get_object('jid_label1').set_text(_('Jabber ID:'))
1833 savepass
= gajim
.config
.get_per('accounts', account
, 'savepass')
1834 save_password
= self
.xml
.get_object('save_password_checkbutton1')
1835 save_password
.set_sensitive(True)
1836 save_password
.set_active(savepass
)
1837 password_entry
= self
.xml
.get_object('password_entry1')
1839 passstr
= passwords
.get_password(account
) or ''
1840 password_entry
.set_sensitive(True)
1843 password_entry
.set_sensitive(False)
1844 password_entry
.set_text(passstr
)
1846 jid
= gajim
.config
.get_per('accounts', account
, 'name') \
1847 + '@' + gajim
.config
.get_per('accounts', account
, 'hostname')
1848 self
.xml
.get_object('jid_entry1').set_text(jid
)
1849 self
.ignore_events
= False
1851 def init_normal_account(self
):
1852 account
= self
.current_account
1854 self
.draw_normal_jid()
1855 self
.xml
.get_object('resource_entry1').set_text(gajim
.config
.get_per(
1856 'accounts', account
, 'resource'))
1858 client_cert
= gajim
.config
.get_per('accounts', account
, 'client_cert')
1859 self
.xml
.get_object('cert_entry1').set_text(client_cert
)
1861 self
.xml
.get_object('adjust_priority_with_status_checkbutton1').\
1862 set_active(gajim
.config
.get_per('accounts', account
,
1863 'adjust_priority_with_status'))
1864 spinbutton
= self
.xml
.get_object('priority_spinbutton1')
1865 if gajim
.config
.get('enable_negative_priority'):
1866 spinbutton
.set_range(-128, 127)
1868 spinbutton
.set_range(0, 127)
1869 spinbutton
.set_value(gajim
.config
.get_per('accounts', account
,
1873 use_env_http_proxy
= gajim
.config
.get_per('accounts', account
,
1874 'use_env_http_proxy')
1875 self
.xml
.get_object('use_env_http_proxy_checkbutton1').set_active(
1877 self
.xml
.get_object('proxy_hbox1').set_sensitive(not use_env_http_proxy
)
1879 warn_when_insecure_ssl
= gajim
.config
.get_per('accounts', account
,
1880 'warn_when_insecure_ssl_connection')
1881 self
.xml
.get_object('warn_when_insecure_connection_checkbutton1').\
1882 set_active(warn_when_insecure_ssl
)
1884 self
.xml
.get_object('send_keepalive_checkbutton1').set_active(
1885 gajim
.config
.get_per('accounts', account
, 'keep_alives_enabled'))
1887 use_custom_host
= gajim
.config
.get_per('accounts', account
,
1889 self
.xml
.get_object('custom_host_port_checkbutton1').set_active(
1891 custom_host
= gajim
.config
.get_per('accounts', account
, 'custom_host')
1893 custom_host
= gajim
.config
.get_per('accounts', account
, 'hostname')
1894 gajim
.config
.set_per('accounts', account
, 'custom_host', custom_host
)
1895 self
.xml
.get_object('custom_host_entry1').set_text(custom_host
)
1896 custom_port
= gajim
.config
.get_per('accounts', account
, 'custom_port')
1899 gajim
.config
.set_per('accounts', account
, 'custom_port', custom_port
)
1900 self
.xml
.get_object('custom_port_entry1').set_text(unicode(custom_port
))
1903 gpg_key_label
= self
.xml
.get_object('gpg_key_label1')
1905 self
.xml
.get_object('gpg_choose_button1').set_sensitive(True)
1906 self
.init_account_gpg()
1908 gpg_key_label
.set_text(_('OpenPGP is not usable on this computer'))
1909 self
.xml
.get_object('gpg_choose_button1').set_sensitive(False)
1912 self
.xml
.get_object('autoconnect_checkbutton1').set_active(gajim
.config
.\
1913 get_per('accounts', account
, 'autoconnect'))
1914 self
.xml
.get_object('autoreconnect_checkbutton1').set_active(gajim
.
1915 config
.get_per('accounts', account
, 'autoreconnect'))
1917 list_no_log_for
= gajim
.config
.get_per('accounts', account
,
1918 'no_log_for').split()
1919 if account
in list_no_log_for
:
1920 self
.xml
.get_object('log_history_checkbutton1').set_active(False)
1922 self
.xml
.get_object('log_history_checkbutton1').set_active(True)
1924 self
.xml
.get_object('sync_with_global_status_checkbutton1').set_active(
1925 gajim
.config
.get_per('accounts', account
, 'sync_with_global_status'))
1926 self
.xml
.get_object('use_ft_proxies_checkbutton1').set_active(
1927 gajim
.config
.get_per('accounts', account
, 'use_ft_proxies'))
1929 def on_add_button_clicked(self
, widget
):
1931 When add button is clicked: open an account information window
1933 if 'account_creation_wizard' in gajim
.interface
.instances
:
1934 gajim
.interface
.instances
['account_creation_wizard'].window
.present()
1936 gajim
.interface
.instances
['account_creation_wizard'] = \
1937 AccountCreationWizardWindow()
1939 def on_remove_button_clicked(self
, widget
):
1941 When delete button is clicked: Remove an account from the listStore and
1942 from the config file
1944 if not self
.current_account
:
1946 account
= self
.current_account
1947 if len(gajim
.events
.get_events(account
)):
1948 dialogs
.ErrorDialog(_('Unread events'),
1949 _('Read all pending events before removing this account.'))
1952 if gajim
.config
.get_per('accounts', account
, 'is_zeroconf'):
1953 # Should never happen as button is insensitive
1957 if gajim
.interface
.msg_win_mgr
.get_controls(acct
=account
):
1959 elif account
in gajim
.interface
.instances
:
1960 for key
in gajim
.interface
.instances
[account
]:
1961 if gajim
.interface
.instances
[account
][key
] and key
!= \
1965 # Detect if we have opened windows for this account
1966 def remove(account
):
1967 if account
in gajim
.interface
.instances
and \
1968 'remove_account' in gajim
.interface
.instances
[account
]:
1969 gajim
.interface
.instances
[account
]['remove_account'].window
.\
1972 if not account
in gajim
.interface
.instances
:
1973 gajim
.interface
.instances
[account
] = {}
1974 gajim
.interface
.instances
[account
]['remove_account'] = \
1975 RemoveAccountWindow(account
)
1977 dialogs
.ConfirmationDialog(
1978 _('You have opened chat in account %s') % account
,
1979 _('All chat and groupchat windows will be closed. Do you want to '
1981 on_response_ok
= (remove
, account
))
1985 def on_rename_button_clicked(self
, widget
):
1986 if not self
.current_account
:
1988 active
= gajim
.config
.get_per('accounts', self
.current_account
, 'active')
1989 if active
and gajim
.connections
[self
.current_account
].connected
!= 0:
1990 dialogs
.ErrorDialog(
1991 _('You are currently connected to the server'),
1992 _('To change the account name, you must be disconnected.'))
1994 if len(gajim
.events
.get_events(self
.current_account
)):
1995 dialogs
.ErrorDialog(_('Unread events'),
1996 _('To change the account name, you must read all pending '
2000 def on_renamed(new_name
, old_name
):
2001 if new_name
in gajim
.connections
:
2002 dialogs
.ErrorDialog(_('Account Name Already Used'),
2003 _('This name is already used by another of your accounts. '
2004 'Please choose another name.'))
2006 if (new_name
== ''):
2007 dialogs
.ErrorDialog(_('Invalid account name'),
2008 _('Account name cannot be empty.'))
2010 if new_name
.find(' ') != -1:
2011 dialogs
.ErrorDialog(_('Invalid account name'),
2012 _('Account name cannot contain spaces.'))
2016 gajim
.interface
.instances
[new_name
] = gajim
.interface
.instances
[
2018 gajim
.interface
.minimized_controls
[new_name
] = \
2019 gajim
.interface
.minimized_controls
[old_name
]
2020 gajim
.nicks
[new_name
] = gajim
.nicks
[old_name
]
2021 gajim
.block_signed_in_notifications
[new_name
] = \
2022 gajim
.block_signed_in_notifications
[old_name
]
2023 gajim
.groups
[new_name
] = gajim
.groups
[old_name
]
2024 gajim
.gc_connected
[new_name
] = gajim
.gc_connected
[old_name
]
2025 gajim
.automatic_rooms
[new_name
] = gajim
.automatic_rooms
[old_name
]
2026 gajim
.newly_added
[new_name
] = gajim
.newly_added
[old_name
]
2027 gajim
.to_be_removed
[new_name
] = gajim
.to_be_removed
[old_name
]
2028 gajim
.sleeper_state
[new_name
] = gajim
.sleeper_state
[old_name
]
2029 gajim
.encrypted_chats
[new_name
] = gajim
.encrypted_chats
[old_name
]
2030 gajim
.last_message_time
[new_name
] = \
2031 gajim
.last_message_time
[old_name
]
2032 gajim
.status_before_autoaway
[new_name
] = \
2033 gajim
.status_before_autoaway
[old_name
]
2034 gajim
.transport_avatar
[new_name
] = gajim
.transport_avatar
[old_name
]
2035 gajim
.gajim_optional_features
[new_name
] = \
2036 gajim
.gajim_optional_features
[old_name
]
2037 gajim
.caps_hash
[new_name
] = gajim
.caps_hash
[old_name
]
2039 gajim
.contacts
.change_account_name(old_name
, new_name
)
2040 gajim
.events
.change_account_name(old_name
, new_name
)
2042 # change account variable for chat / gc controls
2043 gajim
.interface
.msg_win_mgr
.change_account_name(old_name
, new_name
)
2044 # upgrade account variable in opened windows
2045 for kind
in ('infos', 'disco', 'gc_config', 'search',
2047 for j
in gajim
.interface
.instances
[new_name
][kind
]:
2048 gajim
.interface
.instances
[new_name
][kind
][j
].account
= \
2051 # ServiceCache object keep old property account
2052 if hasattr(gajim
.connections
[old_name
], 'services_cache'):
2053 gajim
.connections
[old_name
].services_cache
.account
= new_name
2054 del gajim
.interface
.instances
[old_name
]
2055 del gajim
.interface
.minimized_controls
[old_name
]
2056 del gajim
.nicks
[old_name
]
2057 del gajim
.block_signed_in_notifications
[old_name
]
2058 del gajim
.groups
[old_name
]
2059 del gajim
.gc_connected
[old_name
]
2060 del gajim
.automatic_rooms
[old_name
]
2061 del gajim
.newly_added
[old_name
]
2062 del gajim
.to_be_removed
[old_name
]
2063 del gajim
.sleeper_state
[old_name
]
2064 del gajim
.encrypted_chats
[old_name
]
2065 del gajim
.last_message_time
[old_name
]
2066 del gajim
.status_before_autoaway
[old_name
]
2067 del gajim
.transport_avatar
[old_name
]
2068 del gajim
.gajim_optional_features
[old_name
]
2069 del gajim
.caps_hash
[old_name
]
2070 gajim
.connections
[old_name
].name
= new_name
2071 gajim
.connections
[old_name
].pep_change_account_name(new_name
)
2072 gajim
.connections
[old_name
].caps_change_account_name(new_name
)
2073 gajim
.connections
[new_name
] = gajim
.connections
[old_name
]
2074 del gajim
.connections
[old_name
]
2075 gajim
.config
.add_per('accounts', new_name
)
2076 old_config
= gajim
.config
.get_per('accounts', old_name
)
2077 for opt
in old_config
:
2078 gajim
.config
.set_per('accounts', new_name
, opt
, old_config
[opt
][1])
2079 gajim
.config
.del_per('accounts', old_name
)
2080 if self
.current_account
== old_name
:
2081 self
.current_account
= new_name
2082 if old_name
== gajim
.ZEROCONF_ACC_NAME
:
2083 gajim
.ZEROCONF_ACC_NAME
= new_name
2085 gajim
.interface
.roster
.setup_and_draw_roster()
2086 self
.init_accounts()
2087 self
.select_account(new_name
)
2089 title
= _('Rename Account')
2090 message
= _('Enter a new name for account %s') % self
.current_account
2091 old_text
= self
.current_account
2092 dialogs
.InputDialog(title
, message
, old_text
, is_modal
=False,
2093 ok_handler
=(on_renamed
, self
.current_account
))
2095 def option_changed(self
, option
, value
):
2096 return gajim
.config
.get_per('accounts', self
.current_account
, option
) != \
2099 def on_jid_entry1_focus_out_event(self
, widget
, event
):
2100 if self
.ignore_events
:
2102 jid
= widget
.get_text()
2103 # check if jid is conform to RFC and stringprep it
2105 jid
= helpers
.parse_jid(jid
)
2106 except helpers
.InvalidFormat
, s
:
2107 if not widget
.is_focus():
2108 pritext
= _('Invalid Jabber ID')
2109 dialogs
.ErrorDialog(pritext
, str(s
))
2110 gobject
.idle_add(lambda: widget
.grab_focus())
2113 jid_splited
= jid
.split('@', 1)
2114 if len(jid_splited
) != 2 and not gajim
.config
.get_per('accounts',
2115 self
.current_account
, 'anonymous_auth'):
2116 if not widget
.is_focus():
2117 pritext
= _('Invalid Jabber ID')
2118 sectext
= _('A Jabber ID must be in the form "user@servername".')
2119 dialogs
.ErrorDialog(pritext
, sectext
)
2120 gobject
.idle_add(lambda: widget
.grab_focus())
2124 if gajim
.config
.get_per('accounts', self
.current_account
,
2126 gajim
.config
.set_per('accounts', self
.current_account
, 'hostname',
2128 if self
.option_changed('hostname', jid_splited
[0]):
2129 self
.need_relogin
= True
2131 if self
.option_changed('name', jid_splited
[0]) or \
2132 self
.option_changed('hostname', jid_splited
[1]):
2133 self
.need_relogin
= True
2135 gajim
.config
.set_per('accounts', self
.current_account
, 'name',
2137 gajim
.config
.set_per('accounts', self
.current_account
, 'hostname',
2140 def on_cert_entry1_focus_out_event(self
, widget
, event
):
2141 if self
.ignore_events
:
2143 client_cert
= widget
.get_text()
2144 if self
.option_changed('client_cert', client_cert
):
2145 self
.need_relogin
= True
2146 gajim
.config
.set_per('accounts', self
.current_account
, 'client_cert',
2149 def on_anonymous_checkbutton1_toggled(self
, widget
):
2150 if self
.ignore_events
:
2152 active
= widget
.get_active()
2153 gajim
.config
.set_per('accounts', self
.current_account
, 'anonymous_auth',
2155 self
.draw_normal_jid()
2157 def on_password_entry1_changed(self
, widget
):
2158 if self
.ignore_events
:
2160 passwords
.save_password(self
.current_account
, widget
.get_text().decode(
2163 def on_save_password_checkbutton1_toggled(self
, widget
):
2164 if self
.ignore_events
:
2166 active
= widget
.get_active()
2167 password_entry
= self
.xml
.get_object('password_entry1')
2168 password_entry
.set_sensitive(active
)
2169 gajim
.config
.set_per('accounts', self
.current_account
, 'savepass', active
)
2171 password
= password_entry
.get_text()
2172 passwords
.save_password(self
.current_account
, password
)
2174 passwords
.save_password(self
.current_account
, '')
2176 def on_resource_entry1_focus_out_event(self
, widget
, event
):
2177 if self
.ignore_events
:
2179 resource
= self
.xml
.get_object('resource_entry1').get_text().decode(
2182 resource
= helpers
.parse_resource(resource
)
2183 except helpers
.InvalidFormat
, s
:
2184 if not widget
.is_focus():
2185 pritext
= _('Invalid Jabber ID')
2186 dialogs
.ErrorDialog(pritext
, str(s
))
2187 gobject
.idle_add(lambda: widget
.grab_focus())
2190 if self
.option_changed('resource', resource
):
2191 self
.need_relogin
= True
2193 gajim
.config
.set_per('accounts', self
.current_account
, 'resource',
2196 def on_adjust_priority_with_status_checkbutton1_toggled(self
, widget
):
2197 self
.xml
.get_object('priority_spinbutton1').set_sensitive(
2198 not widget
.get_active())
2199 self
.on_checkbutton_toggled(widget
, 'adjust_priority_with_status',
2200 account
= self
.current_account
)
2202 def on_priority_spinbutton1_value_changed(self
, widget
):
2203 prio
= widget
.get_value_as_int()
2205 if self
.option_changed('priority', prio
):
2206 self
.resend_presence
= True
2208 gajim
.config
.set_per('accounts', self
.current_account
, 'priority', prio
)
2210 def on_synchronise_contacts_button1_clicked(self
, widget
):
2212 dialogs
.SynchroniseSelectAccountDialog(self
.current_account
)
2213 except GajimGeneralException
:
2214 # If we showed ErrorDialog, there will not be dialog instance
2217 def on_change_password_button1_clicked(self
, widget
):
2218 def on_changed(new_password
):
2219 if new_password
is not None:
2220 gajim
.connections
[self
.current_account
].change_password(
2222 if self
.xml
.get_object('save_password_checkbutton1').get_active():
2223 self
.xml
.get_object('password_entry1').set_text(new_password
)
2226 dialogs
.ChangePasswordDialog(self
.current_account
, on_changed
)
2227 except GajimGeneralException
:
2228 # if we showed ErrorDialog, there will not be dialog instance
2231 def on_autoconnect_checkbutton_toggled(self
, widget
):
2232 if self
.ignore_events
:
2234 self
.on_checkbutton_toggled(widget
, 'autoconnect',
2235 account
=self
.current_account
)
2237 def on_autoreconnect_checkbutton_toggled(self
, widget
):
2238 if self
.ignore_events
:
2240 self
.on_checkbutton_toggled(widget
, 'autoreconnect',
2241 account
=self
.current_account
)
2243 def on_log_history_checkbutton_toggled(self
, widget
):
2244 if self
.ignore_events
:
2246 list_no_log_for
= gajim
.config
.get_per('accounts', self
.current_account
,
2247 'no_log_for').split()
2248 if self
.current_account
in list_no_log_for
:
2249 list_no_log_for
.remove(self
.current_account
)
2251 if not widget
.get_active():
2252 list_no_log_for
.append(self
.current_account
)
2253 gajim
.config
.set_per('accounts', self
.current_account
, 'no_log_for',
2254 ' '.join(list_no_log_for
))
2256 def on_sync_with_global_status_checkbutton_toggled(self
, widget
):
2257 if self
.ignore_events
:
2259 self
.on_checkbutton_toggled(widget
, 'sync_with_global_status',
2260 account
=self
.current_account
)
2261 gajim
.interface
.roster
.update_status_combobox()
2263 def on_use_ft_proxies_checkbutton1_toggled(self
, widget
):
2264 if self
.ignore_events
:
2266 self
.on_checkbutton_toggled(widget
, 'use_ft_proxies',
2267 account
=self
.current_account
)
2269 def on_use_env_http_proxy_checkbutton1_toggled(self
, widget
):
2270 if self
.ignore_events
:
2272 self
.on_checkbutton_toggled(widget
, 'use_env_http_proxy',
2273 account
=self
.current_account
)
2274 hbox
= self
.xml
.get_object('proxy_hbox1')
2275 hbox
.set_sensitive(not widget
.get_active())
2277 def on_proxies_combobox1_changed(self
, widget
):
2278 active
= widget
.get_active()
2279 proxy
= widget
.get_model()[active
][0].decode('utf-8')
2280 if proxy
== _('None'):
2283 if self
.option_changed('proxy', proxy
):
2284 self
.need_relogin
= True
2286 gajim
.config
.set_per('accounts', self
.current_account
, 'proxy', proxy
)
2288 def on_manage_proxies_button1_clicked(self
, widget
):
2289 if 'manage_proxies' in gajim
.interface
.instances
:
2290 gajim
.interface
.instances
['manage_proxies'].window
.present()
2292 gajim
.interface
.instances
['manage_proxies'] = ManageProxiesWindow()
2294 def on_warn_when_insecure_connection_checkbutton1_toggled(self
, widget
):
2295 if self
.ignore_events
:
2298 self
.on_checkbutton_toggled(widget
, 'warn_when_insecure_ssl_connection',
2299 account
=self
.current_account
)
2301 def on_send_keepalive_checkbutton1_toggled(self
, widget
):
2302 if self
.ignore_events
:
2304 self
.on_checkbutton_toggled(widget
, 'keep_alives_enabled',
2305 account
=self
.current_account
)
2306 gajim
.config
.set_per('accounts', self
.current_account
,
2307 'ping_alives_enabled', widget
.get_active())
2309 def on_custom_host_port_checkbutton1_toggled(self
, widget
):
2310 if self
.option_changed('use_custom_host', widget
.get_active()):
2311 self
.need_relogin
= True
2313 self
.on_checkbutton_toggled(widget
, 'use_custom_host',
2314 account
=self
.current_account
)
2315 active
= widget
.get_active()
2316 self
.xml
.get_object('custom_host_port_hbox1').set_sensitive(active
)
2318 def on_custom_host_entry1_changed(self
, widget
):
2319 if self
.ignore_events
:
2321 host
= widget
.get_text().decode('utf-8')
2322 if self
.option_changed('custom_host', host
):
2323 self
.need_relogin
= True
2324 gajim
.config
.set_per('accounts', self
.current_account
, 'custom_host',
2327 def on_custom_port_entry_focus_out_event(self
, widget
, event
):
2328 if self
.ignore_events
:
2330 custom_port
= widget
.get_text()
2332 custom_port
= int(custom_port
)
2334 if not widget
.is_focus():
2335 dialogs
.ErrorDialog(_('Invalid entry'),
2336 _('Custom port must be a port number.'))
2337 gobject
.idle_add(lambda: widget
.grab_focus())
2339 if self
.option_changed('custom_port', custom_port
):
2340 self
.need_relogin
= True
2341 gajim
.config
.set_per('accounts', self
.current_account
, 'custom_port',
2344 def on_gpg_choose_button_clicked(self
, widget
, data
= None):
2345 if self
.current_account
in gajim
.connections
and \
2346 gajim
.connections
[self
.current_account
].gpg
:
2347 secret_keys
= gajim
.connections
[self
.current_account
].\
2348 ask_gpg_secrete_keys()
2350 # self.current_account is None and/or gajim.connections is {}
2353 secret_keys
= gpg
.GnuPG().get_secret_keys()
2357 dialogs
.ErrorDialog(_('Failed to get secret keys'),
2358 _('There is no OpenPGP secret key available.'))
2359 secret_keys
[_('None')] = _('None')
2361 def on_key_selected(keyID
):
2364 if self
.current_account
== gajim
.ZEROCONF_ACC_NAME
:
2365 wiget_name_ext
= '2'
2367 wiget_name_ext
= '1'
2368 gpg_key_label
= self
.xml
.get_object('gpg_key_label' + wiget_name_ext
)
2369 gpg_name_label
= self
.xml
.get_object('gpg_name_label' + wiget_name_ext
)
2370 use_gpg_agent_checkbutton
= self
.xml
.get_object(
2371 'use_gpg_agent_checkbutton' + wiget_name_ext
)
2372 if keyID
[0] == _('None'):
2373 gpg_key_label
.set_text(_('No key selected'))
2374 gpg_name_label
.set_text('')
2375 use_gpg_agent_checkbutton
.set_sensitive(False)
2376 if self
.option_changed('keyid', ''):
2377 self
.need_relogin
= True
2378 gajim
.config
.set_per('accounts', self
.current_account
, 'keyname',
2380 gajim
.config
.set_per('accounts', self
.current_account
, 'keyid', '')
2382 gpg_key_label
.set_text(keyID
[0])
2383 gpg_name_label
.set_text(keyID
[1])
2384 use_gpg_agent_checkbutton
.set_sensitive(True)
2385 if self
.option_changed('keyid', keyID
[0]):
2386 self
.need_relogin
= True
2387 gajim
.config
.set_per('accounts', self
.current_account
, 'keyname',
2389 gajim
.config
.set_per('accounts', self
.current_account
, 'keyid',
2392 dialogs
.ChooseGPGKeyDialog(_('OpenPGP Key Selection'),
2393 _('Choose your OpenPGP key'), secret_keys
, on_key_selected
)
2395 def on_use_gpg_agent_checkbutton_toggled(self
, widget
):
2396 self
.on_checkbutton_toggled(widget
, 'use_gpg_agent')
2398 def on_edit_details_button1_clicked(self
, widget
):
2399 if self
.current_account
not in gajim
.interface
.instances
:
2400 dialogs
.ErrorDialog(_('No such account available'),
2401 _('You must create your account before editing your personal '
2405 # show error dialog if account is newly created (not in gajim.connections)
2406 if self
.current_account
not in gajim
.connections
or \
2407 gajim
.connections
[self
.current_account
].connected
< 2:
2408 dialogs
.ErrorDialog(_('You are not connected to the server'),
2409 _('Without a connection, you can not edit your personal information.'))
2412 if not gajim
.connections
[self
.current_account
].vcard_supported
:
2413 dialogs
.ErrorDialog(_("Your server doesn't support Vcard"),
2414 _("Your server can't save your personal information."))
2417 gajim
.interface
.edit_own_details(self
.current_account
)
2419 def on_checkbutton_toggled(self
, widget
, config_name
,
2420 change_sensitivity_widgets
= None, account
= None):
2422 gajim
.config
.set_per('accounts', account
, config_name
,
2423 widget
.get_active())
2425 gajim
.config
.set(config_name
, widget
.get_active())
2426 if change_sensitivity_widgets
:
2427 for w
in change_sensitivity_widgets
:
2428 w
.set_sensitive(widget
.get_active())
2429 gajim
.interface
.save_config()
2431 def on_merge_checkbutton_toggled(self
, widget
):
2432 self
.on_checkbutton_toggled(widget
, 'mergeaccounts')
2433 if len(gajim
.connections
) >= 2: # Do not merge accounts if only one active
2434 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2436 gajim
.interface
.roster
.regroup
= False
2437 gajim
.interface
.roster
.setup_and_draw_roster()
2439 def _disable_account(self
, account
):
2440 gajim
.interface
.roster
.close_all(account
)
2441 if account
== gajim
.ZEROCONF_ACC_NAME
:
2442 gajim
.connections
[account
].disable_account()
2443 del gajim
.connections
[account
]
2444 gajim
.interface
.save_config()
2445 del gajim
.interface
.instances
[account
]
2446 del gajim
.interface
.minimized_controls
[account
]
2447 del gajim
.nicks
[account
]
2448 del gajim
.block_signed_in_notifications
[account
]
2449 del gajim
.groups
[account
]
2450 gajim
.contacts
.remove_account(account
)
2451 del gajim
.gc_connected
[account
]
2452 del gajim
.automatic_rooms
[account
]
2453 del gajim
.to_be_removed
[account
]
2454 del gajim
.newly_added
[account
]
2455 del gajim
.sleeper_state
[account
]
2456 del gajim
.encrypted_chats
[account
]
2457 del gajim
.last_message_time
[account
]
2458 del gajim
.status_before_autoaway
[account
]
2459 del gajim
.transport_avatar
[account
]
2460 del gajim
.gajim_optional_features
[account
]
2461 del gajim
.caps_hash
[account
]
2462 if len(gajim
.connections
) >= 2:
2463 # Do not merge accounts if only one exists
2464 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2466 gajim
.interface
.roster
.regroup
= False
2467 gajim
.interface
.roster
.setup_and_draw_roster()
2468 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
2470 def _enable_account(self
, account
):
2471 if account
== gajim
.ZEROCONF_ACC_NAME
:
2472 gajim
.connections
[account
] = connection_zeroconf
.ConnectionZeroconf(
2474 if gajim
.connections
[account
].gpg
:
2475 self
.xml
.get_object('gpg_choose_button2').set_sensitive(True)
2477 gajim
.connections
[account
] = common
.connection
.Connection(account
)
2478 if gajim
.connections
[account
].gpg
:
2479 self
.xml
.get_object('gpg_choose_button1').set_sensitive(True)
2480 self
.init_account_gpg()
2482 gajim
.interface
.instances
[account
] = {'infos': {},
2483 'disco': {}, 'gc_config': {}, 'search': {}, 'online_dialog': {}}
2484 gajim
.interface
.minimized_controls
[account
] = {}
2485 gajim
.connections
[account
].connected
= 0
2486 gajim
.groups
[account
] = {}
2487 gajim
.contacts
.add_account(account
)
2488 gajim
.gc_connected
[account
] = {}
2489 gajim
.automatic_rooms
[account
] = {}
2490 gajim
.newly_added
[account
] = []
2491 gajim
.to_be_removed
[account
] = []
2492 if account
== gajim
.ZEROCONF_ACC_NAME
:
2493 gajim
.nicks
[account
] = gajim
.ZEROCONF_ACC_NAME
2495 gajim
.nicks
[account
] = gajim
.config
.get_per('accounts', account
,
2497 gajim
.block_signed_in_notifications
[account
] = True
2498 gajim
.sleeper_state
[account
] = 'off'
2499 gajim
.encrypted_chats
[account
] = []
2500 gajim
.last_message_time
[account
] = {}
2501 gajim
.status_before_autoaway
[account
] = ''
2502 gajim
.transport_avatar
[account
] = {}
2503 gajim
.gajim_optional_features
[account
] = []
2504 gajim
.caps_hash
[account
] = ''
2506 if len(gajim
.connections
) >= 2:
2507 # Do not merge accounts if only one exists
2508 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2510 gajim
.interface
.roster
.regroup
= False
2511 gajim
.interface
.roster
.setup_and_draw_roster()
2512 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
2513 gajim
.interface
.save_config()
2515 def on_enable_zeroconf_checkbutton2_toggled(self
, widget
):
2516 # don't do anything if there is an account with the local name but is a
2518 if self
.ignore_events
:
2520 if self
.current_account
in gajim
.connections
and \
2521 gajim
.connections
[self
.current_account
].connected
> 0:
2522 self
.ignore_events
= True
2523 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_active(True)
2524 self
.ignore_events
= False
2525 dialogs
.ErrorDialog(
2526 _('You are currently connected to the server'),
2527 _('To disable the account, you must be disconnected.'))
2529 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
and not \
2530 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].is_zeroconf
:
2531 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].dispatch('ERROR',
2532 (_('Account Local already exists.'),
2533 _('Please rename or remove it before enabling link-local messaging'
2537 if gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
, 'active') \
2538 and not widget
.get_active():
2539 self
.xml
.get_object('zeroconf_notebook').set_sensitive(False)
2541 self
._disable
_account
(gajim
.ZEROCONF_ACC_NAME
)
2543 elif not gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
2544 'active') and widget
.get_active():
2545 self
.xml
.get_object('zeroconf_notebook').set_sensitive(True)
2546 # enable (will create new account if not present)
2547 self
._enable
_account
(gajim
.ZEROCONF_ACC_NAME
)
2549 self
.on_checkbutton_toggled(widget
, 'active',
2550 account
=gajim
.ZEROCONF_ACC_NAME
)
2552 def on_enable_checkbutton1_toggled(self
, widget
):
2553 if self
.ignore_events
:
2555 if self
.current_account
in gajim
.connections
and \
2556 gajim
.connections
[self
.current_account
].connected
> 0:
2557 # connecting or connected
2558 self
.ignore_events
= True
2559 self
.xml
.get_object('enable_checkbutton1').set_active(True)
2560 self
.ignore_events
= False
2561 dialogs
.ErrorDialog(
2562 _('You are currently connected to the server'),
2563 _('To disable the account, you must be disconnected.'))
2565 # add/remove account in roster and all variables
2566 if widget
.get_active():
2568 self
._enable
_account
(self
.current_account
)
2571 self
._disable
_account
(self
.current_account
)
2572 self
.on_checkbutton_toggled(widget
, 'active',
2573 account
=self
.current_account
, change_sensitivity_widgets
=[
2574 self
.xml
.get_object('normal_notebook1')])
2576 def on_custom_port_checkbutton2_toggled(self
, widget
):
2577 self
.xml
.get_object('custom_port_entry2').set_sensitive(
2578 widget
.get_active())
2579 self
.on_checkbutton_toggled(widget
, 'use_custom_host',
2580 account
= self
.current_account
)
2581 if not widget
.get_active():
2582 self
.xml
.get_object('custom_port_entry2').set_text('5298')
2584 def on_first_name_entry2_changed(self
, widget
):
2585 if self
.ignore_events
:
2587 name
= widget
.get_text().decode('utf-8')
2588 if self
.option_changed('zeroconf_first_name', name
):
2589 self
.need_relogin
= True
2590 gajim
.config
.set_per('accounts', self
.current_account
,
2591 'zeroconf_first_name', name
)
2593 def on_last_name_entry2_changed(self
, widget
):
2594 if self
.ignore_events
:
2596 name
= widget
.get_text().decode('utf-8')
2597 if self
.option_changed('zeroconf_last_name', name
):
2598 self
.need_relogin
= True
2599 gajim
.config
.set_per('accounts', self
.current_account
,
2600 'zeroconf_last_name', name
)
2602 def on_jabber_id_entry2_changed(self
, widget
):
2603 if self
.ignore_events
:
2605 id_
= widget
.get_text().decode('utf-8')
2606 if self
.option_changed('zeroconf_jabber_id', id_
):
2607 self
.need_relogin
= True
2608 gajim
.config
.set_per('accounts', self
.current_account
,
2609 'zeroconf_jabber_id', id_
)
2611 def on_email_entry2_changed(self
, widget
):
2612 if self
.ignore_events
:
2614 email
= widget
.get_text().decode('utf-8')
2615 if self
.option_changed('zeroconf_email', email
):
2616 self
.need_relogin
= True
2617 gajim
.config
.set_per('accounts', self
.current_account
,
2618 'zeroconf_email', email
)
2620 class FakeDataForm(gtk
.Table
, object):
2622 Class for forms that are in XML format <entry1>value1</entry1> infos in a
2623 table {entry1: value1}
2626 def __init__(self
, infos
):
2627 gtk
.Table
.__init
__(self
)
2632 def _draw_table(self
):
2637 if 'instructions' in self
.infos
:
2639 self
.resize(rows
= nbrow
, columns
= 2)
2640 label
= gtk
.Label(self
.infos
['instructions'])
2641 self
.attach(label
, 0, 2, 0, 1, 0, 0, 0, 0)
2642 for name
in self
.infos
.keys():
2643 if name
in ('key', 'instructions', 'x', 'registered'):
2649 self
.resize(rows
= nbrow
, columns
= 2)
2650 label
= gtk
.Label(name
.capitalize() + ':')
2651 self
.attach(label
, 0, 1, nbrow
- 1, nbrow
, 0, 0, 0, 0)
2653 entry
.set_activates_default(True)
2654 if self
.infos
[name
]:
2655 entry
.set_text(self
.infos
[name
])
2656 if name
== 'password':
2657 entry
.set_visibility(False)
2658 self
.attach(entry
, 1, 2, nbrow
- 1, nbrow
, 0, 0, 0, 0)
2659 self
.entries
[name
] = entry
2663 def get_infos(self
):
2664 for name
in self
.entries
.keys():
2665 self
.infos
[name
] = self
.entries
[name
].get_text().decode('utf-8')
2668 class ServiceRegistrationWindow
:
2670 Class for Service registration window. Window that appears when we want to
2671 subscribe to a service if is_form we use dataforms_widget else we use
2672 service_registarion_window
2674 def __init__(self
, service
, infos
, account
, is_form
):
2675 self
.service
= service
2676 self
.account
= account
2677 self
.is_form
= is_form
2678 self
.xml
= gtkgui_helpers
.get_gtk_builder('service_registration_window.ui')
2679 self
.window
= self
.xml
.get_object('service_registration_window')
2680 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2682 dataform
= dataforms
.ExtendForm(node
= infos
)
2683 self
.data_form_widget
= dataforms_widget
.DataFormWidget(dataform
)
2684 if self
.data_form_widget
.title
:
2685 self
.window
.set_title('%s - Gajim' % self
.data_form_widget
.title
)
2686 table
= self
.xml
.get_object('table')
2687 table
.attach(self
.data_form_widget
, 0, 2, 0, 1)
2689 if 'registered' in infos
:
2690 self
.window
.set_title(_('Edit %s') % service
)
2692 self
.window
.set_title(_('Register to %s') % service
)
2693 self
.data_form_widget
= FakeDataForm(infos
)
2694 table
= self
.xml
.get_object('table')
2695 table
.attach(self
.data_form_widget
, 0, 2, 0, 1)
2697 self
.xml
.connect_signals(self
)
2698 self
.window
.show_all()
2700 def on_cancel_button_clicked(self
, widget
):
2701 self
.window
.destroy()
2703 def on_ok_button_clicked(self
, widget
):
2704 # send registration info to the core
2706 form
= self
.data_form_widget
.data_form
2707 gajim
.connections
[self
.account
].register_agent(self
.service
,
2708 form
, True) # True is for is_form
2710 infos
= self
.data_form_widget
.get_infos()
2711 if 'instructions' in infos
:
2712 del infos
['instructions']
2713 if 'registered' in infos
:
2714 del infos
['registered']
2715 gajim
.connections
[self
.account
].register_agent(self
.service
, infos
)
2717 self
.window
.destroy()
2719 class GroupchatConfigWindow
:
2721 def __init__(self
, account
, room_jid
, form
=None):
2722 self
.account
= account
2723 self
.room_jid
= room_jid
2725 self
.remove_button
= {}
2726 self
.affiliation_treeview
= {}
2727 self
.start_users_dict
= {} # list at the beginning
2728 self
.affiliation_labels
= {'outcast': _('Ban List'),
2729 'member': _('Member List'), 'owner': _('Owner List'),
2730 'admin':_('Administrator List')}
2732 self
.xml
= gtkgui_helpers
.get_gtk_builder('data_form_window.ui',
2734 self
.window
= self
.xml
.get_object('data_form_window')
2735 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2738 config_vbox
= self
.xml
.get_object('config_vbox')
2739 self
.data_form_widget
= dataforms_widget
.DataFormWidget(self
.form
)
2740 # hide scrollbar of this data_form_widget, we already have in this
2742 sw
= self
.data_form_widget
.xml
.get_object(
2743 'single_form_scrolledwindow')
2744 sw
.set_policy(gtk
.POLICY_NEVER
, gtk
.POLICY_NEVER
)
2746 self
.xml
.get_object('title_label').set_text(self
.form
.title
)
2748 self
.xml
.get_object('title_hseparator').set_no_show_all(True)
2749 self
.xml
.get_object('title_hseparator').hide()
2751 self
.data_form_widget
.show()
2752 config_vbox
.pack_start(self
.data_form_widget
)
2754 self
.xml
.get_object('title_label').set_no_show_all(True)
2755 self
.xml
.get_object('title_label').hide()
2756 self
.xml
.get_object('title_hseparator').set_no_show_all(True)
2757 self
.xml
.get_object('title_hseparator').hide()
2758 self
.xml
.get_object('config_hseparator').set_no_show_all(True)
2759 self
.xml
.get_object('config_hseparator').hide()
2761 # Draw the edit affiliation list things
2762 add_on_vbox
= self
.xml
.get_object('add_on_vbox')
2764 for affiliation
in self
.affiliation_labels
.keys():
2765 self
.start_users_dict
[affiliation
] = {}
2766 hbox
= gtk
.HBox(spacing
=5)
2767 add_on_vbox
.pack_start(hbox
, False)
2769 label
= gtk
.Label(self
.affiliation_labels
[affiliation
])
2770 hbox
.pack_start(label
, False)
2772 bb
= gtk
.HButtonBox()
2773 bb
.set_layout(gtk
.BUTTONBOX_END
)
2776 add_button
= gtk
.Button(stock
=gtk
.STOCK_ADD
)
2777 add_button
.connect('clicked', self
.on_add_button_clicked
,
2779 bb
.pack_start(add_button
)
2780 self
.remove_button
[affiliation
] = gtk
.Button(stock
=gtk
.STOCK_REMOVE
)
2781 self
.remove_button
[affiliation
].set_sensitive(False)
2782 self
.remove_button
[affiliation
].connect('clicked',
2783 self
.on_remove_button_clicked
, affiliation
)
2784 bb
.pack_start(self
.remove_button
[affiliation
])
2786 # jid, reason, nick, role
2787 liststore
= gtk
.ListStore(str, str, str, str)
2788 self
.affiliation_treeview
[affiliation
] = gtk
.TreeView(liststore
)
2789 self
.affiliation_treeview
[affiliation
].get_selection().set_mode(
2790 gtk
.SELECTION_MULTIPLE
)
2791 self
.affiliation_treeview
[affiliation
].connect('cursor-changed',
2792 self
.on_affiliation_treeview_cursor_changed
, affiliation
)
2793 renderer
= gtk
.CellRendererText()
2794 col
= gtk
.TreeViewColumn(_('JID'), renderer
)
2795 col
.add_attribute(renderer
, 'text', 0)
2796 col
.set_resizable(True)
2797 col
.set_sort_column_id(0)
2798 self
.affiliation_treeview
[affiliation
].append_column(col
)
2800 if affiliation
== 'outcast':
2801 renderer
= gtk
.CellRendererText()
2802 renderer
.set_property('editable', True)
2803 renderer
.connect('edited', self
.on_cell_edited
)
2804 col
= gtk
.TreeViewColumn(_('Reason'), renderer
)
2805 col
.add_attribute(renderer
, 'text', 1)
2806 col
.set_resizable(True)
2807 col
.set_sort_column_id(1)
2808 self
.affiliation_treeview
[affiliation
].append_column(col
)
2809 elif affiliation
== 'member':
2810 renderer
= gtk
.CellRendererText()
2811 col
= gtk
.TreeViewColumn(_('Nick'), renderer
)
2812 col
.add_attribute(renderer
, 'text', 2)
2813 col
.set_resizable(True)
2814 col
.set_sort_column_id(2)
2815 self
.affiliation_treeview
[affiliation
].append_column(col
)
2816 renderer
= gtk
.CellRendererText()
2817 col
= gtk
.TreeViewColumn(_('Role'), renderer
)
2818 col
.add_attribute(renderer
, 'text', 3)
2819 col
.set_resizable(True)
2820 col
.set_sort_column_id(3)
2821 self
.affiliation_treeview
[affiliation
].append_column(col
)
2823 sw
= gtk
.ScrolledWindow()
2824 sw
.set_policy(gtk
.POLICY_AUTOMATIC
, gtk
.POLICY_NEVER
)
2825 sw
.add(self
.affiliation_treeview
[affiliation
])
2826 add_on_vbox
.pack_start(sw
)
2827 gajim
.connections
[self
.account
].get_affiliation_list(self
.room_jid
,
2830 self
.xml
.connect_signals(self
)
2831 self
.window
.show_all()
2833 def on_cancel_button_clicked(self
, widget
):
2834 self
.window
.destroy()
2836 def on_cell_edited(self
, cell
, path
, new_text
):
2837 model
= self
.affiliation_treeview
['outcast'].get_model()
2838 new_text
= new_text
.decode('utf-8')
2839 iter_
= model
.get_iter(path
)
2840 model
[iter_
][1] = new_text
2842 def on_add_button_clicked(self
, widget
, affiliation
):
2843 if affiliation
== 'outcast':
2844 title
= _('Banning...')
2845 #You can move '\n' before user@domain if that line is TOO BIG
2846 prompt
= _('<b>Whom do you want to ban?</b>\n\n')
2847 elif affiliation
== 'member':
2848 title
= _('Adding Member...')
2849 prompt
= _('<b>Whom do you want to make a member?</b>\n\n')
2850 elif affiliation
== 'owner':
2851 title
= _('Adding Owner...')
2852 prompt
= _('<b>Whom do you want to make an owner?</b>\n\n')
2854 title
= _('Adding Administrator...')
2855 prompt
= _('<b>Whom do you want to make an administrator?</b>\n\n')
2856 prompt
+= _('Can be one of the following:\n'
2857 '1. user@domain/resource (only that resource matches).\n'
2858 '2. user@domain (any resource matches).\n'
2859 '3. domain/resource (only that resource matches).\n'
2860 '4. domain (the domain itself matches, as does any user@domain,\n'
2861 'domain/resource, or address containing a subdomain).')
2866 model
= self
.affiliation_treeview
[affiliation
].get_model()
2867 model
.append((jid
, '', '', ''))
2868 dialogs
.InputDialog(title
, prompt
, ok_handler
=on_ok
)
2870 def on_remove_button_clicked(self
, widget
, affiliation
):
2871 selection
= self
.affiliation_treeview
[affiliation
].get_selection()
2872 model
, paths
= selection
.get_selected_rows()
2875 row_refs
.append(gtk
.TreeRowReference(model
, path
))
2876 for row_ref
in row_refs
:
2877 path
= row_ref
.get_path()
2878 iter_
= model
.get_iter(path
)
2880 self
.remove_button
[affiliation
].set_sensitive(False)
2882 def on_affiliation_treeview_cursor_changed(self
, widget
, affiliation
):
2883 self
.remove_button
[affiliation
].set_sensitive(True)
2885 def affiliation_list_received(self
, users_dict
):
2887 Fill the affiliation treeview
2889 for jid
in users_dict
:
2890 affiliation
= users_dict
[jid
]['affiliation']
2891 if affiliation
not in self
.affiliation_labels
.keys():
2892 # Unknown affiliation or 'none' affiliation, do not show it
2894 self
.start_users_dict
[affiliation
][jid
] = users_dict
[jid
]
2895 tv
= self
.affiliation_treeview
[affiliation
]
2896 model
= tv
.get_model()
2897 reason
= users_dict
[jid
].get('reason', '')
2898 nick
= users_dict
[jid
].get('nick', '')
2899 role
= users_dict
[jid
].get('role', '')
2900 model
.append((jid
, reason
, nick
, role
))
2902 def on_data_form_window_destroy(self
, widget
):
2903 del gajim
.interface
.instances
[self
.account
]['gc_config'][self
.room_jid
]
2905 def on_ok_button_clicked(self
, widget
):
2907 form
= self
.data_form_widget
.data_form
2908 gajim
.connections
[self
.account
].send_gc_config(self
.room_jid
, form
)
2909 for affiliation
in self
.affiliation_labels
.keys():
2911 actual_jid_list
= []
2912 model
= self
.affiliation_treeview
[affiliation
].get_model()
2913 iter_
= model
.get_iter_first()
2916 jid
= model
[iter_
][0].decode('utf-8')
2917 actual_jid_list
.append(jid
)
2918 if jid
not in self
.start_users_dict
[affiliation
] or \
2919 (affiliation
== 'outcast' and 'reason' in self
.start_users_dict
[
2920 affiliation
][jid
] and self
.start_users_dict
[affiliation
][jid
]\
2921 ['reason'] != model
[iter_
][1].decode('utf-8')):
2922 users_dict
[jid
] = {'affiliation': affiliation
}
2923 if affiliation
== 'outcast':
2924 users_dict
[jid
]['reason'] = model
[iter_
][1].decode(
2926 iter_
= model
.iter_next(iter_
)
2927 # remove removed one
2928 for jid
in self
.start_users_dict
[affiliation
]:
2929 if jid
not in actual_jid_list
:
2930 users_dict
[jid
] = {'affiliation': 'none'}
2932 gajim
.connections
[self
.account
].send_gc_affiliation_list(
2933 self
.room_jid
, users_dict
)
2934 self
.window
.destroy()
2936 #---------- RemoveAccountWindow class -------------#
2937 class RemoveAccountWindow
:
2939 Ask for removing from gajim only or from gajim and server too and do
2940 removing of the account given
2943 def on_remove_account_window_destroy(self
, widget
):
2944 if self
.account
in gajim
.interface
.instances
:
2945 del gajim
.interface
.instances
[self
.account
]['remove_account']
2947 def on_cancel_button_clicked(self
, widget
):
2948 self
.window
.destroy()
2950 def __init__(self
, account
):
2951 self
.account
= account
2952 xml
= gtkgui_helpers
.get_gtk_builder('remove_account_window.ui')
2953 self
.window
= xml
.get_object('remove_account_window')
2954 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2955 self
.remove_and_unregister_radiobutton
= xml
.get_object(
2956 'remove_and_unregister_radiobutton')
2957 self
.window
.set_title(_('Removing %s account') % self
.account
)
2958 xml
.connect_signals(self
)
2959 self
.window
.show_all()
2961 def on_remove_button_clicked(self
, widget
):
2963 if self
.account
in gajim
.connections
and \
2964 gajim
.connections
[self
.account
].connected
and \
2965 not self
.remove_and_unregister_radiobutton
.get_active():
2966 # change status to offline only if we will not remove this JID from
2968 gajim
.connections
[self
.account
].change_status('offline', 'offline')
2969 if self
.remove_and_unregister_radiobutton
.get_active():
2970 if not self
.account
in gajim
.connections
:
2971 dialogs
.ErrorDialog(
2972 _('Account is disabled'),
2973 _('To unregister from a server, account must be '
2976 if not gajim
.connections
[self
.account
].password
:
2977 def on_ok(passphrase
, checked
):
2978 if passphrase
== -1:
2979 # We don't remove account cause we canceled pw window
2981 gajim
.connections
[self
.account
].password
= passphrase
2982 gajim
.connections
[self
.account
].unregister_account(
2983 self
._on
_remove
_success
)
2985 dialogs
.PassphraseDialog(
2986 _('Password Required'),
2987 _('Enter your password for account %s') % self
.account
,
2988 _('Save password'), ok_handler
=on_ok
)
2990 gajim
.connections
[self
.account
].unregister_account(
2991 self
._on
_remove
_success
)
2993 self
._on
_remove
_success
(True)
2995 if self
.account
in gajim
.connections
and \
2996 gajim
.connections
[self
.account
].connected
:
2997 dialogs
.ConfirmationDialog(
2998 _('Account "%s" is connected to the server') % self
.account
,
2999 _('If you remove it, the connection will be lost.'),
3000 on_response_ok
=remove
)
3004 def on_remove_responce_ok(self
, is_checked
):
3006 self
._on
_remove
_success
(True)
3008 def _on_remove_success(self
, res
):
3009 # action of unregistration has failed, we don't remove the account
3010 # Error message is send by connect_and_auth()
3012 dialogs
.ConfirmationDialogDoubleRadio(
3013 _('Connection to server %s failed') % self
.account
,
3014 _('What would you like to do?'),
3015 _('Remove only from Gajim'),
3016 _('Don\'t remove anything. I\'ll try again later'),
3017 on_response_ok
=self
.on_remove_responce_ok
, is_modal
=False)
3019 # Close all opened windows
3020 gajim
.interface
.roster
.close_all(self
.account
, force
=True)
3021 if self
.account
in gajim
.connections
:
3022 gajim
.connections
[self
.account
].disconnect(on_purpose
=True)
3023 gajim
.connections
[self
.account
].cleanup()
3024 del gajim
.connections
[self
.account
]
3025 gajim
.logger
.remove_roster(gajim
.get_jid_from_account(self
.account
))
3026 gajim
.config
.del_per('accounts', self
.account
)
3027 gajim
.interface
.save_config()
3028 del gajim
.interface
.instances
[self
.account
]
3029 if self
.account
in gajim
.nicks
:
3030 del gajim
.interface
.minimized_controls
[self
.account
]
3031 del gajim
.nicks
[self
.account
]
3032 del gajim
.block_signed_in_notifications
[self
.account
]
3033 del gajim
.groups
[self
.account
]
3034 gajim
.contacts
.remove_account(self
.account
)
3035 del gajim
.gc_connected
[self
.account
]
3036 del gajim
.automatic_rooms
[self
.account
]
3037 del gajim
.to_be_removed
[self
.account
]
3038 del gajim
.newly_added
[self
.account
]
3039 del gajim
.sleeper_state
[self
.account
]
3040 del gajim
.encrypted_chats
[self
.account
]
3041 del gajim
.last_message_time
[self
.account
]
3042 del gajim
.status_before_autoaway
[self
.account
]
3043 del gajim
.transport_avatar
[self
.account
]
3044 del gajim
.gajim_optional_features
[self
.account
]
3045 del gajim
.caps_hash
[self
.account
]
3046 if len(gajim
.connections
) >= 2: # Do not merge accounts if only one exists
3047 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
3049 gajim
.interface
.roster
.regroup
= False
3050 gajim
.interface
.roster
.setup_and_draw_roster()
3051 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3052 if 'accounts' in gajim
.interface
.instances
:
3053 gajim
.interface
.instances
['accounts'].init_accounts()
3054 gajim
.interface
.instances
['accounts'].init_account()
3055 self
.window
.destroy()
3057 #---------- ManageBookmarksWindow class -------------#
3058 class ManageBookmarksWindow
:
3060 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_bookmarks_window.ui')
3061 self
.window
= self
.xml
.get_object('manage_bookmarks_window')
3062 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3064 # Account-JID, RoomName, Room-JID, Autojoin, Minimize, Passowrd, Nick,
3066 self
.treestore
= gtk
.TreeStore(str, str, str, bool, bool, str, str, str)
3067 self
.treestore
.set_sort_column_id(1, gtk
.SORT_ASCENDING
)
3069 # Store bookmarks in treeview.
3070 for account
in gajim
.connections
:
3071 if gajim
.connections
[account
].connected
<= 1:
3073 if gajim
.connections
[account
].is_zeroconf
:
3075 if not gajim
.connections
[account
].private_storage_supported
:
3077 iter_
= self
.treestore
.append(None, [None, account
, None, None,
3078 None, None, None, None])
3080 for bookmark
in gajim
.connections
[account
].bookmarks
:
3081 if bookmark
['name'] == '':
3082 # No name was given for this bookmark.
3083 # Use the first part of JID instead...
3084 name
= bookmark
['jid'].split("@")[0]
3085 bookmark
['name'] = name
3087 # make '1', '0', 'true', 'false' (or other) to True/False
3088 autojoin
= helpers
.from_xs_boolean_to_python_boolean(
3089 bookmark
['autojoin'])
3091 minimize
= helpers
.from_xs_boolean_to_python_boolean(
3092 bookmark
['minimize'])
3094 print_status
= bookmark
.get('print_status', '')
3095 if print_status
not in ('', 'all', 'in_and_out', 'none'):
3097 self
.treestore
.append(iter_
, [
3103 bookmark
['password'],
3107 self
.print_status_combobox
= self
.xml
.get_object('print_status_combobox')
3108 model
= gtk
.ListStore(str, str)
3110 self
.option_list
= {'': _('Default'), 'all': Q_('?print_status:All'),
3111 'in_and_out': _('Enter and leave only'),
3112 'none': Q_('?print_status:None')}
3113 opts
= sorted(self
.option_list
.keys())
3115 model
.append([self
.option_list
[opt
], opt
])
3117 self
.print_status_combobox
.set_model(model
)
3118 self
.print_status_combobox
.set_active(1)
3120 self
.view
= self
.xml
.get_object('bookmarks_treeview')
3121 self
.view
.set_model(self
.treestore
)
3122 self
.view
.expand_all()
3124 renderer
= gtk
.CellRendererText()
3125 column
= gtk
.TreeViewColumn('Bookmarks', renderer
, text
=1)
3126 self
.view
.append_column(column
)
3128 self
.selection
= self
.view
.get_selection()
3129 self
.selection
.connect('changed', self
.bookmark_selected
)
3131 #Prepare input fields
3132 self
.title_entry
= self
.xml
.get_object('title_entry')
3133 self
.title_entry
.connect('changed', self
.on_title_entry_changed
)
3134 self
.nick_entry
= self
.xml
.get_object('nick_entry')
3135 self
.nick_entry
.connect('changed', self
.on_nick_entry_changed
)
3136 self
.server_entry
= self
.xml
.get_object('server_entry')
3137 self
.server_entry
.connect('changed', self
.on_server_entry_changed
)
3138 self
.room_entry
= self
.xml
.get_object('room_entry')
3139 self
.room_entry
.connect('changed', self
.on_room_entry_changed
)
3140 self
.pass_entry
= self
.xml
.get_object('pass_entry')
3141 self
.pass_entry
.connect('changed', self
.on_pass_entry_changed
)
3142 self
.autojoin_checkbutton
= self
.xml
.get_object('autojoin_checkbutton')
3143 self
.minimize_checkbutton
= self
.xml
.get_object('minimize_checkbutton')
3145 self
.xml
.connect_signals(self
)
3146 self
.window
.show_all()
3148 self
.selection
.select_iter(self
.treestore
.get_iter_root())
3150 def on_bookmarks_treeview_button_press_event(self
, widget
, event
):
3151 (model
, iter_
) = self
.selection
.get_selected()
3153 # Removed a bookmark before
3156 if model
.iter_parent(iter_
):
3157 # The currently selected node is a bookmark
3158 return not self
.check_valid_bookmark()
3160 def on_manage_bookmarks_window_destroy(self
, widget
, event
):
3161 del gajim
.interface
.instances
['manage_bookmarks']
3163 def on_add_bookmark_button_clicked(self
, widget
):
3167 # Get the account that is currently used
3168 # (the parent of the currently selected item)
3169 (model
, iter_
) = self
.selection
.get_selected()
3170 if not iter_
: # Nothing selected, do nothing
3173 parent
= model
.iter_parent(iter_
)
3176 # We got a bookmark selected, so we add_to the parent
3179 # No parent, so we got an account -> add to this.
3182 account
= model
[add_to
][1].decode('utf-8')
3183 nick
= gajim
.nicks
[account
]
3184 iter_
= self
.treestore
.append(add_to
, [account
, _('New Group Chat'),
3185 '@', False, False, '', nick
, 'in_and_out'])
3187 self
.view
.expand_row(model
.get_path(add_to
), True)
3188 self
.view
.set_cursor(model
.get_path(iter_
))
3190 def on_remove_bookmark_button_clicked(self
, widget
):
3192 Remove selected bookmark
3194 (model
, iter_
) = self
.selection
.get_selected()
3195 if not iter_
: # Nothing selected
3198 if not model
.iter_parent(iter_
):
3199 # Don't remove account iters
3205 def check_valid_bookmark(self
):
3207 Check if all neccessary fields are entered correctly
3209 (model
, iter_
) = self
.selection
.get_selected()
3211 if not model
.iter_parent(iter_
):
3212 #Account data can't be changed
3215 if self
.server_entry
.get_text().decode('utf-8') == '' or \
3216 self
.room_entry
.get_text().decode('utf-8') == '':
3217 dialogs
.ErrorDialog(_('This bookmark has invalid data'),
3218 _('Please be sure to fill out server and room fields or remove this'
3224 def on_ok_button_clicked(self
, widget
):
3226 Parse the treestore data into our new bookmarks array, then send the new
3227 bookmarks to the server.
3229 (model
, iter_
) = self
.selection
.get_selected()
3230 if iter_
and model
.iter_parent(iter_
):
3231 #bookmark selected, check it
3232 if not self
.check_valid_bookmark():
3235 for account
in self
.treestore
:
3236 account_unicode
= account
[1].decode('utf-8')
3237 gajim
.connections
[account_unicode
].bookmarks
= []
3239 for bm
in account
.iterchildren():
3240 # Convert True/False/None to '1' or '0'
3241 autojoin
= unicode(int(bm
[3]))
3242 minimize
= unicode(int(bm
[4]))
3245 name
= name
.decode('utf-8')
3248 jid
= jid
.decode('utf-8')
3251 pw
= pw
.decode('utf-8')
3254 nick
= nick
.decode('utf-8')
3256 # create the bookmark-dict
3257 bmdict
= { 'name': name
, 'jid': jid
, 'autojoin': autojoin
,
3258 'minimize': minimize
, 'password': pw
, 'nick': nick
,
3259 'print_status': bm
[7]}
3261 gajim
.connections
[account_unicode
].bookmarks
.append(bmdict
)
3263 gajim
.connections
[account_unicode
].store_bookmarks()
3264 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3265 self
.window
.destroy()
3267 def on_cancel_button_clicked(self
, widget
):
3268 self
.window
.destroy()
3270 def bookmark_selected(self
, selection
):
3272 Fill in the bookmark's data into the fields.
3274 (model
, iter_
) = selection
.get_selected()
3277 # After removing the last bookmark for one account
3278 # this will be None, so we will just:
3281 widgets
= [ self
.title_entry
, self
.nick_entry
, self
.room_entry
,
3282 self
.server_entry
, self
.pass_entry
, self
.autojoin_checkbutton
,
3283 self
.minimize_checkbutton
, self
.print_status_combobox
]
3285 if model
.iter_parent(iter_
):
3286 # make the fields sensitive
3287 for field
in widgets
:
3288 field
.set_sensitive(True)
3290 # Top-level has no data (it's the account fields)
3291 # clear fields & make them insensitive
3293 for field
in widgets
:
3294 field
.set_sensitive(False)
3297 # Fill in the data for childs
3298 self
.title_entry
.set_text(model
[iter_
][1])
3299 room_jid
= model
[iter_
][2].decode('utf-8')
3300 (room
, server
) = room_jid
.split('@')
3301 self
.room_entry
.set_text(room
)
3302 self
.server_entry
.set_text(server
)
3304 self
.autojoin_checkbutton
.set_active(model
[iter_
][3])
3305 self
.minimize_checkbutton
.set_active(model
[iter_
][4])
3306 # sensitive only if auto join is checked
3307 self
.minimize_checkbutton
.set_sensitive(model
[iter_
][3])
3309 if model
[iter_
][5] is not None:
3310 password
= model
[iter_
][5].decode('utf-8')
3315 self
.pass_entry
.set_text(password
)
3317 self
.pass_entry
.set_text('')
3318 nick
= model
[iter_
][6]
3320 nick
= nick
.decode('utf-8')
3321 self
.nick_entry
.set_text(nick
)
3323 self
.nick_entry
.set_text('')
3325 print_status
= model
[iter_
][7]
3326 opts
= sorted(self
.option_list
.keys())
3327 self
.print_status_combobox
.set_active(opts
.index(print_status
))
3329 def on_title_entry_changed(self
, widget
):
3330 (model
, iter_
) = self
.selection
.get_selected()
3331 if iter_
: # After removing a bookmark, we got nothing selected
3332 if model
.iter_parent(iter_
):
3333 # Don't clear the title field for account nodes
3334 model
[iter_
][1] = self
.title_entry
.get_text()
3336 def on_nick_entry_changed(self
, widget
):
3337 (model
, iter_
) = self
.selection
.get_selected()
3339 nick
= self
.nick_entry
.get_text().decode('utf-8')
3341 nick
= helpers
.parse_resource(nick
)
3342 except helpers
.InvalidFormat
, e
:
3343 dialogs
.ErrorDialog(_('Invalid nickname'),
3344 _('Character not allowed'))
3345 self
.nick_entry
.set_text(model
[iter_
][6])
3347 model
[iter_
][6] = nick
3349 def on_server_entry_changed(self
, widget
):
3350 (model
, iter_
) = self
.selection
.get_selected()
3353 server
= widget
.get_text().decode('utf-8')
3355 dialogs
.ErrorDialog(_('Invalid server'), _('Character not allowed'))
3356 widget
.set_text(server
.replace('@', ''))
3358 room_jid
= self
.room_entry
.get_text().decode('utf-8').strip() + '@' + \
3361 room_jid
= helpers
.parse_resource(room_jid
)
3362 except helpers
.InvalidFormat
, e
:
3363 dialogs
.ErrorDialog(_('Invalid server'),
3364 _('Character not allowed'))
3365 self
.server_entry
.set_text(model
[iter_
][2].split('@')[1])
3367 model
[iter_
][2] = room_jid
3369 def on_room_entry_changed(self
, widget
):
3370 (model
, iter_
) = self
.selection
.get_selected()
3373 room
= widget
.get_text().decode('utf-8')
3375 dialogs
.ErrorDialog(_('Invalid server'), _('Character not allowed'))
3376 widget
.set_text(room
.replace('@', ''))
3377 room_jid
= room
.strip() + '@' + \
3378 self
.server_entry
.get_text().decode('utf-8').strip()
3380 room_jid
= helpers
.parse_resource(room_jid
)
3381 except helpers
.InvalidFormat
, e
:
3382 dialogs
.ErrorDialog(_('Invalid room'),
3383 _('Character not allowed'))
3384 self
.room_entry
.set_text(model
[iter_
][2].split('@')[0])
3386 model
[iter_
][2] = room_jid
3388 def on_pass_entry_changed(self
, widget
):
3389 (model
, iter_
) = self
.selection
.get_selected()
3391 model
[iter_
][5] = self
.pass_entry
.get_text()
3393 def on_autojoin_checkbutton_toggled(self
, widget
):
3394 (model
, iter_
) = self
.selection
.get_selected()
3396 model
[iter_
][3] = self
.autojoin_checkbutton
.get_active()
3397 self
.minimize_checkbutton
.set_sensitive(model
[iter_
][3])
3399 def on_minimize_checkbutton_toggled(self
, widget
):
3400 (model
, iter_
) = self
.selection
.get_selected()
3402 model
[iter_
][4] = self
.minimize_checkbutton
.get_active()
3404 def on_print_status_combobox_changed(self
, widget
):
3405 active
= widget
.get_active()
3406 model
= widget
.get_model()
3407 print_status
= model
[active
][1]
3408 (model2
, iter_
) = self
.selection
.get_selected()
3410 model2
[iter_
][7] = print_status
3412 def clear_fields(self
):
3413 widgets
= [ self
.title_entry
, self
.nick_entry
, self
.room_entry
,
3414 self
.server_entry
, self
.pass_entry
]
3415 for field
in widgets
:
3417 self
.autojoin_checkbutton
.set_active(False)
3418 self
.minimize_checkbutton
.set_active(False)
3419 self
.print_status_combobox
.set_active(1)
3421 class AccountCreationWizardWindow
:
3423 self
.xml
= gtkgui_helpers
.get_gtk_builder(
3424 'account_creation_wizard_window.ui')
3425 self
.window
= self
.xml
.get_object('account_creation_wizard_window')
3426 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3428 completion
= gtk
.EntryCompletion()
3429 completion1
= gtk
.EntryCompletion()
3430 # Connect events from comboboxentry.child
3431 server_comboboxentry
= self
.xml
.get_object('server_comboboxentry')
3432 entry
= server_comboboxentry
.child
3433 entry
.connect('key_press_event',
3434 self
.on_server_comboboxentry_key_press_event
, server_comboboxentry
)
3435 entry
.set_completion(completion
)
3436 # Do the same for the other server comboboxentry
3437 server_comboboxentry1
= self
.xml
.get_object('server_comboboxentry1')
3438 entry
= server_comboboxentry1
.child
3439 entry
.set_completion(completion1
)
3441 self
.update_proxy_list()
3444 servers_xml
= os
.path
.join(gajim
.DATA_DIR
, 'other', 'servers.xml')
3445 servers
= gtkgui_helpers
.parse_server_xml(servers_xml
)
3446 servers_model
= gtk
.ListStore(str)
3447 for server
in servers
:
3448 servers_model
.append((server
,))
3450 completion
.set_model(servers_model
)
3451 completion
.set_text_column(0)
3452 completion1
.set_model(servers_model
)
3453 completion1
.set_text_column(0)
3455 # Put servers into comboboxentries
3456 server_comboboxentry
.set_model(servers_model
)
3457 server_comboboxentry
.set_text_column(0)
3458 server_comboboxentry1
.set_model(servers_model
)
3459 server_comboboxentry1
.set_text_column(0)
3462 self
.notebook
= self
.xml
.get_object('notebook')
3463 self
.cancel_button
= self
.xml
.get_object('cancel_button')
3464 self
.back_button
= self
.xml
.get_object('back_button')
3465 self
.forward_button
= self
.xml
.get_object('forward_button')
3466 self
.finish_button
= self
.xml
.get_object('finish_button')
3467 self
.advanced_button
= self
.xml
.get_object('advanced_button')
3468 self
.finish_label
= self
.xml
.get_object('finish_label')
3469 self
.go_online_checkbutton
= self
.xml
.get_object(
3470 'go_online_checkbutton')
3471 self
.show_vcard_checkbutton
= self
.xml
.get_object(
3472 'show_vcard_checkbutton')
3473 self
.progressbar
= self
.xml
.get_object('progressbar')
3476 self
.update_progressbar_timeout_id
= None
3478 self
.notebook
.set_current_page(0)
3479 self
.xml
.connect_signals(self
)
3480 self
.window
.show_all()
3481 gajim
.ged
.register_event_handler('new-account-connected', ged
.GUI1
,
3482 self
._nec
_new
_acc
_connected
)
3483 gajim
.ged
.register_event_handler('new-account-not-connected', ged
.GUI1
,
3484 self
._nec
_new
_acc
_not
_connected
)
3485 gajim
.ged
.register_event_handler('account-created', ged
.GUI1
,
3486 self
._nec
_acc
_is
_ok
)
3487 gajim
.ged
.register_event_handler('account-not-created', ged
.GUI1
,
3488 self
._nec
_acc
_is
_not
_ok
)
3490 def on_wizard_window_destroy(self
, widget
):
3491 page
= self
.notebook
.get_current_page()
3492 if page
in (4, 5) and self
.account
in gajim
.connections
:
3493 # connection instance is saved in gajim.connections and we canceled
3494 # the addition of the account
3495 del gajim
.connections
[self
.account
]
3496 if self
.account
in gajim
.config
.get_per('accounts'):
3497 gajim
.config
.del_per('accounts', self
.account
)
3498 gajim
.ged
.remove_event_handler('new-account-connected', ged
.GUI1
,
3499 self
._nec
_new
_acc
_connected
)
3500 gajim
.ged
.remove_event_handler('new-account-not-connected', ged
.GUI1
,
3501 self
._nec
_new
_acc
_not
_connected
)
3502 gajim
.ged
.remove_event_handler('account-created', ged
.GUI1
,
3503 self
._nec
_acc
_is
_ok
)
3504 gajim
.ged
.remove_event_handler('account-not-created', ged
.GUI1
,
3505 self
._nec
_acc
_is
_not
_ok
)
3506 del gajim
.interface
.instances
['account_creation_wizard']
3508 def on_register_server_features_button_clicked(self
, widget
):
3509 helpers
.launch_browser_mailer('url',
3510 'http://www.jabber.org/network/oldnetwork.shtml')
3512 def on_save_password_checkbutton_toggled(self
, widget
):
3513 self
.xml
.get_object('password_entry').grab_focus()
3515 def on_cancel_button_clicked(self
, widget
):
3516 self
.window
.destroy()
3518 def on_back_button_clicked(self
, widget
):
3519 cur_page
= self
.notebook
.get_current_page()
3520 if cur_page
in (1, 2):
3521 self
.notebook
.set_current_page(0)
3522 self
.back_button
.set_sensitive(False)
3524 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3525 self
.notebook
.set_current_page(2) # show server page
3527 if self
.account
in gajim
.connections
:
3528 del gajim
.connections
[self
.account
]
3529 self
.notebook
.set_current_page(2)
3530 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3531 elif cur_page
== 6: # finish page
3532 self
.forward_button
.show()
3534 self
.notebook
.set_current_page(1) # Go to parameters page
3536 self
.notebook
.set_current_page(2) # Go to server page
3538 def on_anonymous_checkbutton1_toggled(self
, widget
):
3539 active
= widget
.get_active()
3540 self
.xml
.get_object('username_entry').set_sensitive(not active
)
3541 self
.xml
.get_object('password_entry').set_sensitive(not active
)
3542 self
.xml
.get_object('save_password_checkbutton').set_sensitive(
3545 def show_finish_page(self
):
3546 self
.cancel_button
.hide()
3547 self
.back_button
.hide()
3548 self
.forward_button
.hide()
3550 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3551 _('Account has been added successfully'),
3552 _('You can set advanced account options by pressing the '
3553 'Advanced button, or later by choosing the Accounts menu item '
3554 'under the Edit menu from the main window.'))
3556 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3557 _('Your new account has been created successfully'),
3558 _('You can set advanced account options by pressing the '
3559 'Advanced button, or later by choosing the Accounts menu item '
3560 'under the Edit menu from the main window.'))
3561 self
.finish_label
.set_markup(finish_text
)
3562 self
.finish_button
.show()
3563 self
.finish_button
.set_property('has-default', True)
3564 self
.advanced_button
.show()
3565 self
.go_online_checkbutton
.show()
3566 img
= self
.xml
.get_object('finish_image')
3568 img
.set_from_stock(gtk
.STOCK_APPLY
, gtk
.ICON_SIZE_DIALOG
)
3570 path_to_file
= gtkgui_helpers
.get_icon_path('gajim', 48)
3571 img
.set_from_file(path_to_file
)
3572 self
.show_vcard_checkbutton
.set_active(not self
.modify
)
3573 self
.notebook
.set_current_page(6) # show finish page
3575 def on_forward_button_clicked(self
, widget
):
3576 cur_page
= self
.notebook
.get_current_page()
3579 widget
= self
.xml
.get_object('use_existing_account_radiobutton')
3580 if widget
.get_active():
3582 self
.notebook
.set_current_page(1)
3585 self
.notebook
.set_current_page(2)
3586 self
.back_button
.set_sensitive(True)
3590 # We are adding an existing account
3591 anonymous
= self
.xml
.get_object('anonymous_checkbutton1').\
3593 username
= self
.xml
.get_object('username_entry').get_text().decode(
3595 if not username
and not anonymous
:
3596 pritext
= _('Invalid username')
3598 'You must provide a username to configure this account.')
3599 dialogs
.ErrorDialog(pritext
, sectext
)
3601 server
= self
.xml
.get_object('server_comboboxentry').child
.\
3602 get_text().decode('utf-8').strip()
3603 savepass
= self
.xml
.get_object('save_password_checkbutton').\
3605 password
= self
.xml
.get_object('password_entry').get_text().decode(
3608 jid
= username
+ '@' + server
3609 # check if jid is conform to RFC and stringprep it
3611 jid
= helpers
.parse_jid(jid
)
3612 except helpers
.InvalidFormat
, s
:
3613 pritext
= _('Invalid Jabber ID')
3614 dialogs
.ErrorDialog(pritext
, str(s
))
3617 self
.account
= server
3619 while self
.account
in gajim
.connections
:
3620 self
.account
= server
+ str(i
)
3623 username
, server
= gajim
.get_name_and_server_from_jid(jid
)
3624 if self
.xml
.get_object('anonymous_checkbutton1').get_active():
3625 self
.save_account('', server
, False, '', anonymous
=True)
3627 self
.save_account(username
, server
, savepass
, password
)
3628 self
.show_finish_page()
3630 # We are creating a new account
3631 server
= self
.xml
.get_object('server_comboboxentry1').child
.\
3632 get_text().decode('utf-8')
3635 dialogs
.ErrorDialog(_('Invalid server'),
3636 _('Please provide a server on which you want to register.'))
3638 self
.account
= server
3640 while self
.account
in gajim
.connections
:
3641 self
.account
= server
+ str(i
)
3644 config
= self
.get_config('', server
, '', '')
3645 # Get advanced options
3646 proxies_combobox
= self
.xml
.get_object('proxies_combobox')
3647 active
= proxies_combobox
.get_active()
3648 proxy
= proxies_combobox
.get_model()[active
][0].decode('utf-8')
3649 if proxy
== _('None'):
3651 config
['proxy'] = proxy
3653 config
['use_custom_host'] = self
.xml
.get_object(
3654 'custom_host_port_checkbutton').get_active()
3655 custom_port
= self
.xml
.get_object('custom_port_entry').get_text()
3657 custom_port
= int(custom_port
)
3659 dialogs
.ErrorDialog(_('Invalid entry'),
3660 _('Custom port must be a port number.'))
3662 config
['custom_port'] = custom_port
3663 config
['custom_host'] = self
.xml
.get_object(
3664 'custom_host_entry').get_text().decode('utf-8')
3666 if self
.xml
.get_object('anonymous_checkbutton2').get_active():
3668 self
.save_account('', server
, False, '', anonymous
=True)
3669 self
.show_finish_page()
3671 self
.notebook
.set_current_page(5) # show creating page
3672 self
.back_button
.hide()
3673 self
.forward_button
.hide()
3674 self
.update_progressbar_timeout_id
= gobject
.timeout_add(100,
3675 self
.update_progressbar
)
3676 # Get form from serveur
3677 con
= connection
.Connection(self
.account
)
3678 gajim
.connections
[self
.account
] = con
3679 con
.new_account(self
.account
, config
)
3681 checked
= self
.xml
.get_object('ssl_checkbutton').get_active()
3683 hostname
= gajim
.connections
[self
.account
].new_account_info
[
3685 # Check if cert is already in file
3687 if os
.path
.isfile(gajim
.MY_CACERTS
):
3688 f
= open(gajim
.MY_CACERTS
)
3691 if self
.ssl_cert
in certs
:
3692 dialogs
.ErrorDialog(_('Certificate Already in File'),
3693 _('This certificate is already in file %s, so it\'s '
3694 'not added again.') % gajim
.MY_CACERTS
)
3696 f
= open(gajim
.MY_CACERTS
, 'a')
3697 f
.write(hostname
+ '\n')
3698 f
.write(self
.ssl_cert
+ '\n\n')
3700 gajim
.connections
[self
.account
].new_account_info
[
3701 'ssl_fingerprint_sha1'] = self
.ssl_fingerprint
3702 self
.notebook
.set_current_page(4) # show fom page
3705 form
= self
.data_form_widget
.data_form
3707 form
= self
.data_form_widget
.get_infos()
3708 gajim
.connections
[self
.account
].send_new_account_infos(form
,
3710 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3711 self
.xml
.get_object('progressbar_label').set_markup(
3712 '<b>Account is being created</b>\n\nPlease wait...')
3713 self
.notebook
.set_current_page(5) # show creating page
3714 self
.back_button
.hide()
3715 self
.forward_button
.hide()
3716 self
.update_progressbar_timeout_id
= gobject
.timeout_add(100,
3717 self
.update_progressbar
)
3719 def update_proxy_list(self
):
3720 proxies_combobox
= self
.xml
.get_object('proxies_combobox')
3721 model
= gtk
.ListStore(str)
3722 proxies_combobox
.set_model(model
)
3723 l
= gajim
.config
.get_per('proxies')
3724 l
.insert(0, _('None'))
3725 for i
in xrange(len(l
)):
3726 model
.append([l
[i
]])
3727 proxies_combobox
.set_active(0)
3729 def on_manage_proxies_button_clicked(self
, widget
):
3730 if 'manage_proxies' in gajim
.interface
.instances
:
3731 gajim
.interface
.instances
['manage_proxies'].window
.present()
3733 gajim
.interface
.instances
['manage_proxies'] = \
3734 ManageProxiesWindow()
3736 def on_custom_host_port_checkbutton_toggled(self
, widget
):
3737 self
.xml
.get_object('custom_host_hbox').set_sensitive(widget
.\
3740 def update_progressbar(self
):
3741 self
.progressbar
.pulse()
3742 return True # loop forever
3744 def _nec_new_acc_connected(self
, obj
):
3746 Connection to server succeded, present the form to the user
3748 # We receive events from all accounts from GED
3749 if obj
.conn
.name
!= self
.account
:
3751 if self
.update_progressbar_timeout_id
is not None:
3752 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3753 self
.back_button
.show()
3754 self
.forward_button
.show()
3755 self
.is_form
= obj
.is_form
3757 dataform
= dataforms
.ExtendForm(node
=obj
.config
)
3758 self
.data_form_widget
= dataforms_widget
.DataFormWidget(dataform
)
3760 self
.data_form_widget
= FakeDataForm(obj
.config
)
3761 self
.data_form_widget
.show_all()
3762 self
.xml
.get_object('form_vbox').pack_start(self
.data_form_widget
)
3763 self
.ssl_fingerprint
= obj
.ssl_fingerprint
3764 self
.ssl_cert
= obj
.ssl_cert
3766 # An SSL warning occured, show it
3767 hostname
= gajim
.connections
[self
.account
].new_account_info
[
3769 self
.xml
.get_object('ssl_label').set_markup(_(
3770 '<b>Security Warning</b>'
3771 '\n\nThe authenticity of the %(hostname)s SSL certificate could'
3772 ' be invalid.\nSSL Error: %(error)s\n'
3773 'Do you still want to connect to this server?') % {
3774 'hostname': hostname
, 'error': obj
.ssl_msg
})
3775 if obj
.errnum
in (18, 27):
3776 text
= _('Add this certificate to the list of trusted '
3777 'certificates.\nSHA1 fingerprint of the certificate:\n%s') \
3778 % obj
.ssl_fingerprint
3779 self
.xml
.get_object('ssl_checkbutton').set_label(text
)
3781 self
.xml
.get_object('ssl_checkbutton').set_no_show_all(True)
3782 self
.xml
.get_object('ssl_checkbutton').hide()
3783 self
.notebook
.set_current_page(3) # show SSL page
3785 self
.notebook
.set_current_page(4) # show form page
3787 def _nec_new_acc_not_connected(self
, obj
):
3789 Account creation failed: connection to server failed
3791 # We receive events from all accounts from GED
3792 if obj
.conn
.name
!= self
.account
:
3794 if self
.account
not in gajim
.connections
:
3796 if self
.update_progressbar_timeout_id
is not None:
3797 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3798 del gajim
.connections
[self
.account
]
3799 if self
.account
in gajim
.config
.get_per('accounts'):
3800 gajim
.config
.del_per('accounts', self
.account
)
3801 self
.back_button
.show()
3802 self
.cancel_button
.show()
3803 self
.go_online_checkbutton
.hide()
3804 self
.show_vcard_checkbutton
.hide()
3805 img
= self
.xml
.get_object('finish_image')
3806 img
.set_from_stock(gtk
.STOCK_DIALOG_ERROR
, gtk
.ICON_SIZE_DIALOG
)
3807 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3808 _('An error occurred during account creation'), obj
.reason
)
3809 self
.finish_label
.set_markup(finish_text
)
3810 self
.notebook
.set_current_page(6) # show finish page
3812 def _nec_acc_is_ok(self
, obj
):
3814 Account creation succeeded
3816 # We receive events from all accounts from GED
3817 if obj
.conn
.name
!= self
.account
:
3819 self
.create_vars(obj
.account_info
)
3820 self
.show_finish_page()
3822 if self
.update_progressbar_timeout_id
is not None:
3823 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3825 def _nec_acc_is_not_ok(self
, obj
):
3827 Account creation failed
3829 # We receive events from all accounts from GED
3830 if obj
.conn
.name
!= self
.account
:
3832 self
.back_button
.show()
3833 self
.cancel_button
.show()
3834 self
.go_online_checkbutton
.hide()
3835 self
.show_vcard_checkbutton
.hide()
3836 del gajim
.connections
[self
.account
]
3837 if self
.account
in gajim
.config
.get_per('accounts'):
3838 gajim
.config
.del_per('accounts', self
.account
)
3839 img
= self
.xml
.get_object('finish_image')
3840 img
.set_from_stock(gtk
.STOCK_DIALOG_ERROR
, gtk
.ICON_SIZE_DIALOG
)
3841 finish_text
= '<big><b>%s</b></big>\n\n%s' % (_(
3842 'An error occurred during account creation'), obj
.reason
)
3843 self
.finish_label
.set_markup(finish_text
)
3844 self
.notebook
.set_current_page(6) # show finish page
3846 if self
.update_progressbar_timeout_id
is not None:
3847 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3849 def on_advanced_button_clicked(self
, widget
):
3850 if 'accounts' in gajim
.interface
.instances
:
3851 gajim
.interface
.instances
['accounts'].window
.present()
3853 gajim
.interface
.instances
['accounts'] = AccountsWindow()
3854 gajim
.interface
.instances
['accounts'].select_account(self
.account
)
3855 self
.window
.destroy()
3857 def on_finish_button_clicked(self
, widget
):
3858 go_online
= self
.xml
.get_object('go_online_checkbutton').get_active()
3859 show_vcard
= self
.xml
.get_object('show_vcard_checkbutton').get_active()
3860 self
.window
.destroy()
3862 gajim
.interface
.show_vcard_when_connect
.append(self
.account
)
3864 gajim
.interface
.roster
.send_status(self
.account
, 'online', '')
3866 def on_username_entry_key_press_event(self
, widget
, event
):
3867 # Check for pressed @ and jump to combobox if found
3868 if event
.keyval
== gtk
.keysyms
.at
:
3869 combobox
= self
.xml
.get_object('server_comboboxentry')
3870 combobox
.grab_focus()
3871 combobox
.child
.set_position(-1)
3874 def on_server_comboboxentry_key_press_event(self
, widget
, event
, combobox
):
3875 # If backspace is pressed in empty field, return to the nick entry field
3876 backspace
= event
.keyval
== gtk
.keysyms
.BackSpace
3877 empty
= len(combobox
.get_active_text()) == 0
3878 if backspace
and empty
and self
.modify
:
3879 username_entry
= self
.xml
.get_object('username_entry')
3880 username_entry
.grab_focus()
3881 username_entry
.set_position(-1)
3884 def get_config(self
, login
, server
, savepass
, password
, anonymous
=False):
3886 config
['name'] = login
3887 config
['hostname'] = server
3888 config
['savepass'] = savepass
3889 config
['password'] = password
3890 config
['resource'] = 'Gajim'
3891 config
['anonymous_auth'] = anonymous
3892 config
['priority'] = 5
3893 config
['autoconnect'] = True
3894 config
['no_log_for'] = ''
3895 config
['sync_with_global_status'] = True
3896 config
['proxy'] = ''
3897 config
['usessl'] = False
3898 config
['use_custom_host'] = False
3899 config
['custom_port'] = 0
3900 config
['custom_host'] = ''
3901 config
['keyname'] = ''
3902 config
['keyid'] = ''
3905 def save_account(self
, login
, server
, savepass
, password
, anonymous
=False):
3906 if self
.account
in gajim
.connections
:
3907 dialogs
.ErrorDialog(_('Account name is in use'),
3908 _('You already have an account using this name.'))
3910 con
= connection
.Connection(self
.account
)
3911 con
.password
= password
3913 config
= self
.get_config(login
, server
, savepass
, password
, anonymous
)
3916 con
.new_account(self
.account
, config
)
3918 gajim
.connections
[self
.account
] = con
3919 self
.create_vars(config
)
3921 def create_vars(self
, config
):
3922 gajim
.config
.add_per('accounts', self
.account
)
3924 if not config
['savepass']:
3925 config
['password'] = ''
3928 gajim
.config
.set_per('accounts', self
.account
, opt
, config
[opt
])
3931 gajim
.interface
.instances
[self
.account
] = {'infos': {}, 'disco': {},
3932 'gc_config': {}, 'search': {}, 'online_dialog': {}}
3933 gajim
.interface
.minimized_controls
[self
.account
] = {}
3934 gajim
.connections
[self
.account
].connected
= 0
3935 gajim
.connections
[self
.account
].keepalives
= gajim
.config
.get_per(
3936 'accounts', self
.account
, 'keep_alive_every_foo_secs')
3937 gajim
.groups
[self
.account
] = {}
3938 gajim
.contacts
.add_account(self
.account
)
3939 gajim
.gc_connected
[self
.account
] = {}
3940 gajim
.automatic_rooms
[self
.account
] = {}
3941 gajim
.newly_added
[self
.account
] = []
3942 gajim
.to_be_removed
[self
.account
] = []
3943 gajim
.nicks
[self
.account
] = config
['name']
3944 gajim
.block_signed_in_notifications
[self
.account
] = True
3945 gajim
.sleeper_state
[self
.account
] = 'off'
3946 gajim
.encrypted_chats
[self
.account
] = []
3947 gajim
.last_message_time
[self
.account
] = {}
3948 gajim
.status_before_autoaway
[self
.account
] = ''
3949 gajim
.transport_avatar
[self
.account
] = {}
3950 gajim
.gajim_optional_features
[self
.account
] = []
3951 gajim
.caps_hash
[self
.account
] = ''
3952 # refresh accounts window
3953 if 'accounts' in gajim
.interface
.instances
:
3954 gajim
.interface
.instances
['accounts'].init_accounts()
3956 if len(gajim
.connections
) >= 2:
3957 # Do not merge accounts if only one exists
3958 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
3960 gajim
.interface
.roster
.regroup
= False
3961 gajim
.interface
.roster
.setup_and_draw_roster()
3962 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3963 gajim
.interface
.save_config()
3965 class ManagePEPServicesWindow
:
3966 def __init__(self
, account
):
3967 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_pep_services_window.ui')
3968 self
.window
= self
.xml
.get_object('manage_pep_services_window')
3969 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3970 self
.xml
.get_object('configure_button').set_sensitive(False)
3971 self
.xml
.get_object('delete_button').set_sensitive(False)
3972 self
.xml
.connect_signals(self
)
3973 self
.account
= account
3975 self
.init_services()
3976 self
.xml
.get_object('services_treeview').get_selection().connect(
3977 'changed', self
.on_services_selection_changed
)
3979 gajim
.ged
.register_event_handler('pep-config-received', ged
.GUI1
,
3980 self
._nec
_pep
_config
_received
)
3981 gajim
.ged
.register_event_handler('agent-items-received', ged
.GUI1
,
3982 self
._nec
_agent
_items
_received
)
3984 self
.window
.show_all()
3986 def on_manage_pep_services_window_destroy(self
, widget
):
3988 del gajim
.interface
.instances
[self
.account
]['pep_services']
3989 gajim
.ged
.remove_event_handler('pep-config-received', ged
.GUI1
,
3990 self
._nec
_pep
_config
_received
)
3991 gajim
.ged
.remove_event_handler('agent-items-received', ged
.GUI1
,
3992 self
._nec
_agent
_items
_received
)
3994 def on_close_button_clicked(self
, widget
):
3995 self
.window
.destroy()
3997 def on_services_selection_changed(self
, sel
):
3998 self
.xml
.get_object('configure_button').set_sensitive(True)
3999 self
.xml
.get_object('delete_button').set_sensitive(True)
4001 def init_services(self
):
4002 self
.treeview
= self
.xml
.get_object('services_treeview')
4003 # service, access_model, group
4004 self
.treestore
= gtk
.ListStore(str)
4005 self
.treeview
.set_model(self
.treestore
)
4007 col
= gtk
.TreeViewColumn('Service')
4008 self
.treeview
.append_column(col
)
4010 cellrenderer_text
= gtk
.CellRendererText()
4011 col
.pack_start(cellrenderer_text
)
4012 col
.add_attribute(cellrenderer_text
, 'text', 0)
4014 our_jid
= gajim
.get_jid_from_account(self
.account
)
4015 gajim
.connections
[self
.account
].discoverItems(our_jid
)
4017 def _nec_agent_items_received(self
, obj
):
4018 our_jid
= gajim
.get_jid_from_account(self
.account
)
4019 for item
in obj
.items
:
4020 if 'jid' in item
and item
['jid'] == our_jid
and 'node' in item
:
4021 self
.treestore
.append([item
['node']])
4023 def node_removed(self
, jid
, node
):
4024 if jid
!= gajim
.get_jid_from_account(self
.account
):
4026 model
= self
.treeview
.get_model()
4027 iter_
= model
.get_iter_root()
4029 if model
[iter_
][0] == node
:
4032 iter_
= model
.iter_next(iter_
)
4034 def node_not_removed(self
, jid
, node
, msg
):
4035 if jid
!= gajim
.get_jid_from_account(self
.account
):
4037 dialogs
.WarningDialog(_('PEP node was not removed'),
4038 _('PEP node %(node)s was not removed: %(message)s') % {'node': node
,
4041 def on_delete_button_clicked(self
, widget
):
4042 selection
= self
.treeview
.get_selection()
4045 model
, iter_
= selection
.get_selected()
4046 node
= model
[iter_
][0]
4047 our_jid
= gajim
.get_jid_from_account(self
.account
)
4048 gajim
.connections
[self
.account
].send_pb_delete(our_jid
, node
,
4049 on_ok
=self
.node_removed
, on_fail
=self
.node_not_removed
)
4051 def on_configure_button_clicked(self
, widget
):
4052 selection
= self
.treeview
.get_selection()
4055 model
, iter_
= selection
.get_selected()
4056 node
= model
[iter_
][0]
4057 our_jid
= gajim
.get_jid_from_account(self
.account
)
4058 gajim
.connections
[self
.account
].request_pb_configuration(our_jid
, node
)
4060 def _nec_pep_config_received(self
, obj
):
4061 def on_ok(form
, node
):
4062 form
.type = 'submit'
4063 our_jid
= gajim
.get_jid_from_account(self
.account
)
4064 gajim
.connections
[self
.account
].send_pb_configure(our_jid
, node
, form
)
4065 window
= dialogs
.DataFormWindow(obj
.form
, (on_ok
, obj
.node
))
4066 title
= _('Configure %s') % obj
.node
4067 window
.set_title(title
)
4070 class ManageSoundsWindow
:
4072 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_sounds_window.ui')
4073 self
.window
= self
.xml
.get_object('manage_sounds_window')
4076 self
.sound_tree
= self
.xml
.get_object('sounds_treeview')
4078 # active, event ui name, path to sound file, event_config_name
4079 model
= gtk
.ListStore(bool, str, str, str)
4080 self
.sound_tree
.set_model(model
)
4082 col
= gtk
.TreeViewColumn(_('Active'))
4083 self
.sound_tree
.append_column(col
)
4084 renderer
= gtk
.CellRendererToggle()
4085 renderer
.set_property('activatable', True)
4086 renderer
.connect('toggled', self
.sound_toggled_cb
)
4087 col
.pack_start(renderer
)
4088 col
.set_attributes(renderer
, active
= 0)
4090 col
= gtk
.TreeViewColumn(_('Event'))
4091 self
.sound_tree
.append_column(col
)
4092 renderer
= gtk
.CellRendererText()
4093 col
.pack_start(renderer
)
4094 col
.set_attributes(renderer
, text
= 1)
4096 self
.fill_sound_treeview()
4098 self
.xml
.connect_signals(self
)
4100 self
.sound_tree
.get_model().connect('row-changed',
4101 self
.on_sounds_treemodel_row_changed
)
4103 self
.window
.show_all()
4105 def on_sounds_treemodel_row_changed(self
, model
, path
, iter_
):
4106 sound_event
= model
[iter_
][3].decode('utf-8')
4107 gajim
.config
.set_per('soundevents', sound_event
, 'enabled',
4108 bool(model
[path
][0]))
4109 gajim
.config
.set_per('soundevents', sound_event
, 'path',
4110 model
[iter_
][2].decode('utf-8'))
4111 gajim
.interface
.save_config()
4113 def sound_toggled_cb(self
, cell
, path
):
4114 model
= self
.sound_tree
.get_model()
4115 model
[path
][0] = not model
[path
][0]
4117 def fill_sound_treeview(self
):
4118 model
= self
.sound_tree
.get_model()
4120 model
.set_sort_column_id(1, gtk
.SORT_ASCENDING
)
4122 # NOTE: sounds_ui_names MUST have all items of
4123 # sounds = gajim.config.get_per('soundevents') as keys
4125 'first_message_received': _('First Message Received'),
4126 'next_message_received_focused': _('Next Message Received Focused'),
4127 'next_message_received_unfocused':
4128 _('Next Message Received Unfocused'),
4129 'contact_connected': _('Contact Connected'),
4130 'contact_disconnected': _('Contact Disconnected'),
4131 'message_sent': _('Message Sent'),
4132 'muc_message_highlight': _('Group Chat Message Highlight'),
4133 'muc_message_received': _('Group Chat Message Received'),
4134 'gmail_received': _('GMail Email Received')
4137 for sound_event_config_name
, sound_ui_name
in sounds_dict
.items():
4138 enabled
= gajim
.config
.get_per('soundevents',
4139 sound_event_config_name
, 'enabled')
4140 path
= gajim
.config
.get_per('soundevents',
4141 sound_event_config_name
, 'path')
4142 model
.append((enabled
, sound_ui_name
, path
, sound_event_config_name
))
4144 def on_treeview_sounds_cursor_changed(self
, widget
, data
= None):
4145 (model
, iter_
) = self
.sound_tree
.get_selection().get_selected()
4146 sounds_entry
= self
.xml
.get_object('sounds_entry')
4148 sounds_entry
.set_text('')
4150 path_to_snd_file
= model
[iter_
][2]
4151 sounds_entry
.set_text(path_to_snd_file
)
4153 def on_browse_for_sounds_button_clicked(self
, widget
, data
= None):
4154 (model
, iter_
) = self
.sound_tree
.get_selection().get_selected()
4157 def on_ok(widget
, path_to_snd_file
):
4158 self
.dialog
.destroy()
4159 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4160 if not path_to_snd_file
:
4161 model
[iter_
][2] = ''
4162 self
.xml
.get_object('sounds_entry').set_text('')
4163 model
[iter_
][0] = False
4165 directory
= os
.path
.dirname(path_to_snd_file
)
4166 gajim
.config
.set('last_sounds_dir', directory
)
4167 path_to_snd_file
= helpers
.strip_soundfile_path(path_to_snd_file
)
4168 self
.xml
.get_object('sounds_entry').set_text(path_to_snd_file
)
4170 model
[iter_
][2] = path_to_snd_file
# set new path to sounds_model
4171 model
[iter_
][0] = True # set the sound to enabled
4173 def on_cancel(widget
):
4174 self
.dialog
.destroy()
4176 path_to_snd_file
= model
[iter_
][2].decode('utf-8')
4177 self
.dialog
= dialogs
.SoundChooserDialog(path_to_snd_file
, on_ok
,
4180 def on_sounds_entry_changed(self
, widget
):
4181 path_to_snd_file
= widget
.get_text()
4182 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4183 model
[iter_
][2] = path_to_snd_file
# set new path to sounds_model
4185 def on_play_button_clicked(self
, widget
):
4186 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4189 snd_event_config_name
= model
[iter_
][3]
4190 helpers
.play_sound(snd_event_config_name
)
4192 def on_close_button_clicked(self
, widget
):
4195 def on_manage_sounds_window_delete_event(self
, widget
, event
):
4197 return True # do NOT destroy the window