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)
508 self
.applications_combobox
.set_active(1)
509 self
.xml
.get_object('custom_apps_frame').show()
511 self
.xml
.get_object('custom_browser_entry').set_text(
512 gajim
.config
.get('custombrowser'))
513 self
.xml
.get_object('custom_mail_client_entry').set_text(
514 gajim
.config
.get('custommailapp'))
515 self
.xml
.get_object('custom_file_manager_entry').set_text(
516 gajim
.config
.get('custom_file_manager'))
518 # log status changes of contacts
519 st
= gajim
.config
.get('log_contact_status_changes')
520 self
.xml
.get_object('log_show_changes_checkbutton').set_active(st
)
522 # log encrypted chat sessions
523 w
= self
.xml
.get_object('log_encrypted_chats_checkbutton')
524 st
= self
.get_per_account_option('log_encrypted_sessions')
526 w
.set_inconsistent(True)
531 w
= self
.xml
.get_object('send_os_info_checkbutton')
532 st
= self
.get_per_account_option('send_os_info')
534 w
.set_inconsistent(True)
539 w
= self
.xml
.get_object('send_idle_time_checkbutton')
540 st
= self
.get_per_account_option('send_idle_time')
542 w
.set_inconsistent(True)
546 # check if gajm is default
547 st
= gajim
.config
.get('check_if_gajim_is_default')
548 self
.xml
.get_object('check_default_client_checkbutton').set_active(st
)
550 # Ignore messages from unknown contacts
551 w
= self
.xml
.get_object('ignore_events_from_unknown_contacts_checkbutton')
552 st
= self
.get_per_account_option('ignore_unknown_contacts')
554 w
.set_inconsistent(True)
558 self
.xml
.connect_signals(self
)
560 self
.msg_tree
.get_model().connect('row-changed',
561 self
.on_msg_treemodel_row_changed
)
562 self
.msg_tree
.get_model().connect('row-deleted',
563 self
.on_msg_treemodel_row_deleted
)
564 self
.default_msg_tree
.get_model().connect('row-changed',
565 self
.on_default_msg_treemodel_row_changed
)
567 self
.theme_preferences
= None
568 self
.sounds_preferences
= None
570 self
.notebook
.set_current_page(0)
572 self
.window
.show_all()
573 gtkgui_helpers
.possibly_move_window_in_current_desktop(self
.window
)
575 def on_preferences_window_key_press_event(self
, widget
, event
):
576 if event
.keyval
== gtk
.keysyms
.Escape
:
579 def get_per_account_option(self
, opt
):
581 Return the value of the option opt if it's the same in all accounts else
584 if len(gajim
.connections
) == 0:
585 # a non existant key return default value
586 return gajim
.config
.get_per('accounts', '__default__', opt
)
588 for account
in gajim
.connections
:
589 v
= gajim
.config
.get_per('accounts', account
, opt
)
596 def on_checkbutton_toggled(self
, widget
, config_name
,
597 change_sensitivity_widgets
=None):
598 gajim
.config
.set(config_name
, widget
.get_active())
599 if change_sensitivity_widgets
:
600 for w
in change_sensitivity_widgets
:
601 w
.set_sensitive(widget
.get_active())
602 gajim
.interface
.save_config()
604 def on_per_account_checkbutton_toggled(self
, widget
, config_name
,
605 change_sensitivity_widgets
=None):
606 for account
in gajim
.connections
:
607 gajim
.config
.set_per('accounts', account
, config_name
,
609 if change_sensitivity_widgets
:
610 for w
in change_sensitivity_widgets
:
611 w
.set_sensitive(widget
.get_active())
612 gajim
.interface
.save_config()
614 def _get_all_controls(self
):
615 for ctrl
in gajim
.interface
.msg_win_mgr
.get_controls():
617 for account
in gajim
.connections
:
618 for ctrl
in gajim
.interface
.minimized_controls
[account
].values():
621 def _get_all_muc_controls(self
):
622 for ctrl
in gajim
.interface
.msg_win_mgr
.get_controls(
623 message_control
.TYPE_GC
):
625 for account
in gajim
.connections
:
626 for ctrl
in gajim
.interface
.minimized_controls
[account
].values():
629 def on_sort_by_show_in_roster_checkbutton_toggled(self
, widget
):
630 self
.on_checkbutton_toggled(widget
, 'sort_by_show_in_roster')
631 gajim
.interface
.roster
.setup_and_draw_roster()
633 def on_sort_by_show_in_muc_checkbutton_toggled(self
, widget
):
634 self
.on_checkbutton_toggled(widget
, 'sort_by_show_in_muc')
636 for ctrl
in self
._get
_all
_muc
_controls
():
639 def on_show_avatars_in_roster_checkbutton_toggled(self
, widget
):
640 self
.on_checkbutton_toggled(widget
, 'show_avatars_in_roster')
641 gajim
.interface
.roster
.setup_and_draw_roster()
642 # Redraw groupchats (in an ugly way)
643 for ctrl
in self
._get
_all
_muc
_controls
():
646 def on_show_status_msgs_in_roster_checkbutton_toggled(self
, widget
):
647 self
.on_checkbutton_toggled(widget
, 'show_status_msgs_in_roster')
648 gajim
.interface
.roster
.setup_and_draw_roster()
649 for ctrl
in self
._get
_all
_muc
_controls
():
652 def on_show_mood_in_roster_checkbutton_toggled(self
, widget
):
653 self
.on_checkbutton_toggled(widget
, 'show_mood_in_roster')
654 gajim
.interface
.roster
.setup_and_draw_roster()
656 def on_show_activity_in_roster_checkbutton_toggled(self
, widget
):
657 self
.on_checkbutton_toggled(widget
, 'show_activity_in_roster')
658 gajim
.interface
.roster
.setup_and_draw_roster()
660 def on_show_tunes_in_roster_checkbutton_toggled(self
, widget
):
661 self
.on_checkbutton_toggled(widget
, 'show_tunes_in_roster')
662 gajim
.interface
.roster
.setup_and_draw_roster()
664 def on_show_location_in_roster_checkbutton_toggled(self
, widget
):
665 self
.on_checkbutton_toggled(widget
, 'show_location_in_roster')
666 gajim
.interface
.roster
.setup_and_draw_roster()
668 def on_emoticons_combobox_changed(self
, widget
):
669 active
= widget
.get_active()
670 model
= widget
.get_model()
671 emot_theme
= model
[active
][0].decode('utf-8')
672 if emot_theme
== _('Disabled'):
673 gajim
.config
.set('emoticons_theme', '')
675 gajim
.config
.set('emoticons_theme', emot_theme
)
677 gajim
.interface
.init_emoticons(need_reload
= True)
678 gajim
.interface
.make_regexps()
679 self
.toggle_emoticons()
681 def toggle_emoticons(self
):
683 Update emoticons state in Opened Chat Windows
685 for ctrl
in self
._get
_all
_controls
():
686 ctrl
.toggle_emoticons()
688 def on_one_window_type_combo_changed(self
, widget
):
689 active
= widget
.get_active()
690 config_type
= common
.config
.opt_one_window_types
[active
]
691 gajim
.config
.set('one_message_window', config_type
)
692 gajim
.interface
.save_config()
693 gajim
.interface
.msg_win_mgr
.reconfig()
695 def on_show_roster_on_startup_changed(self
, widget
):
696 active
= widget
.get_active()
697 config_type
= common
.config
.opt_show_roster_on_startup
[active
]
698 gajim
.config
.set('show_roster_on_startup', config_type
)
699 gajim
.interface
.save_config()
701 def on_compact_view_checkbutton_toggled(self
, widget
):
702 active
= widget
.get_active()
703 for ctrl
in self
._get
_all
_controls
():
704 ctrl
.chat_buttons_set_visible(active
)
705 gajim
.config
.set('compact_view', active
)
706 gajim
.interface
.save_config()
708 def on_xhtml_checkbutton_toggled(self
, widget
):
709 self
.on_checkbutton_toggled(widget
, 'ignore_incoming_xhtml')
710 helpers
.update_optional_features()
712 def apply_speller(self
):
713 for ctrl
in self
._get
_all
_controls
():
714 if isinstance(ctrl
, chat_control
.ChatControlBase
):
716 spell_obj
= gtkspell
.get_from_text_view(ctrl
.msg_textview
)
717 except (TypeError, RuntimeError, OSError):
723 def remove_speller(self
):
724 for ctrl
in self
._get
_all
_controls
():
725 if isinstance(ctrl
, chat_control
.ChatControlBase
):
727 spell_obj
= gtkspell
.get_from_text_view(ctrl
.msg_textview
)
728 except (TypeError, RuntimeError):
733 def on_speller_checkbutton_toggled(self
, widget
):
734 active
= widget
.get_active()
735 gajim
.config
.set('use_speller', active
)
736 gajim
.interface
.save_config()
738 lang
= gajim
.config
.get('speller_language')
743 gtkspell
.Spell(tv
, lang
)
744 except (TypeError, RuntimeError, OSError):
746 _('Dictionary for lang %s not available') % lang
,
747 _('You have to install %s dictionary to use spellchecking, or '
748 'choose another language by setting the speller_language option.'
750 gajim
.config
.set('use_speller', False)
751 widget
.set_active(False)
753 gajim
.config
.set('speller_language', lang
)
756 self
.remove_speller()
758 def on_theme_combobox_changed(self
, widget
):
759 model
= widget
.get_model()
760 active
= widget
.get_active()
761 config_theme
= model
[active
][0].decode('utf-8').replace(' ', '_')
763 gajim
.config
.set('roster_theme', config_theme
)
765 # begin repainting themed widgets throughout
766 gajim
.interface
.roster
.repaint_themed_widgets()
767 gajim
.interface
.roster
.change_roster_style(None)
768 gajim
.interface
.save_config()
770 def update_theme_list(self
):
771 theme_combobox
= self
.xml
.get_object('theme_combobox')
772 model
= gtk
.ListStore(str)
773 theme_combobox
.set_model(model
)
775 for config_theme
in gajim
.config
.get_per('themes'):
776 theme
= config_theme
.replace('_', ' ')
777 model
.append([theme
])
778 if gajim
.config
.get('roster_theme') == config_theme
:
779 theme_combobox
.set_active(i
)
782 def on_manage_theme_button_clicked(self
, widget
):
783 if self
.theme_preferences
is None:
784 self
.theme_preferences
= dialogs
.GajimThemesWindow()
786 self
.theme_preferences
.window
.present()
787 self
.theme_preferences
.select_active_theme()
789 def on_iconset_combobox_changed(self
, widget
):
790 model
= widget
.get_model()
791 active
= widget
.get_active()
792 icon_string
= model
[active
][1].decode('utf-8')
793 gajim
.config
.set('iconset', icon_string
)
794 gtkgui_helpers
.reload_jabber_state_images()
795 gajim
.interface
.save_config()
797 def on_transports_iconsets_checkbutton_toggled(self
, widget
):
798 self
.on_checkbutton_toggled(widget
, 'use_transports_iconsets')
799 gtkgui_helpers
.reload_jabber_state_images()
801 def on_outgoing_chat_states_combobox_changed(self
, widget
):
802 active
= widget
.get_active()
803 old_value
= gajim
.config
.get('outgoing_chat_state_notifications')
804 if active
== 0: # all
805 gajim
.config
.set('outgoing_chat_state_notifications', 'all')
806 elif active
== 1: # only composing
807 gajim
.config
.set('outgoing_chat_state_notifications', 'composing_only')
809 gajim
.config
.set('outgoing_chat_state_notifications', 'disabled')
810 new_value
= gajim
.config
.get('outgoing_chat_state_notifications')
811 if 'disabled' in (old_value
, new_value
):
812 # we changed from disabled to sth else or vice versa
813 helpers
.update_optional_features()
815 def on_displayed_chat_states_combobox_changed(self
, widget
):
816 active
= widget
.get_active()
817 if active
== 0: # all
818 gajim
.config
.set('displayed_chat_state_notifications', 'all')
819 elif active
== 1: # only composing
820 gajim
.config
.set('displayed_chat_state_notifications',
823 gajim
.config
.set('displayed_chat_state_notifications', 'disabled')
825 def on_ignore_events_from_unknown_contacts_checkbutton_toggled(self
, widget
):
826 widget
.set_inconsistent(False)
827 self
.on_per_account_checkbutton_toggled(widget
, 'ignore_unknown_contacts')
829 def on_on_event_combobox_changed(self
, widget
):
830 active
= widget
.get_active()
832 gajim
.config
.set('autopopup', True)
833 gajim
.config
.set('notify_on_new_message', False)
835 gajim
.config
.set('autopopup', False)
836 gajim
.config
.set('notify_on_new_message', True)
838 gajim
.config
.set('autopopup', False)
839 gajim
.config
.set('notify_on_new_message', False)
841 def on_notify_on_signin_checkbutton_toggled(self
, widget
):
842 self
.on_checkbutton_toggled(widget
, 'notify_on_signin')
844 def on_notify_on_signout_checkbutton_toggled(self
, widget
):
845 self
.on_checkbutton_toggled(widget
, 'notify_on_signout')
847 def on_auto_popup_away_checkbutton_toggled(self
, widget
):
848 self
.on_checkbutton_toggled(widget
, 'autopopupaway')
850 def on_sound_dnd_checkbutton_toggled(self
, widget
):
851 self
.on_checkbutton_toggled(widget
, 'sounddnd')
853 def on_systray_combobox_changed(self
, widget
):
854 active
= widget
.get_active()
856 gajim
.config
.set('trayicon', 'never')
857 gajim
.interface
.systray_enabled
= False
858 gajim
.interface
.systray
.hide_icon()
860 gajim
.config
.set('trayicon', 'on_event')
861 gajim
.interface
.systray_enabled
= True
862 gajim
.interface
.systray
.show_icon()
864 gajim
.config
.set('trayicon', 'always')
865 gajim
.interface
.systray_enabled
= True
866 gajim
.interface
.systray
.show_icon()
868 def on_play_sounds_checkbutton_toggled(self
, widget
):
869 self
.on_checkbutton_toggled(widget
, 'sounds_on',
870 [self
.xml
.get_object('manage_sounds_button')])
872 def on_manage_sounds_button_clicked(self
, widget
):
873 if self
.sounds_preferences
is None:
874 self
.sounds_preferences
= ManageSoundsWindow()
876 self
.sounds_preferences
.window
.present()
878 def update_text_tags(self
):
880 Update color tags in opened chat windows
882 for ctrl
in self
._get
_all
_controls
():
885 def on_preference_widget_color_set(self
, widget
, text
):
886 color
= widget
.get_color()
887 color_string
= gtkgui_helpers
.make_color_string(color
)
888 gajim
.config
.set(text
, color_string
)
889 self
.update_text_tags()
890 gajim
.interface
.save_config()
892 def on_preference_widget_font_set(self
, widget
, text
):
894 font
= widget
.get_font_name()
897 gajim
.config
.set(text
, font
)
898 self
.update_text_font()
899 gajim
.interface
.save_config()
901 def update_text_font(self
):
903 Update text font in opened chat windows
905 for ctrl
in self
._get
_all
_controls
():
908 def on_incoming_nick_colorbutton_color_set(self
, widget
):
909 self
.on_preference_widget_color_set(widget
, 'inmsgcolor')
911 def on_outgoing_nick_colorbutton_color_set(self
, widget
):
912 self
.on_preference_widget_color_set(widget
, 'outmsgcolor')
914 def on_incoming_msg_colorbutton_color_set(self
, widget
):
915 self
.on_preference_widget_color_set(widget
, 'inmsgtxtcolor')
917 def on_outgoing_msg_colorbutton_color_set(self
, widget
):
918 self
.on_preference_widget_color_set(widget
, 'outmsgtxtcolor')
920 def on_url_msg_colorbutton_color_set(self
, widget
):
921 self
.on_preference_widget_color_set(widget
, 'urlmsgcolor')
923 def on_status_msg_colorbutton_color_set(self
, widget
):
924 self
.on_preference_widget_color_set(widget
, 'statusmsgcolor')
926 def on_conversation_fontbutton_font_set(self
, widget
):
927 self
.on_preference_widget_font_set(widget
, 'conversation_font')
929 def on_default_chat_font_toggled(self
, widget
):
930 font_widget
= self
.xml
.get_object('conversation_fontbutton')
931 if widget
.get_active():
932 font_widget
.set_sensitive(False)
935 font_widget
.set_sensitive(True)
936 self
.on_preference_widget_font_set(font_widget
, 'conversation_font')
938 def draw_color_widgets(self
):
939 col_to_widget
= {'inmsgcolor': 'incoming_nick_colorbutton',
940 'outmsgcolor': 'outgoing_nick_colorbutton',
941 'inmsgtxtcolor': ['incoming_msg_colorbutton',
942 'incoming_msg_checkbutton'],
943 'outmsgtxtcolor': ['outgoing_msg_colorbutton',
944 'outgoing_msg_checkbutton'],
945 'statusmsgcolor': 'status_msg_colorbutton',
946 'urlmsgcolor': 'url_msg_colorbutton'}
947 for c
in col_to_widget
:
948 col
= gajim
.config
.get(c
)
950 if isinstance(col_to_widget
[c
], list):
951 self
.xml
.get_object(col_to_widget
[c
][0]).set_color(
952 gtk
.gdk
.color_parse(col
))
953 self
.xml
.get_object(col_to_widget
[c
][0]).set_sensitive(True)
954 self
.xml
.get_object(col_to_widget
[c
][1]).set_active(True)
956 self
.xml
.get_object(col_to_widget
[c
]).set_color(
957 gtk
.gdk
.color_parse(col
))
959 if isinstance(col_to_widget
[c
], list):
960 self
.xml
.get_object(col_to_widget
[c
][0]).set_color(
961 gtk
.gdk
.color_parse('#000000'))
962 self
.xml
.get_object(col_to_widget
[c
][0]).set_sensitive(False)
963 self
.xml
.get_object(col_to_widget
[c
][1]).set_active(False)
965 self
.xml
.get_object(col_to_widget
[c
]).set_color(
966 gtk
.gdk
.color_parse('#000000'))
968 def on_reset_colors_button_clicked(self
, widget
):
969 col_to_widget
= {'inmsgcolor': 'incoming_nick_colorbutton',
970 'outmsgcolor': 'outgoing_nick_colorbutton',
971 'inmsgtxtcolor': 'incoming_msg_colorbutton',
972 'outmsgtxtcolor': 'outgoing_msg_colorbutton',
973 'statusmsgcolor': 'status_msg_colorbutton',
974 'urlmsgcolor': 'url_msg_colorbutton'}
975 for c
in col_to_widget
:
976 gajim
.config
.set(c
, gajim
.interface
.default_colors
[c
])
977 self
.draw_color_widgets()
979 self
.update_text_tags()
980 gajim
.interface
.save_config()
982 def _set_color(self
, state
, widget_name
, option
):
984 Set color value in prefs and update the UI
987 color
= self
.xml
.get_object(widget_name
).get_color()
988 color_string
= gtkgui_helpers
.make_color_string(color
)
991 gajim
.config
.set(option
, color_string
)
992 gajim
.interface
.save_config()
994 def on_incoming_msg_checkbutton_toggled(self
, widget
):
995 state
= widget
.get_active()
996 self
.xml
.get_object('incoming_msg_colorbutton').set_sensitive(state
)
997 self
._set
_color
(state
, 'incoming_msg_colorbutton', 'inmsgtxtcolor')
999 def on_outgoing_msg_checkbutton_toggled(self
, widget
):
1000 state
= widget
.get_active()
1001 self
.xml
.get_object('outgoing_msg_colorbutton').set_sensitive(state
)
1002 self
._set
_color
(state
, 'outgoing_msg_colorbutton', 'outmsgtxtcolor')
1004 def on_auto_away_checkbutton_toggled(self
, widget
):
1005 self
.on_checkbutton_toggled(widget
, 'autoaway',
1006 [self
.auto_away_time_spinbutton
, self
.auto_away_message_entry
])
1008 def on_auto_away_time_spinbutton_value_changed(self
, widget
):
1009 aat
= widget
.get_value_as_int()
1010 gajim
.config
.set('autoawaytime', aat
)
1011 gajim
.interface
.sleeper
= common
.sleepy
.Sleepy(
1012 gajim
.config
.get('autoawaytime') * 60,
1013 gajim
.config
.get('autoxatime') * 60)
1014 gajim
.interface
.save_config()
1016 def on_auto_away_message_entry_changed(self
, widget
):
1017 gajim
.config
.set('autoaway_message', widget
.get_text().decode('utf-8'))
1019 def on_auto_xa_checkbutton_toggled(self
, widget
):
1020 self
.on_checkbutton_toggled(widget
, 'autoxa',
1021 [self
.auto_xa_time_spinbutton
, self
.auto_xa_message_entry
])
1023 def on_auto_xa_time_spinbutton_value_changed(self
, widget
):
1024 axt
= widget
.get_value_as_int()
1025 gajim
.config
.set('autoxatime', axt
)
1026 gajim
.interface
.sleeper
= common
.sleepy
.Sleepy(
1027 gajim
.config
.get('autoawaytime') * 60,
1028 gajim
.config
.get('autoxatime') * 60)
1029 gajim
.interface
.save_config()
1031 def on_auto_xa_message_entry_changed(self
, widget
):
1032 gajim
.config
.set('autoxa_message', widget
.get_text().decode('utf-8'))
1034 def on_prompt_online_status_message_checkbutton_toggled(self
, widget
):
1035 self
.on_checkbutton_toggled(widget
, 'ask_online_status')
1037 def on_prompt_offline_status_message_checkbutton_toggled(self
, widget
):
1038 self
.on_checkbutton_toggled(widget
, 'ask_offline_status')
1040 def fill_default_msg_treeview(self
):
1041 model
= self
.default_msg_tree
.get_model()
1044 for status_
in gajim
.config
.get_per('defaultstatusmsg'):
1045 status
.append(status_
)
1047 for status_
in status
:
1048 msg
= gajim
.config
.get_per('defaultstatusmsg', status_
, 'message')
1049 msg
= helpers
.from_one_line(msg
)
1050 enabled
= gajim
.config
.get_per('defaultstatusmsg', status_
, 'enabled')
1051 iter_
= model
.append()
1052 uf_show
= helpers
.get_uf_show(status_
)
1053 model
.set(iter_
, 0, status_
, 1, uf_show
, 2, msg
, 3, enabled
)
1055 def on_default_msg_cell_edited(self
, cell
, row
, new_text
):
1056 model
= self
.default_msg_tree
.get_model()
1057 iter_
= model
.get_iter_from_string(row
)
1058 model
.set_value(iter_
, 2, new_text
)
1060 def default_msg_toggled_cb(self
, cell
, path
):
1061 model
= self
.default_msg_tree
.get_model()
1062 model
[path
][3] = not model
[path
][3]
1064 def on_default_msg_treemodel_row_changed(self
, model
, path
, iter_
):
1065 status
= model
[iter_
][0]
1066 message
= model
[iter_
][2].decode('utf-8')
1067 message
= helpers
.to_one_line(message
)
1068 gajim
.config
.set_per('defaultstatusmsg', status
, 'enabled',
1070 gajim
.config
.set_per('defaultstatusmsg', status
, 'message', message
)
1072 def on_default_status_expander_activate(self
, expander
):
1073 eventbox
= self
.xml
.get_object('default_status_eventbox')
1074 vbox
= self
.xml
.get_object('status_vbox')
1075 vbox
.set_child_packing(eventbox
, not expander
.get_expanded(), True, 0,
1078 def save_status_messages(self
, model
):
1079 for msg
in gajim
.config
.get_per('statusmsg'):
1080 gajim
.config
.del_per('statusmsg', msg
)
1081 iter_
= model
.get_iter_first()
1083 val
= model
[iter_
][0].decode('utf-8')
1084 if model
[iter_
][1]: # we have a preset message
1085 if not val
: # no title, use message text for title
1086 val
= model
[iter_
][1]
1087 gajim
.config
.add_per('statusmsg', val
)
1088 msg
= helpers
.to_one_line(model
[iter_
][1].decode('utf-8'))
1089 gajim
.config
.set_per('statusmsg', val
, 'message', msg
)
1091 # store mood / activity
1092 for subname
in ('activity', 'subactivity', 'activity_text',
1093 'mood', 'mood_text'):
1094 gajim
.config
.set_per('statusmsg', val
, subname
,
1095 model
[iter_
][i
].decode('utf-8'))
1097 iter_
= model
.iter_next(iter_
)
1098 gajim
.interface
.save_config()
1100 def on_msg_treemodel_row_changed(self
, model
, path
, iter_
):
1101 self
.save_status_messages(model
)
1103 def on_msg_treemodel_row_deleted(self
, model
, path
):
1104 self
.save_status_messages(model
)
1106 def on_av_combobox_changed(self
, combobox
, config_name
):
1107 model
= combobox
.get_model()
1108 active
= combobox
.get_active()
1109 device
= model
[active
][1].decode('utf-8')
1110 gajim
.config
.set(config_name
, device
)
1112 def on_audio_input_combobox_changed(self
, widget
):
1113 self
.on_av_combobox_changed(widget
, 'audio_input_device')
1115 def on_audio_output_combobox_changed(self
, widget
):
1116 self
.on_av_combobox_changed(widget
, 'audio_output_device')
1118 def on_video_input_combobox_changed(self
, widget
):
1119 self
.on_av_combobox_changed(widget
, 'video_input_device')
1121 def on_video_output_combobox_changed(self
, widget
):
1122 self
.on_av_combobox_changed(widget
, 'video_output_device')
1124 def on_video_framerate_combobox_changed(self
, widget
):
1125 self
.on_av_combobox_changed(widget
, 'video_framerate')
1127 def on_video_size_combobox_changed(self
, widget
):
1128 self
.on_av_combobox_changed(widget
, 'video_size')
1130 def on_stun_checkbutton_toggled(self
, widget
):
1131 self
.on_checkbutton_toggled(widget
, 'use_stun_server',
1132 [self
.xml
.get_object('stun_server_entry')])
1134 def stun_server_entry_changed(self
, widget
):
1135 gajim
.config
.set('stun_server', widget
.get_text().decode('utf-8'))
1137 def on_applications_combobox_changed(self
, widget
):
1138 if widget
.get_active() == 0:
1139 gajim
.config
.set('autodetect_browser_mailer', True)
1140 self
.xml
.get_object('custom_apps_frame').hide()
1141 elif widget
.get_active() == 1:
1142 gajim
.config
.set('autodetect_browser_mailer', False)
1143 self
.xml
.get_object('custom_apps_frame').show()
1144 gajim
.interface
.save_config()
1146 def on_custom_browser_entry_changed(self
, widget
):
1147 gajim
.config
.set('custombrowser', widget
.get_text().decode('utf-8'))
1148 gajim
.interface
.save_config()
1150 def on_custom_mail_client_entry_changed(self
, widget
):
1151 gajim
.config
.set('custommailapp', widget
.get_text().decode('utf-8'))
1152 gajim
.interface
.save_config()
1154 def on_custom_file_manager_entry_changed(self
, widget
):
1155 gajim
.config
.set('custom_file_manager', widget
.get_text().decode('utf-8'))
1156 gajim
.interface
.save_config()
1158 def on_log_show_changes_checkbutton_toggled(self
, widget
):
1159 self
.on_checkbutton_toggled(widget
, 'log_contact_status_changes')
1161 def on_log_encrypted_chats_checkbutton_toggled(self
, widget
):
1162 widget
.set_inconsistent(False)
1163 self
.on_per_account_checkbutton_toggled(widget
, 'log_encrypted_sessions')
1165 def on_send_os_info_checkbutton_toggled(self
, widget
):
1166 widget
.set_inconsistent(False)
1167 self
.on_per_account_checkbutton_toggled(widget
, 'send_os_info')
1169 def on_send_idle_time_checkbutton_toggled(self
, widget
):
1170 widget
.set_inconsistent(False)
1171 self
.on_per_account_checkbutton_toggled(widget
, 'send_idle_time')
1173 def on_check_default_client_checkbutton_toggled(self
, widget
):
1174 self
.on_checkbutton_toggled(widget
, 'check_if_gajim_is_default')
1176 def on_notify_gmail_checkbutton_toggled(self
, widget
):
1177 self
.on_checkbutton_toggled(widget
, 'notify_on_new_gmail_email')
1179 def on_notify_gmail_extra_checkbutton_toggled(self
, widget
):
1180 self
.on_checkbutton_toggled(widget
, 'notify_on_new_gmail_email_extra')
1182 def fill_msg_treeview(self
):
1183 self
.xml
.get_object('delete_msg_button').set_sensitive(False)
1184 model
= self
.msg_tree
.get_model()
1187 for msg_name
in gajim
.config
.get_per('statusmsg'):
1188 if msg_name
.startswith('_last_'):
1190 preset_status
.append(msg_name
)
1191 preset_status
.sort()
1192 for msg_name
in preset_status
:
1193 msg_text
= gajim
.config
.get_per('statusmsg', msg_name
, 'message')
1194 msg_text
= helpers
.from_one_line(msg_text
)
1195 activity
= gajim
.config
.get_per('statusmsg', msg_name
, 'activity')
1196 subactivity
= gajim
.config
.get_per('statusmsg', msg_name
,
1198 activity_text
= gajim
.config
.get_per('statusmsg', msg_name
,
1200 mood
= gajim
.config
.get_per('statusmsg', msg_name
, 'mood')
1201 mood_text
= gajim
.config
.get_per('statusmsg', msg_name
, 'mood_text')
1202 iter_
= model
.append()
1203 model
.set(iter_
, 0, msg_name
, 1, msg_text
, 2, activity
, 3,
1204 subactivity
, 4, activity_text
, 5, mood
, 6, mood_text
)
1206 def on_msg_cell_edited(self
, cell
, row
, new_text
):
1207 model
= self
.msg_tree
.get_model()
1208 iter_
= model
.get_iter_from_string(row
)
1209 model
.set_value(iter_
, 0, new_text
)
1211 def on_msg_treeview_cursor_changed(self
, widget
, data
= None):
1212 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1215 self
.xml
.get_object('delete_msg_button').set_sensitive(True)
1216 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1217 msg
= model
[iter_
][1]
1220 def on_new_msg_button_clicked(self
, widget
, data
= None):
1221 model
= self
.msg_tree
.get_model()
1222 iter_
= model
.append()
1223 model
.set(iter_
, 0, _('status message title'), 1, _('status message text'))
1224 self
.msg_tree
.set_cursor(model
.get_path(iter_
))
1226 def on_delete_msg_button_clicked(self
, widget
, data
= None):
1227 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1230 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1233 self
.xml
.get_object('delete_msg_button').set_sensitive(False)
1235 def on_msg_textview_changed(self
, widget
, data
= None):
1236 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1239 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1240 first_iter
, end_iter
= buf
.get_bounds()
1241 model
.set_value(iter_
, 1, buf
.get_text(first_iter
, end_iter
))
1243 def on_msg_treeview_key_press_event(self
, widget
, event
):
1244 if event
.keyval
== gtk
.keysyms
.Delete
:
1245 self
.on_delete_msg_button_clicked(widget
)
1247 def on_open_advanced_editor_button_clicked(self
, widget
, data
= None):
1248 if 'advanced_config' in gajim
.interface
.instances
:
1249 gajim
.interface
.instances
['advanced_config'].window
.present()
1251 gajim
.interface
.instances
['advanced_config'] = \
1252 dialogs
.AdvancedConfigurationWindow()
1254 #---------- ManageProxiesWindow class -------------#
1255 class ManageProxiesWindow
:
1257 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_proxies_window.ui')
1258 self
.window
= self
.xml
.get_object('manage_proxies_window')
1259 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
1260 self
.proxies_treeview
= self
.xml
.get_object('proxies_treeview')
1261 self
.proxyname_entry
= self
.xml
.get_object('proxyname_entry')
1262 self
.proxytype_combobox
= self
.xml
.get_object('proxytype_combobox')
1265 self
.block_signal
= False
1266 self
.xml
.connect_signals(self
)
1267 self
.window
.show_all()
1268 # hide the BOSH fields by default
1269 self
.show_bosh_fields()
1271 def show_bosh_fields(self
, show
=True):
1273 self
.xml
.get_object('boshuri_entry').show()
1274 self
.xml
.get_object('boshuri_label').show()
1275 self
.xml
.get_object('boshuseproxy_checkbutton').show()
1277 cb
= self
.xml
.get_object('boshuseproxy_checkbutton')
1280 self
.on_boshuseproxy_checkbutton_toggled(cb
)
1281 self
.xml
.get_object('boshuri_entry').hide()
1282 self
.xml
.get_object('boshuri_label').hide()
1285 def fill_proxies_treeview(self
):
1286 model
= self
.proxies_treeview
.get_model()
1288 iter_
= model
.append()
1289 model
.set(iter_
, 0, _('None'))
1290 for p
in gajim
.config
.get_per('proxies'):
1291 iter_
= model
.append()
1292 model
.set(iter_
, 0, p
)
1294 def init_list(self
):
1295 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1296 self
.proxytype_combobox
.set_sensitive(False)
1297 self
.xml
.get_object('proxy_table').set_sensitive(False)
1298 model
= gtk
.ListStore(str)
1299 self
.proxies_treeview
.set_model(model
)
1300 col
= gtk
.TreeViewColumn('Proxies')
1301 self
.proxies_treeview
.append_column(col
)
1302 renderer
= gtk
.CellRendererText()
1303 col
.pack_start(renderer
, True)
1304 col
.set_attributes(renderer
, text
= 0)
1305 self
.fill_proxies_treeview()
1306 self
.xml
.get_object('proxytype_combobox').set_active(0)
1308 def on_manage_proxies_window_destroy(self
, widget
):
1309 if 'accounts' in gajim
.interface
.instances
:
1310 gajim
.interface
.instances
['accounts'].\
1312 del gajim
.interface
.instances
['manage_proxies']
1314 def on_add_proxy_button_clicked(self
, widget
):
1315 model
= self
.proxies_treeview
.get_model()
1316 proxies
= gajim
.config
.get_per('proxies')
1318 while ('proxy' + unicode(i
)) in proxies
:
1320 iter_
= model
.append()
1321 model
.set(iter_
, 0, 'proxy' + unicode(i
))
1322 gajim
.config
.add_per('proxies', 'proxy' + unicode(i
))
1323 self
.proxies_treeview
.set_cursor(model
.get_path(iter_
))
1325 def on_remove_proxy_button_clicked(self
, widget
):
1326 (model
, iter_
) = self
.proxies_treeview
.get_selection().get_selected()
1329 proxy
= model
[iter_
][0].decode('utf-8')
1331 gajim
.config
.del_per('proxies', proxy
)
1332 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1333 self
.block_signal
= True
1334 self
.on_proxies_treeview_cursor_changed(self
.proxies_treeview
)
1335 self
.block_signal
= False
1337 def on_close_button_clicked(self
, widget
):
1338 self
.window
.destroy()
1340 def on_useauth_checkbutton_toggled(self
, widget
):
1341 if self
.block_signal
:
1343 act
= widget
.get_active()
1344 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1345 gajim
.config
.set_per('proxies', proxy
, 'useauth', act
)
1346 self
.xml
.get_object('proxyuser_entry').set_sensitive(act
)
1347 self
.xml
.get_object('proxypass_entry').set_sensitive(act
)
1349 def on_boshuseproxy_checkbutton_toggled(self
, widget
):
1350 if self
.block_signal
:
1352 act
= widget
.get_active()
1353 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1354 gajim
.config
.set_per('proxies', proxy
, 'bosh_useproxy', act
)
1355 self
.xml
.get_object('proxyhost_entry').set_sensitive(act
)
1356 self
.xml
.get_object('proxyport_entry').set_sensitive(act
)
1358 def on_proxies_treeview_cursor_changed(self
, widget
):
1359 #FIXME: check if off proxy settings are correct (see
1360 # http://trac.gajim.org/changeset/1921#file2 line 1221
1361 proxyhost_entry
= self
.xml
.get_object('proxyhost_entry')
1362 proxyport_entry
= self
.xml
.get_object('proxyport_entry')
1363 proxyuser_entry
= self
.xml
.get_object('proxyuser_entry')
1364 proxypass_entry
= self
.xml
.get_object('proxypass_entry')
1365 boshuri_entry
= self
.xml
.get_object('boshuri_entry')
1366 useauth_checkbutton
= self
.xml
.get_object('useauth_checkbutton')
1367 boshuseproxy_checkbutton
= self
.xml
.get_object('boshuseproxy_checkbutton')
1368 self
.block_signal
= True
1369 proxyhost_entry
.set_text('')
1370 proxyport_entry
.set_text('')
1371 proxyuser_entry
.set_text('')
1372 proxypass_entry
.set_text('')
1373 boshuri_entry
.set_text('')
1375 #boshuseproxy_checkbutton.set_active(False)
1376 #self.on_boshuseproxy_checkbutton_toggled(boshuseproxy_checkbutton)
1378 #useauth_checkbutton.set_active(False)
1379 #self.on_useauth_checkbutton_toggled(useauth_checkbutton)
1381 (model
, iter_
) = widget
.get_selection().get_selected()
1383 self
.xml
.get_object('proxyname_entry').set_text('')
1384 self
.xml
.get_object('proxytype_combobox').set_sensitive(False)
1385 self
.xml
.get_object('proxy_table').set_sensitive(False)
1386 self
.block_signal
= False
1389 proxy
= model
[iter_
][0]
1390 self
.xml
.get_object('proxyname_entry').set_text(proxy
)
1392 if proxy
== _('None'): # special proxy None
1393 self
.show_bosh_fields(False)
1394 self
.proxyname_entry
.set_editable(False)
1395 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1396 self
.xml
.get_object('proxytype_combobox').set_sensitive(False)
1397 self
.xml
.get_object('proxy_table').set_sensitive(False)
1399 proxytype
= gajim
.config
.get_per('proxies', proxy
, 'type')
1401 self
.show_bosh_fields(proxytype
=='bosh')
1403 self
.proxyname_entry
.set_editable(True)
1404 self
.xml
.get_object('remove_proxy_button').set_sensitive(True)
1405 self
.xml
.get_object('proxytype_combobox').set_sensitive(True)
1406 self
.xml
.get_object('proxy_table').set_sensitive(True)
1407 proxyhost_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1409 proxyport_entry
.set_text(unicode(gajim
.config
.get_per('proxies',
1411 proxyuser_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1413 proxypass_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1415 boshuri_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1417 types
= ['http', 'socks5', 'bosh']
1418 self
.proxytype_combobox
.set_active(types
.index(proxytype
))
1419 boshuseproxy_checkbutton
.set_active(
1420 gajim
.config
.get_per('proxies', proxy
, 'bosh_useproxy'))
1421 useauth_checkbutton
.set_active(
1422 gajim
.config
.get_per('proxies', proxy
, 'useauth'))
1423 self
.block_signal
= False
1425 def on_proxies_treeview_key_press_event(self
, widget
, event
):
1426 if event
.keyval
== gtk
.keysyms
.Delete
:
1427 self
.on_remove_proxy_button_clicked(widget
)
1429 def on_proxyname_entry_changed(self
, widget
):
1430 if self
.block_signal
:
1432 (model
, iter_
) = self
.proxies_treeview
.get_selection().get_selected()
1435 old_name
= model
.get_value(iter_
, 0).decode('utf-8')
1436 new_name
= widget
.get_text().decode('utf-8')
1439 if new_name
== old_name
:
1441 config
= gajim
.config
.get_per('proxies', old_name
)
1442 gajim
.config
.del_per('proxies', old_name
)
1443 gajim
.config
.add_per('proxies', new_name
)
1444 for option
in config
:
1445 gajim
.config
.set_per('proxies', new_name
, option
,
1446 config
[option
][common
.config
.OPT_VAL
])
1447 model
.set_value(iter_
, 0, new_name
)
1449 def on_proxytype_combobox_changed(self
, widget
):
1450 if self
.block_signal
:
1452 types
= ['http', 'socks5', 'bosh']
1453 type_
= self
.proxytype_combobox
.get_active()
1454 self
.show_bosh_fields(types
[type_
]=='bosh')
1455 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1456 gajim
.config
.set_per('proxies', proxy
, 'type', types
[type_
])
1458 def on_proxyhost_entry_changed(self
, widget
):
1459 if self
.block_signal
:
1461 value
= widget
.get_text().decode('utf-8')
1462 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1463 gajim
.config
.set_per('proxies', proxy
, 'host', value
)
1465 def on_proxyport_entry_changed(self
, widget
):
1466 if self
.block_signal
:
1468 value
= widget
.get_text().decode('utf-8')
1469 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1470 gajim
.config
.set_per('proxies', proxy
, 'port', value
)
1472 def on_proxyuser_entry_changed(self
, widget
):
1473 if self
.block_signal
:
1475 value
= widget
.get_text().decode('utf-8')
1476 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1477 gajim
.config
.set_per('proxies', proxy
, 'user', value
)
1479 def on_boshuri_entry_changed(self
, widget
):
1480 if self
.block_signal
:
1482 value
= widget
.get_text().decode('utf-8')
1483 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1484 gajim
.config
.set_per('proxies', proxy
, 'bosh_uri', value
)
1486 def on_proxypass_entry_changed(self
, widget
):
1487 if self
.block_signal
:
1489 value
= widget
.get_text().decode('utf-8')
1490 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1491 gajim
.config
.set_per('proxies', proxy
, 'pass', value
)
1494 #---------- AccountsWindow class -------------#
1495 class AccountsWindow
:
1497 Class for accounts window: list of accounts
1500 def on_accounts_window_destroy(self
, widget
):
1501 del gajim
.interface
.instances
['accounts']
1503 def on_close_button_clicked(self
, widget
):
1504 self
.check_resend_relog()
1505 self
.window
.destroy()
1508 self
.xml
= gtkgui_helpers
.get_gtk_builder('accounts_window.ui')
1509 self
.window
= self
.xml
.get_object('accounts_window')
1510 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
1511 self
.accounts_treeview
= self
.xml
.get_object('accounts_treeview')
1512 self
.remove_button
= self
.xml
.get_object('remove_button')
1513 self
.rename_button
= self
.xml
.get_object('rename_button')
1514 path_to_kbd_input_img
= gtkgui_helpers
.get_icon_path('gajim-kbd_input')
1515 img
= self
.xml
.get_object('rename_image')
1516 img
.set_from_file(path_to_kbd_input_img
)
1517 self
.notebook
= self
.xml
.get_object('notebook')
1519 model
= gtk
.ListStore(str)
1520 self
.accounts_treeview
.set_model(model
)
1522 renderer
= gtk
.CellRendererText()
1523 self
.accounts_treeview
.insert_column_with_attributes(-1, _('Name'),
1526 self
.current_account
= None
1527 # When we fill info, we don't want to handle the changed signals
1528 self
.ignore_events
= False
1529 self
.need_relogin
= False
1530 self
.resend_presence
= False
1532 self
.update_proxy_list()
1533 self
.xml
.connect_signals(self
)
1534 self
.init_accounts()
1535 self
.window
.show_all()
1538 st
= gajim
.config
.get('mergeaccounts')
1539 checkbutton
= self
.xml
.get_object('merge_checkbutton')
1540 checkbutton
.set_active(st
)
1541 # prevent roster redraws by connecting the signal after button state is
1543 checkbutton
.connect('toggled', self
.on_merge_checkbutton_toggled
)
1545 self
.avahi_available
= True
1549 self
.avahi_available
= False
1551 def on_accounts_window_key_press_event(self
, widget
, event
):
1552 if event
.keyval
== gtk
.keysyms
.Escape
:
1553 self
.check_resend_relog()
1554 self
.window
.destroy()
1556 def select_account(self
, account
):
1557 model
= self
.accounts_treeview
.get_model()
1558 iter_
= model
.get_iter_root()
1560 acct
= model
[iter_
][0].decode('utf-8')
1562 self
.accounts_treeview
.set_cursor(model
.get_path(iter_
))
1564 iter_
= model
.iter_next(iter_
)
1566 def init_accounts(self
):
1568 Initialize listStore with existing accounts
1570 self
.remove_button
.set_sensitive(False)
1571 self
.rename_button
.set_sensitive(False)
1572 self
.current_account
= None
1573 model
= self
.accounts_treeview
.get_model()
1575 for account
in gajim
.config
.get_per('accounts'):
1576 iter_
= model
.append()
1577 model
.set(iter_
, 0, account
)
1579 def resend(self
, account
):
1580 if not account
in gajim
.connections
:
1582 show
= gajim
.SHOW_LIST
[gajim
.connections
[account
].connected
]
1583 status
= gajim
.connections
[account
].status
1584 gajim
.connections
[account
].change_status(show
, status
)
1586 def check_resend_relog(self
):
1587 if self
.need_relogin
and self
.current_account
== gajim
.ZEROCONF_ACC_NAME
:
1588 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
:
1589 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].update_details()
1592 elif self
.need_relogin
and self
.current_account
and \
1593 gajim
.connections
[self
.current_account
].connected
> 0:
1594 def login(account
, show_before
, status_before
):
1596 Login with previous status
1598 # first make sure connection is really closed,
1599 # 0.5 may not be enough
1600 gajim
.connections
[account
].disconnect(True)
1601 gajim
.interface
.roster
.send_status(account
, show_before
,
1605 self
.dialog
.destroy()
1606 show_before
= gajim
.SHOW_LIST
[gajim
.connections
[account
].connected
]
1607 status_before
= gajim
.connections
[account
].status
1608 gajim
.interface
.roster
.send_status(account
, 'offline',
1609 _('Be right back.'))
1610 gobject
.timeout_add(500, login
, account
, show_before
, status_before
)
1612 def on_yes(checked
, account
):
1615 if self
.resend_presence
:
1616 self
.resend(account
)
1617 if self
.current_account
in gajim
.connections
:
1618 self
.dialog
= dialogs
.YesNoDialog(_('Relogin now?'),
1619 _('If you want all the changes to apply instantly, '
1620 'you must relogin.'), on_response_yes
=(on_yes
,
1621 self
.current_account
), on_response_no
=(on_no
,
1622 self
.current_account
))
1623 elif self
.resend_presence
:
1624 self
.resend(self
.current_account
)
1626 self
.need_relogin
= False
1627 self
.resend_presence
= False
1629 def on_accounts_treeview_cursor_changed(self
, widget
):
1631 Activate modify buttons when a row is selected, update accounts info
1633 sel
= self
.accounts_treeview
.get_selection()
1634 (model
, iter_
) = sel
.get_selected()
1636 account
= model
[iter_
][0].decode('utf-8')
1639 if self
.current_account
and self
.current_account
== account
:
1640 # We're comming back to our current account, no need to update widgets
1642 # Save config for previous account if needed cause focus_out event is
1643 # called after the changed event
1644 if self
.current_account
and self
.window
.get_focus():
1645 focused_widget
= self
.window
.get_focus()
1646 focused_widget_name
= focused_widget
.get_name()
1647 if focused_widget_name
in ('jid_entry1', 'resource_entry1',
1648 'custom_port_entry', 'cert_entry1'):
1649 if focused_widget_name
== 'jid_entry1':
1650 func
= self
.on_jid_entry1_focus_out_event
1651 elif focused_widget_name
== 'resource_entry1':
1652 func
= self
.on_resource_entry1_focus_out_event
1653 elif focused_widget_name
== 'custom_port_entry':
1654 func
= self
.on_custom_port_entry_focus_out_event
1655 elif focused_widget_name
== 'cert_entry1':
1656 func
= self
.on_cert_entry1_focus_out_event
1657 if func(focused_widget
, None):
1658 # Error detected in entry, don't change account, re-put cursor on
1660 self
.select_account(self
.current_account
)
1662 self
.window
.set_focus(widget
)
1664 self
.check_resend_relog()
1667 self
.remove_button
.set_sensitive(True)
1668 self
.rename_button
.set_sensitive(True)
1670 self
.remove_button
.set_sensitive(False)
1671 self
.rename_button
.set_sensitive(False)
1673 self
.current_account
= account
1674 if account
== gajim
.ZEROCONF_ACC_NAME
:
1675 self
.remove_button
.set_sensitive(False)
1677 self
.update_proxy_list()
1679 def on_browse_for_client_cert_button_clicked(self
, widget
, data
=None):
1680 def on_ok(widget
, path_to_clientcert_file
):
1681 self
.dialog
.destroy()
1682 if not path_to_clientcert_file
:
1684 self
.xml
.get_object('cert_entry1').set_text(path_to_clientcert_file
)
1685 gajim
.config
.set_per('accounts', self
.current_account
,
1686 'client_cert', path_to_clientcert_file
)
1688 def on_cancel(widget
):
1689 self
.dialog
.destroy()
1691 path_to_clientcert_file
= self
.xml
.get_object('cert_entry1').get_text()
1692 self
.dialog
= dialogs
.ClientCertChooserDialog(path_to_clientcert_file
,
1695 def update_proxy_list(self
):
1696 if self
.current_account
:
1697 our_proxy
= gajim
.config
.get_per('accounts', self
.current_account
,
1703 our_proxy
= _('None')
1704 proxy_combobox
= self
.xml
.get_object('proxies_combobox1')
1705 model
= gtk
.ListStore(str)
1706 proxy_combobox
.set_model(model
)
1707 l
= gajim
.config
.get_per('proxies')
1708 l
.insert(0, _('None'))
1709 for i
in xrange(len(l
)):
1710 model
.append([l
[i
]])
1711 if our_proxy
== l
[i
]:
1712 proxy_combobox
.set_active(i
)
1714 def init_account(self
):
1715 if not self
.current_account
:
1716 self
.notebook
.set_current_page(0)
1718 if gajim
.config
.get_per('accounts', self
.current_account
, 'is_zeroconf'):
1719 self
.ignore_events
= True
1720 self
.init_zeroconf_account()
1721 self
.ignore_events
= False
1722 self
.notebook
.set_current_page(2)
1724 self
.ignore_events
= True
1725 self
.init_normal_account()
1726 self
.ignore_events
= False
1727 self
.notebook
.set_current_page(1)
1729 def init_zeroconf_account(self
):
1730 active
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1732 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_active(active
)
1733 if not gajim
.HAVE_ZEROCONF
:
1734 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_sensitive(
1736 self
.xml
.get_object('zeroconf_notebook').set_sensitive(active
)
1738 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1740 self
.xml
.get_object('autoconnect_checkbutton2').set_active(st
)
1742 list_no_log_for
= gajim
.config
.get_per('accounts',
1743 gajim
.ZEROCONF_ACC_NAME
, 'no_log_for').split()
1744 if gajim
.ZEROCONF_ACC_NAME
in list_no_log_for
:
1745 self
.xml
.get_object('log_history_checkbutton2').set_active(0)
1747 self
.xml
.get_object('log_history_checkbutton2').set_active(1)
1749 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1750 'sync_with_global_status')
1751 self
.xml
.get_object('sync_with_global_status_checkbutton2').set_active(st
)
1753 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1755 self
.xml
.get_object('custom_port_checkbutton2').set_active(st
)
1756 self
.xml
.get_object('custom_port_entry2').set_sensitive(st
)
1758 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1761 gajim
.config
.set_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1762 'custom_port', '5298')
1764 self
.xml
.get_object('custom_port_entry2').set_text(str(st
))
1767 gpg_key_label
= self
.xml
.get_object('gpg_key_label2')
1768 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
and \
1769 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].gpg
:
1770 self
.xml
.get_object('gpg_choose_button2').set_sensitive(True)
1771 self
.init_account_gpg()
1773 gpg_key_label
.set_text(_('OpenPGP is not usable on this computer'))
1774 self
.xml
.get_object('gpg_choose_button2').set_sensitive(False)
1776 for opt
in ('first_name', 'last_name', 'jabber_id', 'email'):
1777 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1779 self
.xml
.get_object(opt
+ '_entry2').set_text(st
)
1781 def init_account_gpg(self
):
1782 account
= self
.current_account
1783 keyid
= gajim
.config
.get_per('accounts', account
, 'keyid')
1784 keyname
= gajim
.config
.get_per('accounts', account
, 'keyname')
1785 use_gpg_agent
= gajim
.config
.get('use_gpg_agent')
1787 if account
== gajim
.ZEROCONF_ACC_NAME
:
1788 widget_name_add
= '2'
1790 widget_name_add
= '1'
1792 gpg_key_label
= self
.xml
.get_object('gpg_key_label' + widget_name_add
)
1793 gpg_name_label
= self
.xml
.get_object('gpg_name_label' + widget_name_add
)
1794 use_gpg_agent_checkbutton
= self
.xml
.get_object(
1795 'use_gpg_agent_checkbutton' + widget_name_add
)
1798 use_gpg_agent_checkbutton
.set_sensitive(False)
1799 gpg_key_label
.set_text(_('No key selected'))
1800 gpg_name_label
.set_text('')
1803 gpg_key_label
.set_text(keyid
)
1804 gpg_name_label
.set_text(keyname
)
1805 use_gpg_agent_checkbutton
.set_sensitive(True)
1806 use_gpg_agent_checkbutton
.set_active(use_gpg_agent
)
1808 def draw_normal_jid(self
):
1809 account
= self
.current_account
1810 self
.ignore_events
= True
1811 active
= gajim
.config
.get_per('accounts', account
, 'active')
1812 self
.xml
.get_object('enable_checkbutton1').set_active(active
)
1813 self
.xml
.get_object('normal_notebook1').set_sensitive(active
)
1814 if gajim
.config
.get_per('accounts', account
, 'anonymous_auth'):
1815 self
.xml
.get_object('anonymous_checkbutton1').set_active(True)
1816 self
.xml
.get_object('jid_label1').set_text(_('Server:'))
1817 save_password
= self
.xml
.get_object('save_password_checkbutton1')
1818 save_password
.set_active(False)
1819 save_password
.set_sensitive(False)
1820 password_entry
= self
.xml
.get_object('password_entry1')
1821 password_entry
.set_text('')
1822 password_entry
.set_sensitive(False)
1823 jid
= gajim
.config
.get_per('accounts', account
, 'hostname')
1825 self
.xml
.get_object('anonymous_checkbutton1').set_active(False)
1826 self
.xml
.get_object('jid_label1').set_text(_('Jabber ID:'))
1827 savepass
= gajim
.config
.get_per('accounts', account
, 'savepass')
1828 save_password
= self
.xml
.get_object('save_password_checkbutton1')
1829 save_password
.set_sensitive(True)
1830 save_password
.set_active(savepass
)
1831 password_entry
= self
.xml
.get_object('password_entry1')
1833 passstr
= passwords
.get_password(account
) or ''
1834 password_entry
.set_sensitive(True)
1837 password_entry
.set_sensitive(False)
1838 password_entry
.set_text(passstr
)
1840 jid
= gajim
.config
.get_per('accounts', account
, 'name') \
1841 + '@' + gajim
.config
.get_per('accounts', account
, 'hostname')
1842 self
.xml
.get_object('jid_entry1').set_text(jid
)
1843 self
.ignore_events
= False
1845 def init_normal_account(self
):
1846 account
= self
.current_account
1848 self
.draw_normal_jid()
1849 self
.xml
.get_object('resource_entry1').set_text(gajim
.config
.get_per(
1850 'accounts', account
, 'resource'))
1852 client_cert
= gajim
.config
.get_per('accounts', account
, 'client_cert')
1853 self
.xml
.get_object('cert_entry1').set_text(client_cert
)
1854 client_cert_encrypted
= gajim
.config
.get_per('accounts', account
,
1855 'client_cert_encrypted')
1856 self
.xml
.get_object('client_cert_encrypted_checkbutton1').\
1857 set_active(client_cert_encrypted
)
1859 self
.xml
.get_object('adjust_priority_with_status_checkbutton1').\
1860 set_active(gajim
.config
.get_per('accounts', account
,
1861 'adjust_priority_with_status'))
1862 spinbutton
= self
.xml
.get_object('priority_spinbutton1')
1863 if gajim
.config
.get('enable_negative_priority'):
1864 spinbutton
.set_range(-128, 127)
1866 spinbutton
.set_range(0, 127)
1867 spinbutton
.set_value(gajim
.config
.get_per('accounts', account
,
1871 use_env_http_proxy
= gajim
.config
.get_per('accounts', account
,
1872 'use_env_http_proxy')
1873 self
.xml
.get_object('use_env_http_proxy_checkbutton1').set_active(
1875 self
.xml
.get_object('proxy_hbox1').set_sensitive(not use_env_http_proxy
)
1877 warn_when_insecure_ssl
= gajim
.config
.get_per('accounts', account
,
1878 'warn_when_insecure_ssl_connection')
1879 self
.xml
.get_object('warn_when_insecure_connection_checkbutton1').\
1880 set_active(warn_when_insecure_ssl
)
1882 self
.xml
.get_object('send_keepalive_checkbutton1').set_active(
1883 gajim
.config
.get_per('accounts', account
, 'keep_alives_enabled'))
1885 use_custom_host
= gajim
.config
.get_per('accounts', account
,
1887 self
.xml
.get_object('custom_host_port_checkbutton1').set_active(
1889 custom_host
= gajim
.config
.get_per('accounts', account
, 'custom_host')
1891 custom_host
= gajim
.config
.get_per('accounts', account
, 'hostname')
1892 gajim
.config
.set_per('accounts', account
, 'custom_host', custom_host
)
1893 self
.xml
.get_object('custom_host_entry1').set_text(custom_host
)
1894 custom_port
= gajim
.config
.get_per('accounts', account
, 'custom_port')
1897 gajim
.config
.set_per('accounts', account
, 'custom_port', custom_port
)
1898 self
.xml
.get_object('custom_port_entry1').set_text(unicode(custom_port
))
1901 gpg_key_label
= self
.xml
.get_object('gpg_key_label1')
1903 self
.xml
.get_object('gpg_choose_button1').set_sensitive(True)
1904 self
.init_account_gpg()
1906 gpg_key_label
.set_text(_('OpenPGP is not usable on this computer'))
1907 self
.xml
.get_object('gpg_choose_button1').set_sensitive(False)
1910 self
.xml
.get_object('autoconnect_checkbutton1').set_active(gajim
.config
.\
1911 get_per('accounts', account
, 'autoconnect'))
1912 self
.xml
.get_object('autoreconnect_checkbutton1').set_active(gajim
.
1913 config
.get_per('accounts', account
, 'autoreconnect'))
1915 list_no_log_for
= gajim
.config
.get_per('accounts', account
,
1916 'no_log_for').split()
1917 if account
in list_no_log_for
:
1918 self
.xml
.get_object('log_history_checkbutton1').set_active(False)
1920 self
.xml
.get_object('log_history_checkbutton1').set_active(True)
1922 self
.xml
.get_object('sync_with_global_status_checkbutton1').set_active(
1923 gajim
.config
.get_per('accounts', account
, 'sync_with_global_status'))
1924 self
.xml
.get_object('use_ft_proxies_checkbutton1').set_active(
1925 gajim
.config
.get_per('accounts', account
, 'use_ft_proxies'))
1927 def on_add_button_clicked(self
, widget
):
1929 When add button is clicked: open an account information window
1931 if 'account_creation_wizard' in gajim
.interface
.instances
:
1932 gajim
.interface
.instances
['account_creation_wizard'].window
.present()
1934 gajim
.interface
.instances
['account_creation_wizard'] = \
1935 AccountCreationWizardWindow()
1937 def on_remove_button_clicked(self
, widget
):
1939 When delete button is clicked: Remove an account from the listStore and
1940 from the config file
1942 if not self
.current_account
:
1944 account
= self
.current_account
1945 if len(gajim
.events
.get_events(account
)):
1946 dialogs
.ErrorDialog(_('Unread events'),
1947 _('Read all pending events before removing this account.'))
1950 if gajim
.config
.get_per('accounts', account
, 'is_zeroconf'):
1951 # Should never happen as button is insensitive
1955 if gajim
.interface
.msg_win_mgr
.get_controls(acct
=account
):
1957 elif account
in gajim
.interface
.instances
:
1958 for key
in gajim
.interface
.instances
[account
]:
1959 if gajim
.interface
.instances
[account
][key
] and key
!= \
1963 # Detect if we have opened windows for this account
1964 def remove(account
):
1965 if account
in gajim
.interface
.instances
and \
1966 'remove_account' in gajim
.interface
.instances
[account
]:
1967 gajim
.interface
.instances
[account
]['remove_account'].window
.\
1970 if not account
in gajim
.interface
.instances
:
1971 gajim
.interface
.instances
[account
] = {}
1972 gajim
.interface
.instances
[account
]['remove_account'] = \
1973 RemoveAccountWindow(account
)
1975 dialogs
.ConfirmationDialog(
1976 _('You have opened chat in account %s') % account
,
1977 _('All chat and groupchat windows will be closed. Do you want to '
1979 on_response_ok
= (remove
, account
))
1983 def on_rename_button_clicked(self
, widget
):
1984 if not self
.current_account
:
1986 active
= gajim
.config
.get_per('accounts', self
.current_account
, 'active')
1987 if active
and gajim
.connections
[self
.current_account
].connected
!= 0:
1988 dialogs
.ErrorDialog(
1989 _('You are currently connected to the server'),
1990 _('To change the account name, you must be disconnected.'))
1992 if len(gajim
.events
.get_events(self
.current_account
)):
1993 dialogs
.ErrorDialog(_('Unread events'),
1994 _('To change the account name, you must read all pending '
1998 def on_renamed(new_name
, old_name
):
1999 if new_name
in gajim
.connections
:
2000 dialogs
.ErrorDialog(_('Account Name Already Used'),
2001 _('This name is already used by another of your accounts. '
2002 'Please choose another name.'))
2004 if (new_name
== ''):
2005 dialogs
.ErrorDialog(_('Invalid account name'),
2006 _('Account name cannot be empty.'))
2008 if new_name
.find(' ') != -1:
2009 dialogs
.ErrorDialog(_('Invalid account name'),
2010 _('Account name cannot contain spaces.'))
2014 gajim
.interface
.instances
[new_name
] = gajim
.interface
.instances
[
2016 gajim
.interface
.minimized_controls
[new_name
] = \
2017 gajim
.interface
.minimized_controls
[old_name
]
2018 gajim
.nicks
[new_name
] = gajim
.nicks
[old_name
]
2019 gajim
.block_signed_in_notifications
[new_name
] = \
2020 gajim
.block_signed_in_notifications
[old_name
]
2021 gajim
.groups
[new_name
] = gajim
.groups
[old_name
]
2022 gajim
.gc_connected
[new_name
] = gajim
.gc_connected
[old_name
]
2023 gajim
.automatic_rooms
[new_name
] = gajim
.automatic_rooms
[old_name
]
2024 gajim
.newly_added
[new_name
] = gajim
.newly_added
[old_name
]
2025 gajim
.to_be_removed
[new_name
] = gajim
.to_be_removed
[old_name
]
2026 gajim
.sleeper_state
[new_name
] = gajim
.sleeper_state
[old_name
]
2027 gajim
.encrypted_chats
[new_name
] = gajim
.encrypted_chats
[old_name
]
2028 gajim
.last_message_time
[new_name
] = \
2029 gajim
.last_message_time
[old_name
]
2030 gajim
.status_before_autoaway
[new_name
] = \
2031 gajim
.status_before_autoaway
[old_name
]
2032 gajim
.transport_avatar
[new_name
] = gajim
.transport_avatar
[old_name
]
2033 gajim
.gajim_optional_features
[new_name
] = \
2034 gajim
.gajim_optional_features
[old_name
]
2035 gajim
.caps_hash
[new_name
] = gajim
.caps_hash
[old_name
]
2037 gajim
.contacts
.change_account_name(old_name
, new_name
)
2038 gajim
.events
.change_account_name(old_name
, new_name
)
2040 # change account variable for chat / gc controls
2041 gajim
.interface
.msg_win_mgr
.change_account_name(old_name
, new_name
)
2042 # upgrade account variable in opened windows
2043 for kind
in ('infos', 'disco', 'gc_config', 'search',
2044 'online_dialog', 'sub_request'):
2045 for j
in gajim
.interface
.instances
[new_name
][kind
]:
2046 gajim
.interface
.instances
[new_name
][kind
][j
].account
= \
2049 # ServiceCache object keep old property account
2050 if hasattr(gajim
.connections
[old_name
], 'services_cache'):
2051 gajim
.connections
[old_name
].services_cache
.account
= new_name
2052 del gajim
.interface
.instances
[old_name
]
2053 del gajim
.interface
.minimized_controls
[old_name
]
2054 del gajim
.nicks
[old_name
]
2055 del gajim
.block_signed_in_notifications
[old_name
]
2056 del gajim
.groups
[old_name
]
2057 del gajim
.gc_connected
[old_name
]
2058 del gajim
.automatic_rooms
[old_name
]
2059 del gajim
.newly_added
[old_name
]
2060 del gajim
.to_be_removed
[old_name
]
2061 del gajim
.sleeper_state
[old_name
]
2062 del gajim
.encrypted_chats
[old_name
]
2063 del gajim
.last_message_time
[old_name
]
2064 del gajim
.status_before_autoaway
[old_name
]
2065 del gajim
.transport_avatar
[old_name
]
2066 del gajim
.gajim_optional_features
[old_name
]
2067 del gajim
.caps_hash
[old_name
]
2068 gajim
.connections
[old_name
].name
= new_name
2069 gajim
.connections
[old_name
].pep_change_account_name(new_name
)
2070 gajim
.connections
[old_name
].caps_change_account_name(new_name
)
2071 gajim
.connections
[new_name
] = gajim
.connections
[old_name
]
2072 del gajim
.connections
[old_name
]
2073 gajim
.config
.add_per('accounts', new_name
)
2074 old_config
= gajim
.config
.get_per('accounts', old_name
)
2075 for opt
in old_config
:
2076 gajim
.config
.set_per('accounts', new_name
, opt
, old_config
[opt
][1])
2077 gajim
.config
.del_per('accounts', old_name
)
2078 if self
.current_account
== old_name
:
2079 self
.current_account
= new_name
2080 if old_name
== gajim
.ZEROCONF_ACC_NAME
:
2081 gajim
.ZEROCONF_ACC_NAME
= new_name
2083 gajim
.interface
.roster
.setup_and_draw_roster()
2084 self
.init_accounts()
2085 self
.select_account(new_name
)
2087 title
= _('Rename Account')
2088 message
= _('Enter a new name for account %s') % self
.current_account
2089 old_text
= self
.current_account
2090 dialogs
.InputDialog(title
, message
, old_text
, is_modal
=False,
2091 ok_handler
=(on_renamed
, self
.current_account
))
2093 def option_changed(self
, option
, value
):
2094 return gajim
.config
.get_per('accounts', self
.current_account
, option
) != \
2097 def on_jid_entry1_focus_out_event(self
, widget
, event
):
2098 if self
.ignore_events
:
2100 jid
= widget
.get_text()
2101 # check if jid is conform to RFC and stringprep it
2103 jid
= helpers
.parse_jid(jid
)
2104 except helpers
.InvalidFormat
, s
:
2105 if not widget
.is_focus():
2106 pritext
= _('Invalid Jabber ID')
2107 dialogs
.ErrorDialog(pritext
, str(s
))
2108 gobject
.idle_add(lambda: widget
.grab_focus())
2111 jid_splited
= jid
.split('@', 1)
2112 if len(jid_splited
) != 2 and not gajim
.config
.get_per('accounts',
2113 self
.current_account
, 'anonymous_auth'):
2114 if not widget
.is_focus():
2115 pritext
= _('Invalid Jabber ID')
2116 sectext
= _('A Jabber ID must be in the form "user@servername".')
2117 dialogs
.ErrorDialog(pritext
, sectext
)
2118 gobject
.idle_add(lambda: widget
.grab_focus())
2122 if gajim
.config
.get_per('accounts', self
.current_account
,
2124 gajim
.config
.set_per('accounts', self
.current_account
, 'hostname',
2126 if self
.option_changed('hostname', jid_splited
[0]):
2127 self
.need_relogin
= True
2129 if self
.option_changed('name', jid_splited
[0]) or \
2130 self
.option_changed('hostname', jid_splited
[1]):
2131 self
.need_relogin
= True
2133 gajim
.config
.set_per('accounts', self
.current_account
, 'name',
2135 gajim
.config
.set_per('accounts', self
.current_account
, 'hostname',
2138 def on_cert_entry1_focus_out_event(self
, widget
, event
):
2139 if self
.ignore_events
:
2141 client_cert
= widget
.get_text()
2142 if self
.option_changed('client_cert', client_cert
):
2143 self
.need_relogin
= True
2144 gajim
.config
.set_per('accounts', self
.current_account
, 'client_cert',
2147 def on_anonymous_checkbutton1_toggled(self
, widget
):
2148 if self
.ignore_events
:
2150 active
= widget
.get_active()
2151 gajim
.config
.set_per('accounts', self
.current_account
, 'anonymous_auth',
2153 self
.draw_normal_jid()
2155 def on_password_entry1_changed(self
, widget
):
2156 if self
.ignore_events
:
2158 passwords
.save_password(self
.current_account
, widget
.get_text().decode(
2161 def on_save_password_checkbutton1_toggled(self
, widget
):
2162 if self
.ignore_events
:
2164 active
= widget
.get_active()
2165 password_entry
= self
.xml
.get_object('password_entry1')
2166 password_entry
.set_sensitive(active
)
2167 gajim
.config
.set_per('accounts', self
.current_account
, 'savepass', active
)
2169 password
= password_entry
.get_text()
2170 passwords
.save_password(self
.current_account
, password
)
2172 passwords
.save_password(self
.current_account
, '')
2174 def on_resource_entry1_focus_out_event(self
, widget
, event
):
2175 if self
.ignore_events
:
2177 resource
= self
.xml
.get_object('resource_entry1').get_text().decode(
2180 resource
= helpers
.parse_resource(resource
)
2181 except helpers
.InvalidFormat
, s
:
2182 if not widget
.is_focus():
2183 pritext
= _('Invalid Jabber ID')
2184 dialogs
.ErrorDialog(pritext
, str(s
))
2185 gobject
.idle_add(lambda: widget
.grab_focus())
2188 if self
.option_changed('resource', resource
):
2189 self
.need_relogin
= True
2191 gajim
.config
.set_per('accounts', self
.current_account
, 'resource',
2194 def on_adjust_priority_with_status_checkbutton1_toggled(self
, widget
):
2195 self
.xml
.get_object('priority_spinbutton1').set_sensitive(
2196 not widget
.get_active())
2197 self
.on_checkbutton_toggled(widget
, 'adjust_priority_with_status',
2198 account
= self
.current_account
)
2200 def on_priority_spinbutton1_value_changed(self
, widget
):
2201 prio
= widget
.get_value_as_int()
2203 if self
.option_changed('priority', prio
):
2204 self
.resend_presence
= True
2206 gajim
.config
.set_per('accounts', self
.current_account
, 'priority', prio
)
2208 def on_synchronise_contacts_button1_clicked(self
, widget
):
2210 dialogs
.SynchroniseSelectAccountDialog(self
.current_account
)
2211 except GajimGeneralException
:
2212 # If we showed ErrorDialog, there will not be dialog instance
2215 def on_change_password_button1_clicked(self
, widget
):
2216 def on_changed(new_password
):
2217 if new_password
is not None:
2218 gajim
.connections
[self
.current_account
].change_password(
2220 if self
.xml
.get_object('save_password_checkbutton1').get_active():
2221 self
.xml
.get_object('password_entry1').set_text(new_password
)
2224 dialogs
.ChangePasswordDialog(self
.current_account
, on_changed
)
2225 except GajimGeneralException
:
2226 # if we showed ErrorDialog, there will not be dialog instance
2229 def on_client_cert_encrypted_checkbutton1_toggled(self
, widget
):
2230 if self
.ignore_events
:
2232 self
.on_checkbutton_toggled(widget
, 'client_cert_encrypted',
2233 account
=self
.current_account
)
2235 def on_autoconnect_checkbutton_toggled(self
, widget
):
2236 if self
.ignore_events
:
2238 self
.on_checkbutton_toggled(widget
, 'autoconnect',
2239 account
=self
.current_account
)
2241 def on_autoreconnect_checkbutton_toggled(self
, widget
):
2242 if self
.ignore_events
:
2244 self
.on_checkbutton_toggled(widget
, 'autoreconnect',
2245 account
=self
.current_account
)
2247 def on_log_history_checkbutton_toggled(self
, widget
):
2248 if self
.ignore_events
:
2250 list_no_log_for
= gajim
.config
.get_per('accounts', self
.current_account
,
2251 'no_log_for').split()
2252 if self
.current_account
in list_no_log_for
:
2253 list_no_log_for
.remove(self
.current_account
)
2255 if not widget
.get_active():
2256 list_no_log_for
.append(self
.current_account
)
2257 gajim
.config
.set_per('accounts', self
.current_account
, 'no_log_for',
2258 ' '.join(list_no_log_for
))
2260 def on_sync_with_global_status_checkbutton_toggled(self
, widget
):
2261 if self
.ignore_events
:
2263 self
.on_checkbutton_toggled(widget
, 'sync_with_global_status',
2264 account
=self
.current_account
)
2265 gajim
.interface
.roster
.update_status_combobox()
2267 def on_use_ft_proxies_checkbutton1_toggled(self
, widget
):
2268 if self
.ignore_events
:
2270 self
.on_checkbutton_toggled(widget
, 'use_ft_proxies',
2271 account
=self
.current_account
)
2273 def on_use_env_http_proxy_checkbutton1_toggled(self
, widget
):
2274 if self
.ignore_events
:
2276 self
.on_checkbutton_toggled(widget
, 'use_env_http_proxy',
2277 account
=self
.current_account
)
2278 hbox
= self
.xml
.get_object('proxy_hbox1')
2279 hbox
.set_sensitive(not widget
.get_active())
2281 def on_proxies_combobox1_changed(self
, widget
):
2282 active
= widget
.get_active()
2283 proxy
= widget
.get_model()[active
][0].decode('utf-8')
2284 if proxy
== _('None'):
2287 if self
.option_changed('proxy', proxy
):
2288 self
.need_relogin
= True
2290 gajim
.config
.set_per('accounts', self
.current_account
, 'proxy', proxy
)
2292 def on_manage_proxies_button1_clicked(self
, widget
):
2293 if 'manage_proxies' in gajim
.interface
.instances
:
2294 gajim
.interface
.instances
['manage_proxies'].window
.present()
2296 gajim
.interface
.instances
['manage_proxies'] = ManageProxiesWindow()
2298 def on_warn_when_insecure_connection_checkbutton1_toggled(self
, widget
):
2299 if self
.ignore_events
:
2302 self
.on_checkbutton_toggled(widget
, 'warn_when_insecure_ssl_connection',
2303 account
=self
.current_account
)
2305 def on_send_keepalive_checkbutton1_toggled(self
, widget
):
2306 if self
.ignore_events
:
2308 self
.on_checkbutton_toggled(widget
, 'keep_alives_enabled',
2309 account
=self
.current_account
)
2310 gajim
.config
.set_per('accounts', self
.current_account
,
2311 'ping_alives_enabled', widget
.get_active())
2313 def on_custom_host_port_checkbutton1_toggled(self
, widget
):
2314 if self
.option_changed('use_custom_host', widget
.get_active()):
2315 self
.need_relogin
= True
2317 self
.on_checkbutton_toggled(widget
, 'use_custom_host',
2318 account
=self
.current_account
)
2319 active
= widget
.get_active()
2320 self
.xml
.get_object('custom_host_port_hbox1').set_sensitive(active
)
2322 def on_custom_host_entry1_changed(self
, widget
):
2323 if self
.ignore_events
:
2325 host
= widget
.get_text().decode('utf-8')
2326 if self
.option_changed('custom_host', host
):
2327 self
.need_relogin
= True
2328 gajim
.config
.set_per('accounts', self
.current_account
, 'custom_host',
2331 def on_custom_port_entry_focus_out_event(self
, widget
, event
):
2332 if self
.ignore_events
:
2334 custom_port
= widget
.get_text()
2336 custom_port
= int(custom_port
)
2338 if not widget
.is_focus():
2339 dialogs
.ErrorDialog(_('Invalid entry'),
2340 _('Custom port must be a port number.'))
2341 gobject
.idle_add(lambda: widget
.grab_focus())
2343 if self
.option_changed('custom_port', custom_port
):
2344 self
.need_relogin
= True
2345 gajim
.config
.set_per('accounts', self
.current_account
, 'custom_port',
2348 def on_gpg_choose_button_clicked(self
, widget
, data
= None):
2349 if self
.current_account
in gajim
.connections
and \
2350 gajim
.connections
[self
.current_account
].gpg
:
2351 secret_keys
= gajim
.connections
[self
.current_account
].\
2352 ask_gpg_secrete_keys()
2354 # self.current_account is None and/or gajim.connections is {}
2357 secret_keys
= gpg
.GnuPG().get_secret_keys()
2361 dialogs
.ErrorDialog(_('Failed to get secret keys'),
2362 _('There is no OpenPGP secret key available.'))
2363 secret_keys
[_('None')] = _('None')
2365 def on_key_selected(keyID
):
2368 if self
.current_account
== gajim
.ZEROCONF_ACC_NAME
:
2369 wiget_name_ext
= '2'
2371 wiget_name_ext
= '1'
2372 gpg_key_label
= self
.xml
.get_object('gpg_key_label' + wiget_name_ext
)
2373 gpg_name_label
= self
.xml
.get_object('gpg_name_label' + wiget_name_ext
)
2374 use_gpg_agent_checkbutton
= self
.xml
.get_object(
2375 'use_gpg_agent_checkbutton' + wiget_name_ext
)
2376 if keyID
[0] == _('None'):
2377 gpg_key_label
.set_text(_('No key selected'))
2378 gpg_name_label
.set_text('')
2379 use_gpg_agent_checkbutton
.set_sensitive(False)
2380 if self
.option_changed('keyid', ''):
2381 self
.need_relogin
= True
2382 gajim
.config
.set_per('accounts', self
.current_account
, 'keyname',
2384 gajim
.config
.set_per('accounts', self
.current_account
, 'keyid', '')
2386 gpg_key_label
.set_text(keyID
[0])
2387 gpg_name_label
.set_text(keyID
[1])
2388 use_gpg_agent_checkbutton
.set_sensitive(True)
2389 if self
.option_changed('keyid', keyID
[0]):
2390 self
.need_relogin
= True
2391 gajim
.config
.set_per('accounts', self
.current_account
, 'keyname',
2393 gajim
.config
.set_per('accounts', self
.current_account
, 'keyid',
2396 dialogs
.ChooseGPGKeyDialog(_('OpenPGP Key Selection'),
2397 _('Choose your OpenPGP key'), secret_keys
, on_key_selected
)
2399 def on_use_gpg_agent_checkbutton_toggled(self
, widget
):
2400 self
.on_checkbutton_toggled(widget
, 'use_gpg_agent')
2402 def on_edit_details_button1_clicked(self
, widget
):
2403 if self
.current_account
not in gajim
.interface
.instances
:
2404 dialogs
.ErrorDialog(_('No such account available'),
2405 _('You must create your account before editing your personal '
2409 # show error dialog if account is newly created (not in gajim.connections)
2410 if self
.current_account
not in gajim
.connections
or \
2411 gajim
.connections
[self
.current_account
].connected
< 2:
2412 dialogs
.ErrorDialog(_('You are not connected to the server'),
2413 _('Without a connection, you can not edit your personal information.'))
2416 if not gajim
.connections
[self
.current_account
].vcard_supported
:
2417 dialogs
.ErrorDialog(_("Your server doesn't support Vcard"),
2418 _("Your server can't save your personal information."))
2421 gajim
.interface
.edit_own_details(self
.current_account
)
2423 def on_checkbutton_toggled(self
, widget
, config_name
,
2424 change_sensitivity_widgets
= None, account
= None):
2426 gajim
.config
.set_per('accounts', account
, config_name
,
2427 widget
.get_active())
2429 gajim
.config
.set(config_name
, widget
.get_active())
2430 if change_sensitivity_widgets
:
2431 for w
in change_sensitivity_widgets
:
2432 w
.set_sensitive(widget
.get_active())
2433 gajim
.interface
.save_config()
2435 def on_merge_checkbutton_toggled(self
, widget
):
2436 self
.on_checkbutton_toggled(widget
, 'mergeaccounts')
2437 if len(gajim
.connections
) >= 2: # Do not merge accounts if only one active
2438 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2440 gajim
.interface
.roster
.regroup
= False
2441 gajim
.interface
.roster
.setup_and_draw_roster()
2443 def _disable_account(self
, account
):
2444 gajim
.interface
.roster
.close_all(account
)
2445 if account
== gajim
.ZEROCONF_ACC_NAME
:
2446 gajim
.connections
[account
].disable_account()
2447 del gajim
.connections
[account
]
2448 gajim
.interface
.save_config()
2449 del gajim
.interface
.instances
[account
]
2450 del gajim
.interface
.minimized_controls
[account
]
2451 del gajim
.nicks
[account
]
2452 del gajim
.block_signed_in_notifications
[account
]
2453 del gajim
.groups
[account
]
2454 gajim
.contacts
.remove_account(account
)
2455 del gajim
.gc_connected
[account
]
2456 del gajim
.automatic_rooms
[account
]
2457 del gajim
.to_be_removed
[account
]
2458 del gajim
.newly_added
[account
]
2459 del gajim
.sleeper_state
[account
]
2460 del gajim
.encrypted_chats
[account
]
2461 del gajim
.last_message_time
[account
]
2462 del gajim
.status_before_autoaway
[account
]
2463 del gajim
.transport_avatar
[account
]
2464 del gajim
.gajim_optional_features
[account
]
2465 del gajim
.caps_hash
[account
]
2466 if len(gajim
.connections
) >= 2:
2467 # Do not merge accounts if only one exists
2468 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2470 gajim
.interface
.roster
.regroup
= False
2471 gajim
.interface
.roster
.setup_and_draw_roster()
2472 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
2474 def _enable_account(self
, account
):
2475 if account
== gajim
.ZEROCONF_ACC_NAME
:
2476 gajim
.connections
[account
] = connection_zeroconf
.ConnectionZeroconf(
2478 if gajim
.connections
[account
].gpg
:
2479 self
.xml
.get_object('gpg_choose_button2').set_sensitive(True)
2481 gajim
.connections
[account
] = common
.connection
.Connection(account
)
2482 if gajim
.connections
[account
].gpg
:
2483 self
.xml
.get_object('gpg_choose_button1').set_sensitive(True)
2484 self
.init_account_gpg()
2486 gajim
.interface
.instances
[account
] = {'infos': {},
2487 'disco': {}, 'gc_config': {}, 'search': {}, 'online_dialog': {},
2489 gajim
.interface
.minimized_controls
[account
] = {}
2490 gajim
.connections
[account
].connected
= 0
2491 gajim
.groups
[account
] = {}
2492 gajim
.contacts
.add_account(account
)
2493 gajim
.gc_connected
[account
] = {}
2494 gajim
.automatic_rooms
[account
] = {}
2495 gajim
.newly_added
[account
] = []
2496 gajim
.to_be_removed
[account
] = []
2497 if account
== gajim
.ZEROCONF_ACC_NAME
:
2498 gajim
.nicks
[account
] = gajim
.ZEROCONF_ACC_NAME
2500 gajim
.nicks
[account
] = gajim
.config
.get_per('accounts', account
,
2502 gajim
.block_signed_in_notifications
[account
] = True
2503 gajim
.sleeper_state
[account
] = 'off'
2504 gajim
.encrypted_chats
[account
] = []
2505 gajim
.last_message_time
[account
] = {}
2506 gajim
.status_before_autoaway
[account
] = ''
2507 gajim
.transport_avatar
[account
] = {}
2508 gajim
.gajim_optional_features
[account
] = []
2509 gajim
.caps_hash
[account
] = ''
2511 if len(gajim
.connections
) >= 2:
2512 # Do not merge accounts if only one exists
2513 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2515 gajim
.interface
.roster
.regroup
= False
2516 gajim
.interface
.roster
.setup_and_draw_roster()
2517 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
2518 gajim
.interface
.save_config()
2520 def on_enable_zeroconf_checkbutton2_toggled(self
, widget
):
2521 # don't do anything if there is an account with the local name but is a
2523 if self
.ignore_events
:
2525 if self
.current_account
in gajim
.connections
and \
2526 gajim
.connections
[self
.current_account
].connected
> 0:
2527 self
.ignore_events
= True
2528 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_active(True)
2529 self
.ignore_events
= False
2530 dialogs
.ErrorDialog(
2531 _('You are currently connected to the server'),
2532 _('To disable the account, you must be disconnected.'))
2534 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
and not \
2535 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].is_zeroconf
:
2536 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].dispatch('ERROR',
2537 (_('Account Local already exists.'),
2538 _('Please rename or remove it before enabling link-local messaging'
2542 if gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
, 'active') \
2543 and not widget
.get_active():
2544 self
.xml
.get_object('zeroconf_notebook').set_sensitive(False)
2546 self
._disable
_account
(gajim
.ZEROCONF_ACC_NAME
)
2548 elif not gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
2549 'active') and widget
.get_active():
2550 self
.xml
.get_object('zeroconf_notebook').set_sensitive(True)
2551 # enable (will create new account if not present)
2552 self
._enable
_account
(gajim
.ZEROCONF_ACC_NAME
)
2554 self
.on_checkbutton_toggled(widget
, 'active',
2555 account
=gajim
.ZEROCONF_ACC_NAME
)
2557 def on_enable_checkbutton1_toggled(self
, widget
):
2558 if self
.ignore_events
:
2560 if self
.current_account
in gajim
.connections
and \
2561 gajim
.connections
[self
.current_account
].connected
> 0:
2562 # connecting or connected
2563 self
.ignore_events
= True
2564 self
.xml
.get_object('enable_checkbutton1').set_active(True)
2565 self
.ignore_events
= False
2566 dialogs
.ErrorDialog(
2567 _('You are currently connected to the server'),
2568 _('To disable the account, you must be disconnected.'))
2570 # add/remove account in roster and all variables
2571 if widget
.get_active():
2573 self
._enable
_account
(self
.current_account
)
2576 self
._disable
_account
(self
.current_account
)
2577 self
.on_checkbutton_toggled(widget
, 'active',
2578 account
=self
.current_account
, change_sensitivity_widgets
=[
2579 self
.xml
.get_object('normal_notebook1')])
2581 def on_custom_port_checkbutton2_toggled(self
, widget
):
2582 self
.xml
.get_object('custom_port_entry2').set_sensitive(
2583 widget
.get_active())
2584 self
.on_checkbutton_toggled(widget
, 'use_custom_host',
2585 account
= self
.current_account
)
2586 if not widget
.get_active():
2587 self
.xml
.get_object('custom_port_entry2').set_text('5298')
2589 def on_first_name_entry2_changed(self
, widget
):
2590 if self
.ignore_events
:
2592 name
= widget
.get_text().decode('utf-8')
2593 if self
.option_changed('zeroconf_first_name', name
):
2594 self
.need_relogin
= True
2595 gajim
.config
.set_per('accounts', self
.current_account
,
2596 'zeroconf_first_name', name
)
2598 def on_last_name_entry2_changed(self
, widget
):
2599 if self
.ignore_events
:
2601 name
= widget
.get_text().decode('utf-8')
2602 if self
.option_changed('zeroconf_last_name', name
):
2603 self
.need_relogin
= True
2604 gajim
.config
.set_per('accounts', self
.current_account
,
2605 'zeroconf_last_name', name
)
2607 def on_jabber_id_entry2_changed(self
, widget
):
2608 if self
.ignore_events
:
2610 id_
= widget
.get_text().decode('utf-8')
2611 if self
.option_changed('zeroconf_jabber_id', id_
):
2612 self
.need_relogin
= True
2613 gajim
.config
.set_per('accounts', self
.current_account
,
2614 'zeroconf_jabber_id', id_
)
2616 def on_email_entry2_changed(self
, widget
):
2617 if self
.ignore_events
:
2619 email
= widget
.get_text().decode('utf-8')
2620 if self
.option_changed('zeroconf_email', email
):
2621 self
.need_relogin
= True
2622 gajim
.config
.set_per('accounts', self
.current_account
,
2623 'zeroconf_email', email
)
2625 class FakeDataForm(gtk
.Table
, object):
2627 Class for forms that are in XML format <entry1>value1</entry1> infos in a
2628 table {entry1: value1}
2631 def __init__(self
, infos
):
2632 gtk
.Table
.__init
__(self
)
2637 def _draw_table(self
):
2642 if 'instructions' in self
.infos
:
2644 self
.resize(rows
= nbrow
, columns
= 2)
2645 label
= gtk
.Label(self
.infos
['instructions'])
2646 self
.attach(label
, 0, 2, 0, 1, 0, 0, 0, 0)
2647 for name
in self
.infos
.keys():
2648 if name
in ('key', 'instructions', 'x', 'registered'):
2654 self
.resize(rows
= nbrow
, columns
= 2)
2655 label
= gtk
.Label(name
.capitalize() + ':')
2656 self
.attach(label
, 0, 1, nbrow
- 1, nbrow
, 0, 0, 0, 0)
2658 entry
.set_activates_default(True)
2659 if self
.infos
[name
]:
2660 entry
.set_text(self
.infos
[name
])
2661 if name
== 'password':
2662 entry
.set_visibility(False)
2663 self
.attach(entry
, 1, 2, nbrow
- 1, nbrow
, 0, 0, 0, 0)
2664 self
.entries
[name
] = entry
2668 def get_infos(self
):
2669 for name
in self
.entries
.keys():
2670 self
.infos
[name
] = self
.entries
[name
].get_text().decode('utf-8')
2673 class ServiceRegistrationWindow
:
2675 Class for Service registration window. Window that appears when we want to
2676 subscribe to a service if is_form we use dataforms_widget else we use
2677 service_registarion_window
2679 def __init__(self
, service
, infos
, account
, is_form
):
2680 self
.service
= service
2681 self
.account
= account
2682 self
.is_form
= is_form
2683 self
.xml
= gtkgui_helpers
.get_gtk_builder('service_registration_window.ui')
2684 self
.window
= self
.xml
.get_object('service_registration_window')
2685 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2687 dataform
= dataforms
.ExtendForm(node
= infos
)
2688 self
.data_form_widget
= dataforms_widget
.DataFormWidget(dataform
)
2689 if self
.data_form_widget
.title
:
2690 self
.window
.set_title('%s - Gajim' % self
.data_form_widget
.title
)
2691 table
= self
.xml
.get_object('table')
2692 table
.attach(self
.data_form_widget
, 0, 2, 0, 1)
2694 if 'registered' in infos
:
2695 self
.window
.set_title(_('Edit %s') % service
)
2697 self
.window
.set_title(_('Register to %s') % service
)
2698 self
.data_form_widget
= FakeDataForm(infos
)
2699 table
= self
.xml
.get_object('table')
2700 table
.attach(self
.data_form_widget
, 0, 2, 0, 1)
2702 self
.xml
.connect_signals(self
)
2703 self
.window
.show_all()
2705 def on_cancel_button_clicked(self
, widget
):
2706 self
.window
.destroy()
2708 def on_ok_button_clicked(self
, widget
):
2709 # send registration info to the core
2711 form
= self
.data_form_widget
.data_form
2712 gajim
.connections
[self
.account
].register_agent(self
.service
,
2713 form
, True) # True is for is_form
2715 infos
= self
.data_form_widget
.get_infos()
2716 if 'instructions' in infos
:
2717 del infos
['instructions']
2718 if 'registered' in infos
:
2719 del infos
['registered']
2720 gajim
.connections
[self
.account
].register_agent(self
.service
, infos
)
2722 self
.window
.destroy()
2724 class GroupchatConfigWindow
:
2726 def __init__(self
, account
, room_jid
, form
=None):
2727 self
.account
= account
2728 self
.room_jid
= room_jid
2730 self
.remove_button
= {}
2731 self
.affiliation_treeview
= {}
2732 self
.start_users_dict
= {} # list at the beginning
2733 self
.affiliation_labels
= {'outcast': _('Ban List'),
2734 'member': _('Member List'), 'owner': _('Owner List'),
2735 'admin':_('Administrator List')}
2737 self
.xml
= gtkgui_helpers
.get_gtk_builder('data_form_window.ui',
2739 self
.window
= self
.xml
.get_object('data_form_window')
2740 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2743 config_vbox
= self
.xml
.get_object('config_vbox')
2744 self
.data_form_widget
= dataforms_widget
.DataFormWidget(self
.form
)
2745 # hide scrollbar of this data_form_widget, we already have in this
2747 sw
= self
.data_form_widget
.xml
.get_object(
2748 'single_form_scrolledwindow')
2749 sw
.set_policy(gtk
.POLICY_NEVER
, gtk
.POLICY_NEVER
)
2751 self
.xml
.get_object('title_label').set_text(self
.form
.title
)
2753 self
.xml
.get_object('title_hseparator').set_no_show_all(True)
2754 self
.xml
.get_object('title_hseparator').hide()
2756 self
.data_form_widget
.show()
2757 config_vbox
.pack_start(self
.data_form_widget
)
2759 self
.xml
.get_object('title_label').set_no_show_all(True)
2760 self
.xml
.get_object('title_label').hide()
2761 self
.xml
.get_object('title_hseparator').set_no_show_all(True)
2762 self
.xml
.get_object('title_hseparator').hide()
2763 self
.xml
.get_object('config_hseparator').set_no_show_all(True)
2764 self
.xml
.get_object('config_hseparator').hide()
2766 # Draw the edit affiliation list things
2767 add_on_vbox
= self
.xml
.get_object('add_on_vbox')
2769 for affiliation
in self
.affiliation_labels
.keys():
2770 self
.start_users_dict
[affiliation
] = {}
2771 hbox
= gtk
.HBox(spacing
=5)
2772 add_on_vbox
.pack_start(hbox
, False)
2774 label
= gtk
.Label(self
.affiliation_labels
[affiliation
])
2775 hbox
.pack_start(label
, False)
2777 bb
= gtk
.HButtonBox()
2778 bb
.set_layout(gtk
.BUTTONBOX_END
)
2781 add_button
= gtk
.Button(stock
=gtk
.STOCK_ADD
)
2782 add_button
.connect('clicked', self
.on_add_button_clicked
,
2784 bb
.pack_start(add_button
)
2785 self
.remove_button
[affiliation
] = gtk
.Button(stock
=gtk
.STOCK_REMOVE
)
2786 self
.remove_button
[affiliation
].set_sensitive(False)
2787 self
.remove_button
[affiliation
].connect('clicked',
2788 self
.on_remove_button_clicked
, affiliation
)
2789 bb
.pack_start(self
.remove_button
[affiliation
])
2791 # jid, reason, nick, role
2792 liststore
= gtk
.ListStore(str, str, str, str)
2793 self
.affiliation_treeview
[affiliation
] = gtk
.TreeView(liststore
)
2794 self
.affiliation_treeview
[affiliation
].get_selection().set_mode(
2795 gtk
.SELECTION_MULTIPLE
)
2796 self
.affiliation_treeview
[affiliation
].connect('cursor-changed',
2797 self
.on_affiliation_treeview_cursor_changed
, affiliation
)
2798 renderer
= gtk
.CellRendererText()
2799 col
= gtk
.TreeViewColumn(_('JID'), renderer
)
2800 col
.add_attribute(renderer
, 'text', 0)
2801 col
.set_resizable(True)
2802 col
.set_sort_column_id(0)
2803 self
.affiliation_treeview
[affiliation
].append_column(col
)
2805 if affiliation
== 'outcast':
2806 renderer
= gtk
.CellRendererText()
2807 renderer
.set_property('editable', True)
2808 renderer
.connect('edited', self
.on_cell_edited
)
2809 col
= gtk
.TreeViewColumn(_('Reason'), renderer
)
2810 col
.add_attribute(renderer
, 'text', 1)
2811 col
.set_resizable(True)
2812 col
.set_sort_column_id(1)
2813 self
.affiliation_treeview
[affiliation
].append_column(col
)
2814 elif affiliation
== 'member':
2815 renderer
= gtk
.CellRendererText()
2816 col
= gtk
.TreeViewColumn(_('Nick'), renderer
)
2817 col
.add_attribute(renderer
, 'text', 2)
2818 col
.set_resizable(True)
2819 col
.set_sort_column_id(2)
2820 self
.affiliation_treeview
[affiliation
].append_column(col
)
2821 renderer
= gtk
.CellRendererText()
2822 col
= gtk
.TreeViewColumn(_('Role'), renderer
)
2823 col
.add_attribute(renderer
, 'text', 3)
2824 col
.set_resizable(True)
2825 col
.set_sort_column_id(3)
2826 self
.affiliation_treeview
[affiliation
].append_column(col
)
2828 sw
= gtk
.ScrolledWindow()
2829 sw
.set_policy(gtk
.POLICY_AUTOMATIC
, gtk
.POLICY_NEVER
)
2830 sw
.add(self
.affiliation_treeview
[affiliation
])
2831 add_on_vbox
.pack_start(sw
)
2832 gajim
.connections
[self
.account
].get_affiliation_list(self
.room_jid
,
2835 self
.xml
.connect_signals(self
)
2836 self
.window
.show_all()
2838 def on_cancel_button_clicked(self
, widget
):
2839 self
.window
.destroy()
2841 def on_cell_edited(self
, cell
, path
, new_text
):
2842 model
= self
.affiliation_treeview
['outcast'].get_model()
2843 new_text
= new_text
.decode('utf-8')
2844 iter_
= model
.get_iter(path
)
2845 model
[iter_
][1] = new_text
2847 def on_add_button_clicked(self
, widget
, affiliation
):
2848 if affiliation
== 'outcast':
2849 title
= _('Banning...')
2850 #You can move '\n' before user@domain if that line is TOO BIG
2851 prompt
= _('<b>Whom do you want to ban?</b>\n\n')
2852 elif affiliation
== 'member':
2853 title
= _('Adding Member...')
2854 prompt
= _('<b>Whom do you want to make a member?</b>\n\n')
2855 elif affiliation
== 'owner':
2856 title
= _('Adding Owner...')
2857 prompt
= _('<b>Whom do you want to make an owner?</b>\n\n')
2859 title
= _('Adding Administrator...')
2860 prompt
= _('<b>Whom do you want to make an administrator?</b>\n\n')
2861 prompt
+= _('Can be one of the following:\n'
2862 '1. user@domain/resource (only that resource matches).\n'
2863 '2. user@domain (any resource matches).\n'
2864 '3. domain/resource (only that resource matches).\n'
2865 '4. domain (the domain itself matches, as does any user@domain,\n'
2866 'domain/resource, or address containing a subdomain).')
2871 model
= self
.affiliation_treeview
[affiliation
].get_model()
2872 model
.append((jid
, '', '', ''))
2873 dialogs
.InputDialog(title
, prompt
, ok_handler
=on_ok
)
2875 def on_remove_button_clicked(self
, widget
, affiliation
):
2876 selection
= self
.affiliation_treeview
[affiliation
].get_selection()
2877 model
, paths
= selection
.get_selected_rows()
2880 row_refs
.append(gtk
.TreeRowReference(model
, path
))
2881 for row_ref
in row_refs
:
2882 path
= row_ref
.get_path()
2883 iter_
= model
.get_iter(path
)
2885 self
.remove_button
[affiliation
].set_sensitive(False)
2887 def on_affiliation_treeview_cursor_changed(self
, widget
, affiliation
):
2888 self
.remove_button
[affiliation
].set_sensitive(True)
2890 def affiliation_list_received(self
, users_dict
):
2892 Fill the affiliation treeview
2894 for jid
in users_dict
:
2895 affiliation
= users_dict
[jid
]['affiliation']
2896 if affiliation
not in self
.affiliation_labels
.keys():
2897 # Unknown affiliation or 'none' affiliation, do not show it
2899 self
.start_users_dict
[affiliation
][jid
] = users_dict
[jid
]
2900 tv
= self
.affiliation_treeview
[affiliation
]
2901 model
= tv
.get_model()
2902 reason
= users_dict
[jid
].get('reason', '')
2903 nick
= users_dict
[jid
].get('nick', '')
2904 role
= users_dict
[jid
].get('role', '')
2905 model
.append((jid
, reason
, nick
, role
))
2907 def on_data_form_window_destroy(self
, widget
):
2908 del gajim
.interface
.instances
[self
.account
]['gc_config'][self
.room_jid
]
2910 def on_ok_button_clicked(self
, widget
):
2912 form
= self
.data_form_widget
.data_form
2913 gajim
.connections
[self
.account
].send_gc_config(self
.room_jid
, form
)
2914 for affiliation
in self
.affiliation_labels
.keys():
2916 actual_jid_list
= []
2917 model
= self
.affiliation_treeview
[affiliation
].get_model()
2918 iter_
= model
.get_iter_first()
2921 jid
= model
[iter_
][0].decode('utf-8')
2922 actual_jid_list
.append(jid
)
2923 if jid
not in self
.start_users_dict
[affiliation
] or \
2924 (affiliation
== 'outcast' and 'reason' in self
.start_users_dict
[
2925 affiliation
][jid
] and self
.start_users_dict
[affiliation
][jid
]\
2926 ['reason'] != model
[iter_
][1].decode('utf-8')):
2927 users_dict
[jid
] = {'affiliation': affiliation
}
2928 if affiliation
== 'outcast':
2929 users_dict
[jid
]['reason'] = model
[iter_
][1].decode(
2931 iter_
= model
.iter_next(iter_
)
2932 # remove removed one
2933 for jid
in self
.start_users_dict
[affiliation
]:
2934 if jid
not in actual_jid_list
:
2935 users_dict
[jid
] = {'affiliation': 'none'}
2937 gajim
.connections
[self
.account
].send_gc_affiliation_list(
2938 self
.room_jid
, users_dict
)
2939 self
.window
.destroy()
2941 #---------- RemoveAccountWindow class -------------#
2942 class RemoveAccountWindow
:
2944 Ask for removing from gajim only or from gajim and server too and do
2945 removing of the account given
2948 def on_remove_account_window_destroy(self
, widget
):
2949 if self
.account
in gajim
.interface
.instances
:
2950 del gajim
.interface
.instances
[self
.account
]['remove_account']
2952 def on_cancel_button_clicked(self
, widget
):
2953 self
.window
.destroy()
2955 def __init__(self
, account
):
2956 self
.account
= account
2957 xml
= gtkgui_helpers
.get_gtk_builder('remove_account_window.ui')
2958 self
.window
= xml
.get_object('remove_account_window')
2959 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2960 self
.remove_and_unregister_radiobutton
= xml
.get_object(
2961 'remove_and_unregister_radiobutton')
2962 self
.window
.set_title(_('Removing %s account') % self
.account
)
2963 xml
.connect_signals(self
)
2964 self
.window
.show_all()
2966 def on_remove_button_clicked(self
, widget
):
2968 if self
.account
in gajim
.connections
and \
2969 gajim
.connections
[self
.account
].connected
and \
2970 not self
.remove_and_unregister_radiobutton
.get_active():
2971 # change status to offline only if we will not remove this JID from
2973 gajim
.connections
[self
.account
].change_status('offline', 'offline')
2974 if self
.remove_and_unregister_radiobutton
.get_active():
2975 if not self
.account
in gajim
.connections
:
2976 dialogs
.ErrorDialog(
2977 _('Account is disabled'),
2978 _('To unregister from a server, account must be '
2981 if not gajim
.connections
[self
.account
].password
:
2982 def on_ok(passphrase
, checked
):
2983 if passphrase
== -1:
2984 # We don't remove account cause we canceled pw window
2986 gajim
.connections
[self
.account
].password
= passphrase
2987 gajim
.connections
[self
.account
].unregister_account(
2988 self
._on
_remove
_success
)
2990 dialogs
.PassphraseDialog(
2991 _('Password Required'),
2992 _('Enter your password for account %s') % self
.account
,
2993 _('Save password'), ok_handler
=on_ok
)
2995 gajim
.connections
[self
.account
].unregister_account(
2996 self
._on
_remove
_success
)
2998 self
._on
_remove
_success
(True)
3000 if self
.account
in gajim
.connections
and \
3001 gajim
.connections
[self
.account
].connected
:
3002 dialogs
.ConfirmationDialog(
3003 _('Account "%s" is connected to the server') % self
.account
,
3004 _('If you remove it, the connection will be lost.'),
3005 on_response_ok
=remove
)
3009 def on_remove_responce_ok(self
, is_checked
):
3011 self
._on
_remove
_success
(True)
3013 def _on_remove_success(self
, res
):
3014 # action of unregistration has failed, we don't remove the account
3015 # Error message is send by connect_and_auth()
3017 dialogs
.ConfirmationDialogDoubleRadio(
3018 _('Connection to server %s failed') % self
.account
,
3019 _('What would you like to do?'),
3020 _('Remove only from Gajim'),
3021 _('Don\'t remove anything. I\'ll try again later'),
3022 on_response_ok
=self
.on_remove_responce_ok
, is_modal
=False)
3024 # Close all opened windows
3025 gajim
.interface
.roster
.close_all(self
.account
, force
=True)
3026 if self
.account
in gajim
.connections
:
3027 gajim
.connections
[self
.account
].disconnect(on_purpose
=True)
3028 gajim
.connections
[self
.account
].cleanup()
3029 del gajim
.connections
[self
.account
]
3030 gajim
.logger
.remove_roster(gajim
.get_jid_from_account(self
.account
))
3031 gajim
.config
.del_per('accounts', self
.account
)
3032 gajim
.interface
.save_config()
3033 del gajim
.interface
.instances
[self
.account
]
3034 if self
.account
in gajim
.nicks
:
3035 del gajim
.interface
.minimized_controls
[self
.account
]
3036 del gajim
.nicks
[self
.account
]
3037 del gajim
.block_signed_in_notifications
[self
.account
]
3038 del gajim
.groups
[self
.account
]
3039 gajim
.contacts
.remove_account(self
.account
)
3040 del gajim
.gc_connected
[self
.account
]
3041 del gajim
.automatic_rooms
[self
.account
]
3042 del gajim
.to_be_removed
[self
.account
]
3043 del gajim
.newly_added
[self
.account
]
3044 del gajim
.sleeper_state
[self
.account
]
3045 del gajim
.encrypted_chats
[self
.account
]
3046 del gajim
.last_message_time
[self
.account
]
3047 del gajim
.status_before_autoaway
[self
.account
]
3048 del gajim
.transport_avatar
[self
.account
]
3049 del gajim
.gajim_optional_features
[self
.account
]
3050 del gajim
.caps_hash
[self
.account
]
3051 if len(gajim
.connections
) >= 2: # Do not merge accounts if only one exists
3052 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
3054 gajim
.interface
.roster
.regroup
= False
3055 gajim
.interface
.roster
.setup_and_draw_roster()
3056 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3057 if 'accounts' in gajim
.interface
.instances
:
3058 gajim
.interface
.instances
['accounts'].init_accounts()
3059 gajim
.interface
.instances
['accounts'].init_account()
3060 self
.window
.destroy()
3062 #---------- ManageBookmarksWindow class -------------#
3063 class ManageBookmarksWindow
:
3065 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_bookmarks_window.ui')
3066 self
.window
= self
.xml
.get_object('manage_bookmarks_window')
3067 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3069 # Account-JID, RoomName, Room-JID, Autojoin, Minimize, Passowrd, Nick,
3071 self
.treestore
= gtk
.TreeStore(str, str, str, bool, bool, str, str, str)
3072 self
.treestore
.set_sort_column_id(1, gtk
.SORT_ASCENDING
)
3074 # Store bookmarks in treeview.
3075 for account
in gajim
.connections
:
3076 if gajim
.connections
[account
].connected
<= 1:
3078 if gajim
.connections
[account
].is_zeroconf
:
3080 if not gajim
.connections
[account
].private_storage_supported
:
3082 iter_
= self
.treestore
.append(None, [None, account
, None, None,
3083 None, None, None, None])
3085 for bookmark
in gajim
.connections
[account
].bookmarks
:
3086 if bookmark
['name'] == '':
3087 # No name was given for this bookmark.
3088 # Use the first part of JID instead...
3089 name
= bookmark
['jid'].split("@")[0]
3090 bookmark
['name'] = name
3092 # make '1', '0', 'true', 'false' (or other) to True/False
3093 autojoin
= helpers
.from_xs_boolean_to_python_boolean(
3094 bookmark
['autojoin'])
3096 minimize
= helpers
.from_xs_boolean_to_python_boolean(
3097 bookmark
['minimize'])
3099 print_status
= bookmark
.get('print_status', '')
3100 if print_status
not in ('', 'all', 'in_and_out', 'none'):
3102 self
.treestore
.append(iter_
, [
3108 bookmark
['password'],
3112 self
.print_status_combobox
= self
.xml
.get_object('print_status_combobox')
3113 model
= gtk
.ListStore(str, str)
3115 self
.option_list
= {'': _('Default'), 'all': Q_('?print_status:All'),
3116 'in_and_out': _('Enter and leave only'),
3117 'none': Q_('?print_status:None')}
3118 opts
= sorted(self
.option_list
.keys())
3120 model
.append([self
.option_list
[opt
], opt
])
3122 self
.print_status_combobox
.set_model(model
)
3123 self
.print_status_combobox
.set_active(1)
3125 self
.view
= self
.xml
.get_object('bookmarks_treeview')
3126 self
.view
.set_model(self
.treestore
)
3127 self
.view
.expand_all()
3129 renderer
= gtk
.CellRendererText()
3130 column
= gtk
.TreeViewColumn('Bookmarks', renderer
, text
=1)
3131 self
.view
.append_column(column
)
3133 self
.selection
= self
.view
.get_selection()
3134 self
.selection
.connect('changed', self
.bookmark_selected
)
3136 #Prepare input fields
3137 self
.title_entry
= self
.xml
.get_object('title_entry')
3138 self
.title_entry
.connect('changed', self
.on_title_entry_changed
)
3139 self
.nick_entry
= self
.xml
.get_object('nick_entry')
3140 self
.nick_entry
.connect('changed', self
.on_nick_entry_changed
)
3141 self
.server_entry
= self
.xml
.get_object('server_entry')
3142 self
.server_entry
.connect('changed', self
.on_server_entry_changed
)
3143 self
.room_entry
= self
.xml
.get_object('room_entry')
3144 self
.room_entry
.connect('changed', self
.on_room_entry_changed
)
3145 self
.pass_entry
= self
.xml
.get_object('pass_entry')
3146 self
.pass_entry
.connect('changed', self
.on_pass_entry_changed
)
3147 self
.autojoin_checkbutton
= self
.xml
.get_object('autojoin_checkbutton')
3148 self
.minimize_checkbutton
= self
.xml
.get_object('minimize_checkbutton')
3150 self
.xml
.connect_signals(self
)
3151 self
.window
.show_all()
3153 self
.selection
.select_iter(self
.treestore
.get_iter_root())
3155 def on_bookmarks_treeview_button_press_event(self
, widget
, event
):
3156 (model
, iter_
) = self
.selection
.get_selected()
3158 # Removed a bookmark before
3161 if model
.iter_parent(iter_
):
3162 # The currently selected node is a bookmark
3163 return not self
.check_valid_bookmark()
3165 def on_manage_bookmarks_window_destroy(self
, widget
, event
):
3166 del gajim
.interface
.instances
['manage_bookmarks']
3168 def on_add_bookmark_button_clicked(self
, widget
):
3172 # Get the account that is currently used
3173 # (the parent of the currently selected item)
3174 (model
, iter_
) = self
.selection
.get_selected()
3175 if not iter_
: # Nothing selected, do nothing
3178 parent
= model
.iter_parent(iter_
)
3181 # We got a bookmark selected, so we add_to the parent
3184 # No parent, so we got an account -> add to this.
3187 account
= model
[add_to
][1].decode('utf-8')
3188 nick
= gajim
.nicks
[account
]
3189 iter_
= self
.treestore
.append(add_to
, [account
, _('New Group Chat'),
3190 '@', False, False, '', nick
, 'in_and_out'])
3192 self
.view
.expand_row(model
.get_path(add_to
), True)
3193 self
.view
.set_cursor(model
.get_path(iter_
))
3195 def on_remove_bookmark_button_clicked(self
, widget
):
3197 Remove selected bookmark
3199 (model
, iter_
) = self
.selection
.get_selected()
3200 if not iter_
: # Nothing selected
3203 if not model
.iter_parent(iter_
):
3204 # Don't remove account iters
3210 def check_valid_bookmark(self
):
3212 Check if all neccessary fields are entered correctly
3214 (model
, iter_
) = self
.selection
.get_selected()
3216 if not model
.iter_parent(iter_
):
3217 #Account data can't be changed
3220 if self
.server_entry
.get_text().decode('utf-8') == '' or \
3221 self
.room_entry
.get_text().decode('utf-8') == '':
3222 dialogs
.ErrorDialog(_('This bookmark has invalid data'),
3223 _('Please be sure to fill out server and room fields or remove this'
3229 def on_ok_button_clicked(self
, widget
):
3231 Parse the treestore data into our new bookmarks array, then send the new
3232 bookmarks to the server.
3234 (model
, iter_
) = self
.selection
.get_selected()
3235 if iter_
and model
.iter_parent(iter_
):
3236 #bookmark selected, check it
3237 if not self
.check_valid_bookmark():
3240 for account
in self
.treestore
:
3241 account_unicode
= account
[1].decode('utf-8')
3242 gajim
.connections
[account_unicode
].bookmarks
= []
3244 for bm
in account
.iterchildren():
3245 # Convert True/False/None to '1' or '0'
3246 autojoin
= unicode(int(bm
[3]))
3247 minimize
= unicode(int(bm
[4]))
3250 name
= name
.decode('utf-8')
3253 jid
= jid
.decode('utf-8')
3256 pw
= pw
.decode('utf-8')
3259 nick
= nick
.decode('utf-8')
3261 # create the bookmark-dict
3262 bmdict
= { 'name': name
, 'jid': jid
, 'autojoin': autojoin
,
3263 'minimize': minimize
, 'password': pw
, 'nick': nick
,
3264 'print_status': bm
[7]}
3266 gajim
.connections
[account_unicode
].bookmarks
.append(bmdict
)
3268 gajim
.connections
[account_unicode
].store_bookmarks()
3269 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3270 self
.window
.destroy()
3272 def on_cancel_button_clicked(self
, widget
):
3273 self
.window
.destroy()
3275 def bookmark_selected(self
, selection
):
3277 Fill in the bookmark's data into the fields.
3279 (model
, iter_
) = selection
.get_selected()
3282 # After removing the last bookmark for one account
3283 # this will be None, so we will just:
3286 widgets
= [ self
.title_entry
, self
.nick_entry
, self
.room_entry
,
3287 self
.server_entry
, self
.pass_entry
, self
.autojoin_checkbutton
,
3288 self
.minimize_checkbutton
, self
.print_status_combobox
]
3290 if model
.iter_parent(iter_
):
3291 # make the fields sensitive
3292 for field
in widgets
:
3293 field
.set_sensitive(True)
3295 # Top-level has no data (it's the account fields)
3296 # clear fields & make them insensitive
3298 for field
in widgets
:
3299 field
.set_sensitive(False)
3302 # Fill in the data for childs
3303 self
.title_entry
.set_text(model
[iter_
][1])
3304 room_jid
= model
[iter_
][2].decode('utf-8')
3305 (room
, server
) = room_jid
.split('@')
3306 self
.room_entry
.set_text(room
)
3307 self
.server_entry
.set_text(server
)
3309 self
.autojoin_checkbutton
.set_active(model
[iter_
][3])
3310 self
.minimize_checkbutton
.set_active(model
[iter_
][4])
3311 # sensitive only if auto join is checked
3312 self
.minimize_checkbutton
.set_sensitive(model
[iter_
][3])
3314 if model
[iter_
][5] is not None:
3315 password
= model
[iter_
][5].decode('utf-8')
3320 self
.pass_entry
.set_text(password
)
3322 self
.pass_entry
.set_text('')
3323 nick
= model
[iter_
][6]
3325 nick
= nick
.decode('utf-8')
3326 self
.nick_entry
.set_text(nick
)
3328 self
.nick_entry
.set_text('')
3330 print_status
= model
[iter_
][7]
3331 opts
= sorted(self
.option_list
.keys())
3332 self
.print_status_combobox
.set_active(opts
.index(print_status
))
3334 def on_title_entry_changed(self
, widget
):
3335 (model
, iter_
) = self
.selection
.get_selected()
3336 if iter_
: # After removing a bookmark, we got nothing selected
3337 if model
.iter_parent(iter_
):
3338 # Don't clear the title field for account nodes
3339 model
[iter_
][1] = self
.title_entry
.get_text()
3341 def on_nick_entry_changed(self
, widget
):
3342 (model
, iter_
) = self
.selection
.get_selected()
3344 nick
= self
.nick_entry
.get_text().decode('utf-8')
3346 nick
= helpers
.parse_resource(nick
)
3347 except helpers
.InvalidFormat
, e
:
3348 dialogs
.ErrorDialog(_('Invalid nickname'),
3349 _('Character not allowed'))
3350 self
.nick_entry
.set_text(model
[iter_
][6])
3352 model
[iter_
][6] = nick
3354 def on_server_entry_changed(self
, widget
):
3355 (model
, iter_
) = self
.selection
.get_selected()
3358 server
= widget
.get_text().decode('utf-8')
3360 dialogs
.ErrorDialog(_('Invalid server'), _('Character not allowed'))
3361 widget
.set_text(server
.replace('@', ''))
3363 room_jid
= self
.room_entry
.get_text().decode('utf-8').strip() + '@' + \
3366 room_jid
= helpers
.parse_resource(room_jid
)
3367 except helpers
.InvalidFormat
, e
:
3368 dialogs
.ErrorDialog(_('Invalid server'),
3369 _('Character not allowed'))
3370 self
.server_entry
.set_text(model
[iter_
][2].split('@')[1])
3372 model
[iter_
][2] = room_jid
3374 def on_room_entry_changed(self
, widget
):
3375 (model
, iter_
) = self
.selection
.get_selected()
3378 room
= widget
.get_text().decode('utf-8')
3380 dialogs
.ErrorDialog(_('Invalid server'), _('Character not allowed'))
3381 widget
.set_text(room
.replace('@', ''))
3382 room_jid
= room
.strip() + '@' + \
3383 self
.server_entry
.get_text().decode('utf-8').strip()
3385 room_jid
= helpers
.parse_resource(room_jid
)
3386 except helpers
.InvalidFormat
, e
:
3387 dialogs
.ErrorDialog(_('Invalid room'),
3388 _('Character not allowed'))
3389 self
.room_entry
.set_text(model
[iter_
][2].split('@')[0])
3391 model
[iter_
][2] = room_jid
3393 def on_pass_entry_changed(self
, widget
):
3394 (model
, iter_
) = self
.selection
.get_selected()
3396 model
[iter_
][5] = self
.pass_entry
.get_text()
3398 def on_autojoin_checkbutton_toggled(self
, widget
):
3399 (model
, iter_
) = self
.selection
.get_selected()
3401 model
[iter_
][3] = self
.autojoin_checkbutton
.get_active()
3402 self
.minimize_checkbutton
.set_sensitive(model
[iter_
][3])
3404 def on_minimize_checkbutton_toggled(self
, widget
):
3405 (model
, iter_
) = self
.selection
.get_selected()
3407 model
[iter_
][4] = self
.minimize_checkbutton
.get_active()
3409 def on_print_status_combobox_changed(self
, widget
):
3410 active
= widget
.get_active()
3411 model
= widget
.get_model()
3412 print_status
= model
[active
][1]
3413 (model2
, iter_
) = self
.selection
.get_selected()
3415 model2
[iter_
][7] = print_status
3417 def clear_fields(self
):
3418 widgets
= [ self
.title_entry
, self
.nick_entry
, self
.room_entry
,
3419 self
.server_entry
, self
.pass_entry
]
3420 for field
in widgets
:
3422 self
.autojoin_checkbutton
.set_active(False)
3423 self
.minimize_checkbutton
.set_active(False)
3424 self
.print_status_combobox
.set_active(1)
3426 class AccountCreationWizardWindow
:
3428 self
.xml
= gtkgui_helpers
.get_gtk_builder(
3429 'account_creation_wizard_window.ui')
3430 self
.window
= self
.xml
.get_object('account_creation_wizard_window')
3431 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3433 completion
= gtk
.EntryCompletion()
3434 completion1
= gtk
.EntryCompletion()
3435 # Connect events from comboboxentry.child
3436 server_comboboxentry
= self
.xml
.get_object('server_comboboxentry')
3437 entry
= server_comboboxentry
.child
3438 entry
.connect('key_press_event',
3439 self
.on_server_comboboxentry_key_press_event
, server_comboboxentry
)
3440 entry
.set_completion(completion
)
3441 # Do the same for the other server comboboxentry
3442 server_comboboxentry1
= self
.xml
.get_object('server_comboboxentry1')
3443 entry
= server_comboboxentry1
.child
3444 entry
.set_completion(completion1
)
3446 self
.update_proxy_list()
3449 servers_xml
= os
.path
.join(gajim
.DATA_DIR
, 'other', 'servers.xml')
3450 servers
= gtkgui_helpers
.parse_server_xml(servers_xml
)
3451 servers_model
= gtk
.ListStore(str)
3452 for server
in servers
:
3453 servers_model
.append((server
,))
3455 completion
.set_model(servers_model
)
3456 completion
.set_text_column(0)
3457 completion1
.set_model(servers_model
)
3458 completion1
.set_text_column(0)
3460 # Put servers into comboboxentries
3461 server_comboboxentry
.set_model(servers_model
)
3462 server_comboboxentry
.set_text_column(0)
3463 server_comboboxentry1
.set_model(servers_model
)
3464 server_comboboxentry1
.set_text_column(0)
3467 self
.notebook
= self
.xml
.get_object('notebook')
3468 self
.cancel_button
= self
.xml
.get_object('cancel_button')
3469 self
.back_button
= self
.xml
.get_object('back_button')
3470 self
.forward_button
= self
.xml
.get_object('forward_button')
3471 self
.finish_button
= self
.xml
.get_object('finish_button')
3472 self
.advanced_button
= self
.xml
.get_object('advanced_button')
3473 self
.finish_label
= self
.xml
.get_object('finish_label')
3474 self
.go_online_checkbutton
= self
.xml
.get_object(
3475 'go_online_checkbutton')
3476 self
.show_vcard_checkbutton
= self
.xml
.get_object(
3477 'show_vcard_checkbutton')
3478 self
.progressbar
= self
.xml
.get_object('progressbar')
3481 self
.update_progressbar_timeout_id
= None
3483 self
.notebook
.set_current_page(0)
3484 self
.xml
.connect_signals(self
)
3485 self
.window
.show_all()
3486 gajim
.ged
.register_event_handler('new-account-connected', ged
.GUI1
,
3487 self
._nec
_new
_acc
_connected
)
3488 gajim
.ged
.register_event_handler('new-account-not-connected', ged
.GUI1
,
3489 self
._nec
_new
_acc
_not
_connected
)
3490 gajim
.ged
.register_event_handler('account-created', ged
.GUI1
,
3491 self
._nec
_acc
_is
_ok
)
3492 gajim
.ged
.register_event_handler('account-not-created', ged
.GUI1
,
3493 self
._nec
_acc
_is
_not
_ok
)
3495 def on_wizard_window_destroy(self
, widget
):
3496 page
= self
.notebook
.get_current_page()
3497 if page
in (4, 5) and self
.account
in gajim
.connections
:
3498 # connection instance is saved in gajim.connections and we canceled
3499 # the addition of the account
3500 del gajim
.connections
[self
.account
]
3501 if self
.account
in gajim
.config
.get_per('accounts'):
3502 gajim
.config
.del_per('accounts', self
.account
)
3503 gajim
.ged
.remove_event_handler('new-account-connected', ged
.GUI1
,
3504 self
._nec
_new
_acc
_connected
)
3505 gajim
.ged
.remove_event_handler('new-account-not-connected', ged
.GUI1
,
3506 self
._nec
_new
_acc
_not
_connected
)
3507 gajim
.ged
.remove_event_handler('account-created', ged
.GUI1
,
3508 self
._nec
_acc
_is
_ok
)
3509 gajim
.ged
.remove_event_handler('account-not-created', ged
.GUI1
,
3510 self
._nec
_acc
_is
_not
_ok
)
3511 del gajim
.interface
.instances
['account_creation_wizard']
3513 def on_register_server_features_button_clicked(self
, widget
):
3514 helpers
.launch_browser_mailer('url',
3515 'http://www.jabber.org/network/oldnetwork.shtml')
3517 def on_save_password_checkbutton_toggled(self
, widget
):
3518 self
.xml
.get_object('password_entry').grab_focus()
3520 def on_cancel_button_clicked(self
, widget
):
3521 self
.window
.destroy()
3523 def on_back_button_clicked(self
, widget
):
3524 cur_page
= self
.notebook
.get_current_page()
3525 if cur_page
in (1, 2):
3526 self
.notebook
.set_current_page(0)
3527 self
.back_button
.set_sensitive(False)
3529 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3530 self
.notebook
.set_current_page(2) # show server page
3532 if self
.account
in gajim
.connections
:
3533 del gajim
.connections
[self
.account
]
3534 self
.notebook
.set_current_page(2)
3535 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3536 elif cur_page
== 6: # finish page
3537 self
.forward_button
.show()
3539 self
.notebook
.set_current_page(1) # Go to parameters page
3541 self
.notebook
.set_current_page(2) # Go to server page
3543 def on_anonymous_checkbutton1_toggled(self
, widget
):
3544 active
= widget
.get_active()
3545 self
.xml
.get_object('username_entry').set_sensitive(not active
)
3546 self
.xml
.get_object('password_entry').set_sensitive(not active
)
3547 self
.xml
.get_object('save_password_checkbutton').set_sensitive(
3550 def show_finish_page(self
):
3551 self
.cancel_button
.hide()
3552 self
.back_button
.hide()
3553 self
.forward_button
.hide()
3555 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3556 _('Account has been added successfully'),
3557 _('You can set advanced account options by pressing the '
3558 'Advanced button, or later by choosing the Accounts menu item '
3559 'under the Edit menu from the main window.'))
3561 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3562 _('Your new account has been created successfully'),
3563 _('You can set advanced account options by pressing the '
3564 'Advanced button, or later by choosing the Accounts menu item '
3565 'under the Edit menu from the main window.'))
3566 self
.finish_label
.set_markup(finish_text
)
3567 self
.finish_button
.show()
3568 self
.finish_button
.set_property('has-default', True)
3569 self
.advanced_button
.show()
3570 self
.go_online_checkbutton
.show()
3571 img
= self
.xml
.get_object('finish_image')
3573 img
.set_from_stock(gtk
.STOCK_APPLY
, gtk
.ICON_SIZE_DIALOG
)
3575 path_to_file
= gtkgui_helpers
.get_icon_path('gajim', 48)
3576 img
.set_from_file(path_to_file
)
3577 self
.show_vcard_checkbutton
.set_active(not self
.modify
)
3578 self
.notebook
.set_current_page(6) # show finish page
3580 def on_forward_button_clicked(self
, widget
):
3581 cur_page
= self
.notebook
.get_current_page()
3584 widget
= self
.xml
.get_object('use_existing_account_radiobutton')
3585 if widget
.get_active():
3587 self
.notebook
.set_current_page(1)
3590 self
.notebook
.set_current_page(2)
3591 self
.back_button
.set_sensitive(True)
3595 # We are adding an existing account
3596 anonymous
= self
.xml
.get_object('anonymous_checkbutton1').\
3598 username
= self
.xml
.get_object('username_entry').get_text().decode(
3600 if not username
and not anonymous
:
3601 pritext
= _('Invalid username')
3603 'You must provide a username to configure this account.')
3604 dialogs
.ErrorDialog(pritext
, sectext
)
3606 server
= self
.xml
.get_object('server_comboboxentry').child
.\
3607 get_text().decode('utf-8').strip()
3608 savepass
= self
.xml
.get_object('save_password_checkbutton').\
3610 password
= self
.xml
.get_object('password_entry').get_text().decode(
3613 jid
= username
+ '@' + server
3614 # check if jid is conform to RFC and stringprep it
3616 jid
= helpers
.parse_jid(jid
)
3617 except helpers
.InvalidFormat
, s
:
3618 pritext
= _('Invalid Jabber ID')
3619 dialogs
.ErrorDialog(pritext
, str(s
))
3622 self
.account
= server
3624 while self
.account
in gajim
.connections
:
3625 self
.account
= server
+ str(i
)
3628 username
, server
= gajim
.get_name_and_server_from_jid(jid
)
3629 if self
.xml
.get_object('anonymous_checkbutton1').get_active():
3630 self
.save_account('', server
, False, '', anonymous
=True)
3632 self
.save_account(username
, server
, savepass
, password
)
3633 self
.show_finish_page()
3635 # We are creating a new account
3636 server
= self
.xml
.get_object('server_comboboxentry1').child
.\
3637 get_text().decode('utf-8')
3640 dialogs
.ErrorDialog(_('Invalid server'),
3641 _('Please provide a server on which you want to register.'))
3643 self
.account
= server
3645 while self
.account
in gajim
.connections
:
3646 self
.account
= server
+ str(i
)
3649 config
= self
.get_config('', server
, '', '')
3650 # Get advanced options
3651 proxies_combobox
= self
.xml
.get_object('proxies_combobox')
3652 active
= proxies_combobox
.get_active()
3653 proxy
= proxies_combobox
.get_model()[active
][0].decode('utf-8')
3654 if proxy
== _('None'):
3656 config
['proxy'] = proxy
3658 config
['use_custom_host'] = self
.xml
.get_object(
3659 'custom_host_port_checkbutton').get_active()
3660 custom_port
= self
.xml
.get_object('custom_port_entry').get_text()
3662 custom_port
= int(custom_port
)
3664 dialogs
.ErrorDialog(_('Invalid entry'),
3665 _('Custom port must be a port number.'))
3667 config
['custom_port'] = custom_port
3668 config
['custom_host'] = self
.xml
.get_object(
3669 'custom_host_entry').get_text().decode('utf-8')
3671 if self
.xml
.get_object('anonymous_checkbutton2').get_active():
3673 self
.save_account('', server
, False, '', anonymous
=True)
3674 self
.show_finish_page()
3676 self
.notebook
.set_current_page(5) # show creating page
3677 self
.back_button
.hide()
3678 self
.forward_button
.hide()
3679 self
.update_progressbar_timeout_id
= gobject
.timeout_add(100,
3680 self
.update_progressbar
)
3681 # Get form from serveur
3682 con
= connection
.Connection(self
.account
)
3683 gajim
.connections
[self
.account
] = con
3684 con
.new_account(self
.account
, config
)
3686 checked
= self
.xml
.get_object('ssl_checkbutton').get_active()
3688 hostname
= gajim
.connections
[self
.account
].new_account_info
[
3690 # Check if cert is already in file
3692 if os
.path
.isfile(gajim
.MY_CACERTS
):
3693 f
= open(gajim
.MY_CACERTS
)
3696 if self
.ssl_cert
in certs
:
3697 dialogs
.ErrorDialog(_('Certificate Already in File'),
3698 _('This certificate is already in file %s, so it\'s '
3699 'not added again.') % gajim
.MY_CACERTS
)
3701 f
= open(gajim
.MY_CACERTS
, 'a')
3702 f
.write(hostname
+ '\n')
3703 f
.write(self
.ssl_cert
+ '\n\n')
3705 gajim
.connections
[self
.account
].new_account_info
[
3706 'ssl_fingerprint_sha1'] = self
.ssl_fingerprint
3707 self
.notebook
.set_current_page(4) # show fom page
3710 form
= self
.data_form_widget
.data_form
3712 form
= self
.data_form_widget
.get_infos()
3713 gajim
.connections
[self
.account
].send_new_account_infos(form
,
3715 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3716 self
.xml
.get_object('progressbar_label').set_markup(
3717 '<b>Account is being created</b>\n\nPlease wait...')
3718 self
.notebook
.set_current_page(5) # show creating page
3719 self
.back_button
.hide()
3720 self
.forward_button
.hide()
3721 self
.update_progressbar_timeout_id
= gobject
.timeout_add(100,
3722 self
.update_progressbar
)
3724 def update_proxy_list(self
):
3725 proxies_combobox
= self
.xml
.get_object('proxies_combobox')
3726 model
= gtk
.ListStore(str)
3727 proxies_combobox
.set_model(model
)
3728 l
= gajim
.config
.get_per('proxies')
3729 l
.insert(0, _('None'))
3730 for i
in xrange(len(l
)):
3731 model
.append([l
[i
]])
3732 proxies_combobox
.set_active(0)
3734 def on_manage_proxies_button_clicked(self
, widget
):
3735 if 'manage_proxies' in gajim
.interface
.instances
:
3736 gajim
.interface
.instances
['manage_proxies'].window
.present()
3738 gajim
.interface
.instances
['manage_proxies'] = \
3739 ManageProxiesWindow()
3741 def on_custom_host_port_checkbutton_toggled(self
, widget
):
3742 self
.xml
.get_object('custom_host_hbox').set_sensitive(widget
.\
3745 def update_progressbar(self
):
3746 self
.progressbar
.pulse()
3747 return True # loop forever
3749 def _nec_new_acc_connected(self
, obj
):
3751 Connection to server succeded, present the form to the user
3753 # We receive events from all accounts from GED
3754 if obj
.conn
.name
!= self
.account
:
3756 if self
.update_progressbar_timeout_id
is not None:
3757 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3758 self
.back_button
.show()
3759 self
.forward_button
.show()
3760 self
.is_form
= obj
.is_form
3762 dataform
= dataforms
.ExtendForm(node
=obj
.config
)
3763 self
.data_form_widget
= dataforms_widget
.DataFormWidget(dataform
)
3765 self
.data_form_widget
= FakeDataForm(obj
.config
)
3766 self
.data_form_widget
.show_all()
3767 self
.xml
.get_object('form_vbox').pack_start(self
.data_form_widget
)
3768 self
.ssl_fingerprint
= obj
.ssl_fingerprint
3769 self
.ssl_cert
= obj
.ssl_cert
3771 # An SSL warning occured, show it
3772 hostname
= gajim
.connections
[self
.account
].new_account_info
[
3774 self
.xml
.get_object('ssl_label').set_markup(_(
3775 '<b>Security Warning</b>'
3776 '\n\nThe authenticity of the %(hostname)s SSL certificate could'
3777 ' be invalid.\nSSL Error: %(error)s\n'
3778 'Do you still want to connect to this server?') % {
3779 'hostname': hostname
, 'error': obj
.ssl_msg
})
3780 if obj
.errnum
in (18, 27):
3781 text
= _('Add this certificate to the list of trusted '
3782 'certificates.\nSHA1 fingerprint of the certificate:\n%s') \
3783 % obj
.ssl_fingerprint
3784 self
.xml
.get_object('ssl_checkbutton').set_label(text
)
3786 self
.xml
.get_object('ssl_checkbutton').set_no_show_all(True)
3787 self
.xml
.get_object('ssl_checkbutton').hide()
3788 self
.notebook
.set_current_page(3) # show SSL page
3790 self
.notebook
.set_current_page(4) # show form page
3792 def _nec_new_acc_not_connected(self
, obj
):
3794 Account creation failed: connection to server failed
3796 # We receive events from all accounts from GED
3797 if obj
.conn
.name
!= self
.account
:
3799 if self
.account
not in gajim
.connections
:
3801 if self
.update_progressbar_timeout_id
is not None:
3802 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3803 del gajim
.connections
[self
.account
]
3804 if self
.account
in gajim
.config
.get_per('accounts'):
3805 gajim
.config
.del_per('accounts', self
.account
)
3806 self
.back_button
.show()
3807 self
.cancel_button
.show()
3808 self
.go_online_checkbutton
.hide()
3809 self
.show_vcard_checkbutton
.hide()
3810 img
= self
.xml
.get_object('finish_image')
3811 img
.set_from_stock(gtk
.STOCK_DIALOG_ERROR
, gtk
.ICON_SIZE_DIALOG
)
3812 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3813 _('An error occurred during account creation'), obj
.reason
)
3814 self
.finish_label
.set_markup(finish_text
)
3815 self
.notebook
.set_current_page(6) # show finish page
3817 def _nec_acc_is_ok(self
, obj
):
3819 Account creation succeeded
3821 # We receive events from all accounts from GED
3822 if obj
.conn
.name
!= self
.account
:
3824 self
.create_vars(obj
.account_info
)
3825 self
.show_finish_page()
3827 if self
.update_progressbar_timeout_id
is not None:
3828 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3830 def _nec_acc_is_not_ok(self
, obj
):
3832 Account creation failed
3834 # We receive events from all accounts from GED
3835 if obj
.conn
.name
!= self
.account
:
3837 self
.back_button
.show()
3838 self
.cancel_button
.show()
3839 self
.go_online_checkbutton
.hide()
3840 self
.show_vcard_checkbutton
.hide()
3841 del gajim
.connections
[self
.account
]
3842 if self
.account
in gajim
.config
.get_per('accounts'):
3843 gajim
.config
.del_per('accounts', self
.account
)
3844 img
= self
.xml
.get_object('finish_image')
3845 img
.set_from_stock(gtk
.STOCK_DIALOG_ERROR
, gtk
.ICON_SIZE_DIALOG
)
3846 finish_text
= '<big><b>%s</b></big>\n\n%s' % (_(
3847 'An error occurred during account creation'), obj
.reason
)
3848 self
.finish_label
.set_markup(finish_text
)
3849 self
.notebook
.set_current_page(6) # show finish page
3851 if self
.update_progressbar_timeout_id
is not None:
3852 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3854 def on_advanced_button_clicked(self
, widget
):
3855 if 'accounts' in gajim
.interface
.instances
:
3856 gajim
.interface
.instances
['accounts'].window
.present()
3858 gajim
.interface
.instances
['accounts'] = AccountsWindow()
3859 gajim
.interface
.instances
['accounts'].select_account(self
.account
)
3860 self
.window
.destroy()
3862 def on_finish_button_clicked(self
, widget
):
3863 go_online
= self
.xml
.get_object('go_online_checkbutton').get_active()
3864 show_vcard
= self
.xml
.get_object('show_vcard_checkbutton').get_active()
3865 self
.window
.destroy()
3867 gajim
.interface
.show_vcard_when_connect
.append(self
.account
)
3869 gajim
.interface
.roster
.send_status(self
.account
, 'online', '')
3871 def on_username_entry_key_press_event(self
, widget
, event
):
3872 # Check for pressed @ and jump to combobox if found
3873 if event
.keyval
== gtk
.keysyms
.at
:
3874 combobox
= self
.xml
.get_object('server_comboboxentry')
3875 combobox
.grab_focus()
3876 combobox
.child
.set_position(-1)
3879 def on_server_comboboxentry_key_press_event(self
, widget
, event
, combobox
):
3880 # If backspace is pressed in empty field, return to the nick entry field
3881 backspace
= event
.keyval
== gtk
.keysyms
.BackSpace
3882 empty
= len(combobox
.get_active_text()) == 0
3883 if backspace
and empty
and self
.modify
:
3884 username_entry
= self
.xml
.get_object('username_entry')
3885 username_entry
.grab_focus()
3886 username_entry
.set_position(-1)
3889 def get_config(self
, login
, server
, savepass
, password
, anonymous
=False):
3891 config
['name'] = login
3892 config
['hostname'] = server
3893 config
['savepass'] = savepass
3894 config
['password'] = password
3895 config
['resource'] = 'Gajim'
3896 config
['anonymous_auth'] = anonymous
3897 config
['priority'] = 5
3898 config
['autoconnect'] = True
3899 config
['no_log_for'] = ''
3900 config
['sync_with_global_status'] = True
3901 config
['proxy'] = ''
3902 config
['usessl'] = False
3903 config
['use_custom_host'] = False
3904 config
['custom_port'] = 0
3905 config
['custom_host'] = ''
3906 config
['keyname'] = ''
3907 config
['keyid'] = ''
3910 def save_account(self
, login
, server
, savepass
, password
, anonymous
=False):
3911 if self
.account
in gajim
.connections
:
3912 dialogs
.ErrorDialog(_('Account name is in use'),
3913 _('You already have an account using this name.'))
3915 con
= connection
.Connection(self
.account
)
3916 con
.password
= password
3918 config
= self
.get_config(login
, server
, savepass
, password
, anonymous
)
3921 con
.new_account(self
.account
, config
)
3923 gajim
.connections
[self
.account
] = con
3924 self
.create_vars(config
)
3926 def create_vars(self
, config
):
3927 gajim
.config
.add_per('accounts', self
.account
)
3929 if not config
['savepass']:
3930 config
['password'] = ''
3933 gajim
.config
.set_per('accounts', self
.account
, opt
, config
[opt
])
3936 gajim
.interface
.instances
[self
.account
] = {'infos': {}, 'disco': {},
3937 'gc_config': {}, 'search': {}, 'online_dialog': {},
3939 gajim
.interface
.minimized_controls
[self
.account
] = {}
3940 gajim
.connections
[self
.account
].connected
= 0
3941 gajim
.connections
[self
.account
].keepalives
= gajim
.config
.get_per(
3942 'accounts', self
.account
, 'keep_alive_every_foo_secs')
3943 gajim
.groups
[self
.account
] = {}
3944 gajim
.contacts
.add_account(self
.account
)
3945 gajim
.gc_connected
[self
.account
] = {}
3946 gajim
.automatic_rooms
[self
.account
] = {}
3947 gajim
.newly_added
[self
.account
] = []
3948 gajim
.to_be_removed
[self
.account
] = []
3949 gajim
.nicks
[self
.account
] = config
['name']
3950 gajim
.block_signed_in_notifications
[self
.account
] = True
3951 gajim
.sleeper_state
[self
.account
] = 'off'
3952 gajim
.encrypted_chats
[self
.account
] = []
3953 gajim
.last_message_time
[self
.account
] = {}
3954 gajim
.status_before_autoaway
[self
.account
] = ''
3955 gajim
.transport_avatar
[self
.account
] = {}
3956 gajim
.gajim_optional_features
[self
.account
] = []
3957 gajim
.caps_hash
[self
.account
] = ''
3958 # refresh accounts window
3959 if 'accounts' in gajim
.interface
.instances
:
3960 gajim
.interface
.instances
['accounts'].init_accounts()
3962 if len(gajim
.connections
) >= 2:
3963 # Do not merge accounts if only one exists
3964 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
3966 gajim
.interface
.roster
.regroup
= False
3967 gajim
.interface
.roster
.setup_and_draw_roster()
3968 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3969 gajim
.interface
.save_config()
3971 class ManagePEPServicesWindow
:
3972 def __init__(self
, account
):
3973 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_pep_services_window.ui')
3974 self
.window
= self
.xml
.get_object('manage_pep_services_window')
3975 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3976 self
.xml
.get_object('configure_button').set_sensitive(False)
3977 self
.xml
.get_object('delete_button').set_sensitive(False)
3978 self
.xml
.connect_signals(self
)
3979 self
.account
= account
3981 self
.init_services()
3982 self
.xml
.get_object('services_treeview').get_selection().connect(
3983 'changed', self
.on_services_selection_changed
)
3985 gajim
.ged
.register_event_handler('pep-config-received', ged
.GUI1
,
3986 self
._nec
_pep
_config
_received
)
3987 gajim
.ged
.register_event_handler('agent-items-received', ged
.GUI1
,
3988 self
._nec
_agent
_items
_received
)
3990 self
.window
.show_all()
3992 def on_manage_pep_services_window_destroy(self
, widget
):
3994 del gajim
.interface
.instances
[self
.account
]['pep_services']
3995 gajim
.ged
.remove_event_handler('pep-config-received', ged
.GUI1
,
3996 self
._nec
_pep
_config
_received
)
3997 gajim
.ged
.remove_event_handler('agent-items-received', ged
.GUI1
,
3998 self
._nec
_agent
_items
_received
)
4000 def on_close_button_clicked(self
, widget
):
4001 self
.window
.destroy()
4003 def on_services_selection_changed(self
, sel
):
4004 self
.xml
.get_object('configure_button').set_sensitive(True)
4005 self
.xml
.get_object('delete_button').set_sensitive(True)
4007 def init_services(self
):
4008 self
.treeview
= self
.xml
.get_object('services_treeview')
4009 # service, access_model, group
4010 self
.treestore
= gtk
.ListStore(str)
4011 self
.treeview
.set_model(self
.treestore
)
4013 col
= gtk
.TreeViewColumn('Service')
4014 self
.treeview
.append_column(col
)
4016 cellrenderer_text
= gtk
.CellRendererText()
4017 col
.pack_start(cellrenderer_text
)
4018 col
.add_attribute(cellrenderer_text
, 'text', 0)
4020 our_jid
= gajim
.get_jid_from_account(self
.account
)
4021 gajim
.connections
[self
.account
].discoverItems(our_jid
)
4023 def _nec_agent_items_received(self
, obj
):
4024 our_jid
= gajim
.get_jid_from_account(self
.account
)
4025 for item
in obj
.items
:
4026 if 'jid' in item
and item
['jid'] == our_jid
and 'node' in item
:
4027 self
.treestore
.append([item
['node']])
4029 def node_removed(self
, jid
, node
):
4030 if jid
!= gajim
.get_jid_from_account(self
.account
):
4032 model
= self
.treeview
.get_model()
4033 iter_
= model
.get_iter_root()
4035 if model
[iter_
][0] == node
:
4038 iter_
= model
.iter_next(iter_
)
4040 def node_not_removed(self
, jid
, node
, msg
):
4041 if jid
!= gajim
.get_jid_from_account(self
.account
):
4043 dialogs
.WarningDialog(_('PEP node was not removed'),
4044 _('PEP node %(node)s was not removed: %(message)s') % {'node': node
,
4047 def on_delete_button_clicked(self
, widget
):
4048 selection
= self
.treeview
.get_selection()
4051 model
, iter_
= selection
.get_selected()
4052 node
= model
[iter_
][0]
4053 our_jid
= gajim
.get_jid_from_account(self
.account
)
4054 gajim
.connections
[self
.account
].send_pb_delete(our_jid
, node
,
4055 on_ok
=self
.node_removed
, on_fail
=self
.node_not_removed
)
4057 def on_configure_button_clicked(self
, widget
):
4058 selection
= self
.treeview
.get_selection()
4061 model
, iter_
= selection
.get_selected()
4062 node
= model
[iter_
][0]
4063 our_jid
= gajim
.get_jid_from_account(self
.account
)
4064 gajim
.connections
[self
.account
].request_pb_configuration(our_jid
, node
)
4066 def _nec_pep_config_received(self
, obj
):
4067 def on_ok(form
, node
):
4068 form
.type = 'submit'
4069 our_jid
= gajim
.get_jid_from_account(self
.account
)
4070 gajim
.connections
[self
.account
].send_pb_configure(our_jid
, node
, form
)
4071 window
= dialogs
.DataFormWindow(obj
.form
, (on_ok
, obj
.node
))
4072 title
= _('Configure %s') % obj
.node
4073 window
.set_title(title
)
4076 class ManageSoundsWindow
:
4078 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_sounds_window.ui')
4079 self
.window
= self
.xml
.get_object('manage_sounds_window')
4082 self
.sound_tree
= self
.xml
.get_object('sounds_treeview')
4084 # active, event ui name, path to sound file, event_config_name
4085 model
= gtk
.ListStore(bool, str, str, str)
4086 self
.sound_tree
.set_model(model
)
4088 col
= gtk
.TreeViewColumn(_('Active'))
4089 self
.sound_tree
.append_column(col
)
4090 renderer
= gtk
.CellRendererToggle()
4091 renderer
.set_property('activatable', True)
4092 renderer
.connect('toggled', self
.sound_toggled_cb
)
4093 col
.pack_start(renderer
)
4094 col
.set_attributes(renderer
, active
= 0)
4096 col
= gtk
.TreeViewColumn(_('Event'))
4097 self
.sound_tree
.append_column(col
)
4098 renderer
= gtk
.CellRendererText()
4099 col
.pack_start(renderer
)
4100 col
.set_attributes(renderer
, text
= 1)
4102 self
.fill_sound_treeview()
4104 self
.xml
.connect_signals(self
)
4106 self
.sound_tree
.get_model().connect('row-changed',
4107 self
.on_sounds_treemodel_row_changed
)
4109 self
.window
.show_all()
4111 def on_sounds_treemodel_row_changed(self
, model
, path
, iter_
):
4112 sound_event
= model
[iter_
][3].decode('utf-8')
4113 gajim
.config
.set_per('soundevents', sound_event
, 'enabled',
4114 bool(model
[path
][0]))
4115 gajim
.config
.set_per('soundevents', sound_event
, 'path',
4116 model
[iter_
][2].decode('utf-8'))
4117 gajim
.interface
.save_config()
4119 def sound_toggled_cb(self
, cell
, path
):
4120 model
= self
.sound_tree
.get_model()
4121 model
[path
][0] = not model
[path
][0]
4123 def fill_sound_treeview(self
):
4124 model
= self
.sound_tree
.get_model()
4126 model
.set_sort_column_id(1, gtk
.SORT_ASCENDING
)
4128 # NOTE: sounds_ui_names MUST have all items of
4129 # sounds = gajim.config.get_per('soundevents') as keys
4131 'first_message_received': _('First Message Received'),
4132 'next_message_received_focused': _('Next Message Received Focused'),
4133 'next_message_received_unfocused':
4134 _('Next Message Received Unfocused'),
4135 'contact_connected': _('Contact Connected'),
4136 'contact_disconnected': _('Contact Disconnected'),
4137 'message_sent': _('Message Sent'),
4138 'muc_message_highlight': _('Group Chat Message Highlight'),
4139 'muc_message_received': _('Group Chat Message Received'),
4140 'gmail_received': _('GMail Email Received')
4143 for sound_event_config_name
, sound_ui_name
in sounds_dict
.items():
4144 enabled
= gajim
.config
.get_per('soundevents',
4145 sound_event_config_name
, 'enabled')
4146 path
= gajim
.config
.get_per('soundevents',
4147 sound_event_config_name
, 'path')
4148 model
.append((enabled
, sound_ui_name
, path
, sound_event_config_name
))
4150 def on_treeview_sounds_cursor_changed(self
, widget
, data
= None):
4151 (model
, iter_
) = self
.sound_tree
.get_selection().get_selected()
4152 sounds_entry
= self
.xml
.get_object('sounds_entry')
4154 sounds_entry
.set_text('')
4156 path_to_snd_file
= model
[iter_
][2]
4157 sounds_entry
.set_text(path_to_snd_file
)
4159 def on_browse_for_sounds_button_clicked(self
, widget
, data
= None):
4160 (model
, iter_
) = self
.sound_tree
.get_selection().get_selected()
4163 def on_ok(widget
, path_to_snd_file
):
4164 self
.dialog
.destroy()
4165 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4166 if not path_to_snd_file
:
4167 model
[iter_
][2] = ''
4168 self
.xml
.get_object('sounds_entry').set_text('')
4169 model
[iter_
][0] = False
4171 directory
= os
.path
.dirname(path_to_snd_file
)
4172 gajim
.config
.set('last_sounds_dir', directory
)
4173 path_to_snd_file
= helpers
.strip_soundfile_path(path_to_snd_file
)
4174 self
.xml
.get_object('sounds_entry').set_text(path_to_snd_file
)
4176 model
[iter_
][2] = path_to_snd_file
# set new path to sounds_model
4177 model
[iter_
][0] = True # set the sound to enabled
4179 def on_cancel(widget
):
4180 self
.dialog
.destroy()
4182 path_to_snd_file
= model
[iter_
][2].decode('utf-8')
4183 self
.dialog
= dialogs
.SoundChooserDialog(path_to_snd_file
, on_ok
,
4186 def on_sounds_entry_changed(self
, widget
):
4187 path_to_snd_file
= widget
.get_text()
4188 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4189 model
[iter_
][2] = path_to_snd_file
# set new path to sounds_model
4191 def on_play_button_clicked(self
, widget
):
4192 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4195 snd_event_config_name
= model
[iter_
][3]
4196 helpers
.play_sound(snd_event_config_name
)
4198 def on_close_button_clicked(self
, widget
):
4201 def on_manage_sounds_window_delete_event(self
, widget
, event
):
4203 return True # do NOT destroy the window