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_advanced_notifications_button_clicked(self
, widget
):
869 dialogs
.AdvancedNotificationsWindow()
871 def on_play_sounds_checkbutton_toggled(self
, widget
):
872 self
.on_checkbutton_toggled(widget
, 'sounds_on',
873 [self
.xml
.get_object('manage_sounds_button')])
875 def on_manage_sounds_button_clicked(self
, widget
):
876 if self
.sounds_preferences
is None:
877 self
.sounds_preferences
= ManageSoundsWindow()
879 self
.sounds_preferences
.window
.present()
881 def update_text_tags(self
):
883 Update color tags in opened chat windows
885 for ctrl
in self
._get
_all
_controls
():
888 def on_preference_widget_color_set(self
, widget
, text
):
889 color
= widget
.get_color()
890 color_string
= gtkgui_helpers
.make_color_string(color
)
891 gajim
.config
.set(text
, color_string
)
892 self
.update_text_tags()
893 gajim
.interface
.save_config()
895 def on_preference_widget_font_set(self
, widget
, text
):
897 font
= widget
.get_font_name()
900 gajim
.config
.set(text
, font
)
901 self
.update_text_font()
902 gajim
.interface
.save_config()
904 def update_text_font(self
):
906 Update text font in opened chat windows
908 for ctrl
in self
._get
_all
_controls
():
911 def on_incoming_nick_colorbutton_color_set(self
, widget
):
912 self
.on_preference_widget_color_set(widget
, 'inmsgcolor')
914 def on_outgoing_nick_colorbutton_color_set(self
, widget
):
915 self
.on_preference_widget_color_set(widget
, 'outmsgcolor')
917 def on_incoming_msg_colorbutton_color_set(self
, widget
):
918 self
.on_preference_widget_color_set(widget
, 'inmsgtxtcolor')
920 def on_outgoing_msg_colorbutton_color_set(self
, widget
):
921 self
.on_preference_widget_color_set(widget
, 'outmsgtxtcolor')
923 def on_url_msg_colorbutton_color_set(self
, widget
):
924 self
.on_preference_widget_color_set(widget
, 'urlmsgcolor')
926 def on_status_msg_colorbutton_color_set(self
, widget
):
927 self
.on_preference_widget_color_set(widget
, 'statusmsgcolor')
929 def on_conversation_fontbutton_font_set(self
, widget
):
930 self
.on_preference_widget_font_set(widget
, 'conversation_font')
932 def on_default_chat_font_toggled(self
, widget
):
933 font_widget
= self
.xml
.get_object('conversation_fontbutton')
934 if widget
.get_active():
935 font_widget
.set_sensitive(False)
938 font_widget
.set_sensitive(True)
939 self
.on_preference_widget_font_set(font_widget
, 'conversation_font')
941 def draw_color_widgets(self
):
942 col_to_widget
= {'inmsgcolor': 'incoming_nick_colorbutton',
943 'outmsgcolor': 'outgoing_nick_colorbutton',
944 'inmsgtxtcolor': ['incoming_msg_colorbutton',
945 'incoming_msg_checkbutton'],
946 'outmsgtxtcolor': ['outgoing_msg_colorbutton',
947 'outgoing_msg_checkbutton'],
948 'statusmsgcolor': 'status_msg_colorbutton',
949 'urlmsgcolor': 'url_msg_colorbutton'}
950 for c
in col_to_widget
:
951 col
= gajim
.config
.get(c
)
953 if isinstance(col_to_widget
[c
], list):
954 self
.xml
.get_object(col_to_widget
[c
][0]).set_color(
955 gtk
.gdk
.color_parse(col
))
956 self
.xml
.get_object(col_to_widget
[c
][0]).set_sensitive(True)
957 self
.xml
.get_object(col_to_widget
[c
][1]).set_active(True)
959 self
.xml
.get_object(col_to_widget
[c
]).set_color(
960 gtk
.gdk
.color_parse(col
))
962 if isinstance(col_to_widget
[c
], list):
963 self
.xml
.get_object(col_to_widget
[c
][0]).set_color(
964 gtk
.gdk
.color_parse('#000000'))
965 self
.xml
.get_object(col_to_widget
[c
][0]).set_sensitive(False)
966 self
.xml
.get_object(col_to_widget
[c
][1]).set_active(False)
968 self
.xml
.get_object(col_to_widget
[c
]).set_color(
969 gtk
.gdk
.color_parse('#000000'))
971 def on_reset_colors_button_clicked(self
, widget
):
972 col_to_widget
= {'inmsgcolor': 'incoming_nick_colorbutton',
973 'outmsgcolor': 'outgoing_nick_colorbutton',
974 'inmsgtxtcolor': 'incoming_msg_colorbutton',
975 'outmsgtxtcolor': 'outgoing_msg_colorbutton',
976 'statusmsgcolor': 'status_msg_colorbutton',
977 'urlmsgcolor': 'url_msg_colorbutton'}
978 for c
in col_to_widget
:
979 gajim
.config
.set(c
, gajim
.interface
.default_colors
[c
])
980 self
.draw_color_widgets()
982 self
.update_text_tags()
983 gajim
.interface
.save_config()
985 def _set_color(self
, state
, widget_name
, option
):
987 Set color value in prefs and update the UI
990 color
= self
.xml
.get_object(widget_name
).get_color()
991 color_string
= gtkgui_helpers
.make_color_string(color
)
994 gajim
.config
.set(option
, color_string
)
995 gajim
.interface
.save_config()
997 def on_incoming_msg_checkbutton_toggled(self
, widget
):
998 state
= widget
.get_active()
999 self
.xml
.get_object('incoming_msg_colorbutton').set_sensitive(state
)
1000 self
._set
_color
(state
, 'incoming_msg_colorbutton', 'inmsgtxtcolor')
1002 def on_outgoing_msg_checkbutton_toggled(self
, widget
):
1003 state
= widget
.get_active()
1004 self
.xml
.get_object('outgoing_msg_colorbutton').set_sensitive(state
)
1005 self
._set
_color
(state
, 'outgoing_msg_colorbutton', 'outmsgtxtcolor')
1007 def on_auto_away_checkbutton_toggled(self
, widget
):
1008 self
.on_checkbutton_toggled(widget
, 'autoaway',
1009 [self
.auto_away_time_spinbutton
, self
.auto_away_message_entry
])
1011 def on_auto_away_time_spinbutton_value_changed(self
, widget
):
1012 aat
= widget
.get_value_as_int()
1013 gajim
.config
.set('autoawaytime', aat
)
1014 gajim
.interface
.sleeper
= common
.sleepy
.Sleepy(
1015 gajim
.config
.get('autoawaytime') * 60,
1016 gajim
.config
.get('autoxatime') * 60)
1017 gajim
.interface
.save_config()
1019 def on_auto_away_message_entry_changed(self
, widget
):
1020 gajim
.config
.set('autoaway_message', widget
.get_text().decode('utf-8'))
1022 def on_auto_xa_checkbutton_toggled(self
, widget
):
1023 self
.on_checkbutton_toggled(widget
, 'autoxa',
1024 [self
.auto_xa_time_spinbutton
, self
.auto_xa_message_entry
])
1026 def on_auto_xa_time_spinbutton_value_changed(self
, widget
):
1027 axt
= widget
.get_value_as_int()
1028 gajim
.config
.set('autoxatime', axt
)
1029 gajim
.interface
.sleeper
= common
.sleepy
.Sleepy(
1030 gajim
.config
.get('autoawaytime') * 60,
1031 gajim
.config
.get('autoxatime') * 60)
1032 gajim
.interface
.save_config()
1034 def on_auto_xa_message_entry_changed(self
, widget
):
1035 gajim
.config
.set('autoxa_message', widget
.get_text().decode('utf-8'))
1037 def on_prompt_online_status_message_checkbutton_toggled(self
, widget
):
1038 self
.on_checkbutton_toggled(widget
, 'ask_online_status')
1040 def on_prompt_offline_status_message_checkbutton_toggled(self
, widget
):
1041 self
.on_checkbutton_toggled(widget
, 'ask_offline_status')
1043 def fill_default_msg_treeview(self
):
1044 model
= self
.default_msg_tree
.get_model()
1047 for status_
in gajim
.config
.get_per('defaultstatusmsg'):
1048 status
.append(status_
)
1050 for status_
in status
:
1051 msg
= gajim
.config
.get_per('defaultstatusmsg', status_
, 'message')
1052 msg
= helpers
.from_one_line(msg
)
1053 enabled
= gajim
.config
.get_per('defaultstatusmsg', status_
, 'enabled')
1054 iter_
= model
.append()
1055 uf_show
= helpers
.get_uf_show(status_
)
1056 model
.set(iter_
, 0, status_
, 1, uf_show
, 2, msg
, 3, enabled
)
1058 def on_default_msg_cell_edited(self
, cell
, row
, new_text
):
1059 model
= self
.default_msg_tree
.get_model()
1060 iter_
= model
.get_iter_from_string(row
)
1061 model
.set_value(iter_
, 2, new_text
)
1063 def default_msg_toggled_cb(self
, cell
, path
):
1064 model
= self
.default_msg_tree
.get_model()
1065 model
[path
][3] = not model
[path
][3]
1067 def on_default_msg_treemodel_row_changed(self
, model
, path
, iter_
):
1068 status
= model
[iter_
][0]
1069 message
= model
[iter_
][2].decode('utf-8')
1070 message
= helpers
.to_one_line(message
)
1071 gajim
.config
.set_per('defaultstatusmsg', status
, 'enabled',
1073 gajim
.config
.set_per('defaultstatusmsg', status
, 'message', message
)
1075 def on_default_status_expander_activate(self
, expander
):
1076 eventbox
= self
.xml
.get_object('default_status_eventbox')
1077 vbox
= self
.xml
.get_object('status_vbox')
1078 vbox
.set_child_packing(eventbox
, not expander
.get_expanded(), True, 0,
1081 def save_status_messages(self
, model
):
1082 for msg
in gajim
.config
.get_per('statusmsg'):
1083 gajim
.config
.del_per('statusmsg', msg
)
1084 iter_
= model
.get_iter_first()
1086 val
= model
[iter_
][0].decode('utf-8')
1087 if model
[iter_
][1]: # we have a preset message
1088 if not val
: # no title, use message text for title
1089 val
= model
[iter_
][1]
1090 gajim
.config
.add_per('statusmsg', val
)
1091 msg
= helpers
.to_one_line(model
[iter_
][1].decode('utf-8'))
1092 gajim
.config
.set_per('statusmsg', val
, 'message', msg
)
1094 # store mood / activity
1095 for subname
in ('activity', 'subactivity', 'activity_text',
1096 'mood', 'mood_text'):
1097 gajim
.config
.set_per('statusmsg', val
, subname
,
1098 model
[iter_
][i
].decode('utf-8'))
1100 iter_
= model
.iter_next(iter_
)
1101 gajim
.interface
.save_config()
1103 def on_msg_treemodel_row_changed(self
, model
, path
, iter_
):
1104 self
.save_status_messages(model
)
1106 def on_msg_treemodel_row_deleted(self
, model
, path
):
1107 self
.save_status_messages(model
)
1109 def on_av_combobox_changed(self
, combobox
, config_name
):
1110 model
= combobox
.get_model()
1111 active
= combobox
.get_active()
1112 device
= model
[active
][1].decode('utf-8')
1113 gajim
.config
.set(config_name
, device
)
1115 def on_audio_input_combobox_changed(self
, widget
):
1116 self
.on_av_combobox_changed(widget
, 'audio_input_device')
1118 def on_audio_output_combobox_changed(self
, widget
):
1119 self
.on_av_combobox_changed(widget
, 'audio_output_device')
1121 def on_video_input_combobox_changed(self
, widget
):
1122 self
.on_av_combobox_changed(widget
, 'video_input_device')
1124 def on_video_output_combobox_changed(self
, widget
):
1125 self
.on_av_combobox_changed(widget
, 'video_output_device')
1127 def on_video_framerate_combobox_changed(self
, widget
):
1128 self
.on_av_combobox_changed(widget
, 'video_framerate')
1130 def on_video_size_combobox_changed(self
, widget
):
1131 self
.on_av_combobox_changed(widget
, 'video_size')
1133 def on_stun_checkbutton_toggled(self
, widget
):
1134 self
.on_checkbutton_toggled(widget
, 'use_stun_server',
1135 [self
.xml
.get_object('stun_server_entry')])
1137 def stun_server_entry_changed(self
, widget
):
1138 gajim
.config
.set('stun_server', widget
.get_text().decode('utf-8'))
1140 def on_applications_combobox_changed(self
, widget
):
1141 if widget
.get_active() == 0:
1142 gajim
.config
.set('autodetect_browser_mailer', True)
1143 self
.xml
.get_object('custom_apps_frame').hide()
1144 elif widget
.get_active() == 1:
1145 gajim
.config
.set('autodetect_browser_mailer', False)
1146 self
.xml
.get_object('custom_apps_frame').show()
1147 gajim
.interface
.save_config()
1149 def on_custom_browser_entry_changed(self
, widget
):
1150 gajim
.config
.set('custombrowser', widget
.get_text().decode('utf-8'))
1151 gajim
.interface
.save_config()
1153 def on_custom_mail_client_entry_changed(self
, widget
):
1154 gajim
.config
.set('custommailapp', widget
.get_text().decode('utf-8'))
1155 gajim
.interface
.save_config()
1157 def on_custom_file_manager_entry_changed(self
, widget
):
1158 gajim
.config
.set('custom_file_manager', widget
.get_text().decode('utf-8'))
1159 gajim
.interface
.save_config()
1161 def on_log_show_changes_checkbutton_toggled(self
, widget
):
1162 self
.on_checkbutton_toggled(widget
, 'log_contact_status_changes')
1164 def on_log_encrypted_chats_checkbutton_toggled(self
, widget
):
1165 widget
.set_inconsistent(False)
1166 self
.on_per_account_checkbutton_toggled(widget
, 'log_encrypted_sessions')
1168 def on_send_os_info_checkbutton_toggled(self
, widget
):
1169 widget
.set_inconsistent(False)
1170 self
.on_per_account_checkbutton_toggled(widget
, 'send_os_info')
1172 def on_send_idle_time_checkbutton_toggled(self
, widget
):
1173 widget
.set_inconsistent(False)
1174 self
.on_per_account_checkbutton_toggled(widget
, 'send_idle_time')
1176 def on_check_default_client_checkbutton_toggled(self
, widget
):
1177 self
.on_checkbutton_toggled(widget
, 'check_if_gajim_is_default')
1179 def on_notify_gmail_checkbutton_toggled(self
, widget
):
1180 self
.on_checkbutton_toggled(widget
, 'notify_on_new_gmail_email')
1182 def on_notify_gmail_extra_checkbutton_toggled(self
, widget
):
1183 self
.on_checkbutton_toggled(widget
, 'notify_on_new_gmail_email_extra')
1185 def fill_msg_treeview(self
):
1186 self
.xml
.get_object('delete_msg_button').set_sensitive(False)
1187 model
= self
.msg_tree
.get_model()
1190 for msg_name
in gajim
.config
.get_per('statusmsg'):
1191 if msg_name
.startswith('_last_'):
1193 preset_status
.append(msg_name
)
1194 preset_status
.sort()
1195 for msg_name
in preset_status
:
1196 msg_text
= gajim
.config
.get_per('statusmsg', msg_name
, 'message')
1197 msg_text
= helpers
.from_one_line(msg_text
)
1198 activity
= gajim
.config
.get_per('statusmsg', msg_name
, 'activity')
1199 subactivity
= gajim
.config
.get_per('statusmsg', msg_name
,
1201 activity_text
= gajim
.config
.get_per('statusmsg', msg_name
,
1203 mood
= gajim
.config
.get_per('statusmsg', msg_name
, 'mood')
1204 mood_text
= gajim
.config
.get_per('statusmsg', msg_name
, 'mood_text')
1205 iter_
= model
.append()
1206 model
.set(iter_
, 0, msg_name
, 1, msg_text
, 2, activity
, 3,
1207 subactivity
, 4, activity_text
, 5, mood
, 6, mood_text
)
1209 def on_msg_cell_edited(self
, cell
, row
, new_text
):
1210 model
= self
.msg_tree
.get_model()
1211 iter_
= model
.get_iter_from_string(row
)
1212 model
.set_value(iter_
, 0, new_text
)
1214 def on_msg_treeview_cursor_changed(self
, widget
, data
= None):
1215 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1218 self
.xml
.get_object('delete_msg_button').set_sensitive(True)
1219 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1220 msg
= model
[iter_
][1]
1223 def on_new_msg_button_clicked(self
, widget
, data
= None):
1224 model
= self
.msg_tree
.get_model()
1225 iter_
= model
.append()
1226 model
.set(iter_
, 0, _('status message title'), 1, _('status message text'))
1227 self
.msg_tree
.set_cursor(model
.get_path(iter_
))
1229 def on_delete_msg_button_clicked(self
, widget
, data
= None):
1230 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1233 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1236 self
.xml
.get_object('delete_msg_button').set_sensitive(False)
1238 def on_msg_textview_changed(self
, widget
, data
= None):
1239 (model
, iter_
) = self
.msg_tree
.get_selection().get_selected()
1242 buf
= self
.xml
.get_object('msg_textview').get_buffer()
1243 first_iter
, end_iter
= buf
.get_bounds()
1244 model
.set_value(iter_
, 1, buf
.get_text(first_iter
, end_iter
))
1246 def on_msg_treeview_key_press_event(self
, widget
, event
):
1247 if event
.keyval
== gtk
.keysyms
.Delete
:
1248 self
.on_delete_msg_button_clicked(widget
)
1250 def on_open_advanced_editor_button_clicked(self
, widget
, data
= None):
1251 if 'advanced_config' in gajim
.interface
.instances
:
1252 gajim
.interface
.instances
['advanced_config'].window
.present()
1254 gajim
.interface
.instances
['advanced_config'] = \
1255 dialogs
.AdvancedConfigurationWindow()
1257 #---------- ManageProxiesWindow class -------------#
1258 class ManageProxiesWindow
:
1260 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_proxies_window.ui')
1261 self
.window
= self
.xml
.get_object('manage_proxies_window')
1262 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
1263 self
.proxies_treeview
= self
.xml
.get_object('proxies_treeview')
1264 self
.proxyname_entry
= self
.xml
.get_object('proxyname_entry')
1265 self
.proxytype_combobox
= self
.xml
.get_object('proxytype_combobox')
1268 self
.block_signal
= False
1269 self
.xml
.connect_signals(self
)
1270 self
.window
.show_all()
1271 # hide the BOSH fields by default
1272 self
.show_bosh_fields()
1274 def show_bosh_fields(self
, show
=True):
1276 self
.xml
.get_object('boshuri_entry').show()
1277 self
.xml
.get_object('boshuri_label').show()
1278 self
.xml
.get_object('boshuseproxy_checkbutton').show()
1280 cb
= self
.xml
.get_object('boshuseproxy_checkbutton')
1283 self
.on_boshuseproxy_checkbutton_toggled(cb
)
1284 self
.xml
.get_object('boshuri_entry').hide()
1285 self
.xml
.get_object('boshuri_label').hide()
1288 def fill_proxies_treeview(self
):
1289 model
= self
.proxies_treeview
.get_model()
1291 iter_
= model
.append()
1292 model
.set(iter_
, 0, _('None'))
1293 for p
in gajim
.config
.get_per('proxies'):
1294 iter_
= model
.append()
1295 model
.set(iter_
, 0, p
)
1297 def init_list(self
):
1298 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1299 self
.proxytype_combobox
.set_sensitive(False)
1300 self
.xml
.get_object('proxy_table').set_sensitive(False)
1301 model
= gtk
.ListStore(str)
1302 self
.proxies_treeview
.set_model(model
)
1303 col
= gtk
.TreeViewColumn('Proxies')
1304 self
.proxies_treeview
.append_column(col
)
1305 renderer
= gtk
.CellRendererText()
1306 col
.pack_start(renderer
, True)
1307 col
.set_attributes(renderer
, text
= 0)
1308 self
.fill_proxies_treeview()
1309 self
.xml
.get_object('proxytype_combobox').set_active(0)
1311 def on_manage_proxies_window_destroy(self
, widget
):
1312 if 'accounts' in gajim
.interface
.instances
:
1313 gajim
.interface
.instances
['accounts'].\
1315 del gajim
.interface
.instances
['manage_proxies']
1317 def on_add_proxy_button_clicked(self
, widget
):
1318 model
= self
.proxies_treeview
.get_model()
1319 proxies
= gajim
.config
.get_per('proxies')
1321 while ('proxy' + unicode(i
)) in proxies
:
1323 iter_
= model
.append()
1324 model
.set(iter_
, 0, 'proxy' + unicode(i
))
1325 gajim
.config
.add_per('proxies', 'proxy' + unicode(i
))
1326 self
.proxies_treeview
.set_cursor(model
.get_path(iter_
))
1328 def on_remove_proxy_button_clicked(self
, widget
):
1329 (model
, iter_
) = self
.proxies_treeview
.get_selection().get_selected()
1332 proxy
= model
[iter_
][0].decode('utf-8')
1334 gajim
.config
.del_per('proxies', proxy
)
1335 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1336 self
.block_signal
= True
1337 self
.on_proxies_treeview_cursor_changed(self
.proxies_treeview
)
1338 self
.block_signal
= False
1340 def on_close_button_clicked(self
, widget
):
1341 self
.window
.destroy()
1343 def on_useauth_checkbutton_toggled(self
, widget
):
1344 if self
.block_signal
:
1346 act
= widget
.get_active()
1347 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1348 gajim
.config
.set_per('proxies', proxy
, 'useauth', act
)
1349 self
.xml
.get_object('proxyuser_entry').set_sensitive(act
)
1350 self
.xml
.get_object('proxypass_entry').set_sensitive(act
)
1352 def on_boshuseproxy_checkbutton_toggled(self
, widget
):
1353 if self
.block_signal
:
1355 act
= widget
.get_active()
1356 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1357 gajim
.config
.set_per('proxies', proxy
, 'bosh_useproxy', act
)
1358 self
.xml
.get_object('proxyhost_entry').set_sensitive(act
)
1359 self
.xml
.get_object('proxyport_entry').set_sensitive(act
)
1361 def on_proxies_treeview_cursor_changed(self
, widget
):
1362 #FIXME: check if off proxy settings are correct (see
1363 # http://trac.gajim.org/changeset/1921#file2 line 1221
1364 proxyhost_entry
= self
.xml
.get_object('proxyhost_entry')
1365 proxyport_entry
= self
.xml
.get_object('proxyport_entry')
1366 proxyuser_entry
= self
.xml
.get_object('proxyuser_entry')
1367 proxypass_entry
= self
.xml
.get_object('proxypass_entry')
1368 boshuri_entry
= self
.xml
.get_object('boshuri_entry')
1369 useauth_checkbutton
= self
.xml
.get_object('useauth_checkbutton')
1370 boshuseproxy_checkbutton
= self
.xml
.get_object('boshuseproxy_checkbutton')
1371 self
.block_signal
= True
1372 proxyhost_entry
.set_text('')
1373 proxyport_entry
.set_text('')
1374 proxyuser_entry
.set_text('')
1375 proxypass_entry
.set_text('')
1376 boshuri_entry
.set_text('')
1378 #boshuseproxy_checkbutton.set_active(False)
1379 #self.on_boshuseproxy_checkbutton_toggled(boshuseproxy_checkbutton)
1381 #useauth_checkbutton.set_active(False)
1382 #self.on_useauth_checkbutton_toggled(useauth_checkbutton)
1384 (model
, iter_
) = widget
.get_selection().get_selected()
1386 self
.xml
.get_object('proxyname_entry').set_text('')
1387 self
.xml
.get_object('proxytype_combobox').set_sensitive(False)
1388 self
.xml
.get_object('proxy_table').set_sensitive(False)
1389 self
.block_signal
= False
1392 proxy
= model
[iter_
][0]
1393 self
.xml
.get_object('proxyname_entry').set_text(proxy
)
1395 if proxy
== _('None'): # special proxy None
1396 self
.show_bosh_fields(False)
1397 self
.proxyname_entry
.set_editable(False)
1398 self
.xml
.get_object('remove_proxy_button').set_sensitive(False)
1399 self
.xml
.get_object('proxytype_combobox').set_sensitive(False)
1400 self
.xml
.get_object('proxy_table').set_sensitive(False)
1402 proxytype
= gajim
.config
.get_per('proxies', proxy
, 'type')
1404 self
.show_bosh_fields(proxytype
=='bosh')
1406 self
.proxyname_entry
.set_editable(True)
1407 self
.xml
.get_object('remove_proxy_button').set_sensitive(True)
1408 self
.xml
.get_object('proxytype_combobox').set_sensitive(True)
1409 self
.xml
.get_object('proxy_table').set_sensitive(True)
1410 proxyhost_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1412 proxyport_entry
.set_text(unicode(gajim
.config
.get_per('proxies',
1414 proxyuser_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1416 proxypass_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1418 boshuri_entry
.set_text(gajim
.config
.get_per('proxies', proxy
,
1420 types
= ['http', 'socks5', 'bosh']
1421 self
.proxytype_combobox
.set_active(types
.index(proxytype
))
1422 boshuseproxy_checkbutton
.set_active(
1423 gajim
.config
.get_per('proxies', proxy
, 'bosh_useproxy'))
1424 useauth_checkbutton
.set_active(
1425 gajim
.config
.get_per('proxies', proxy
, 'useauth'))
1426 self
.block_signal
= False
1428 def on_proxies_treeview_key_press_event(self
, widget
, event
):
1429 if event
.keyval
== gtk
.keysyms
.Delete
:
1430 self
.on_remove_proxy_button_clicked(widget
)
1432 def on_proxyname_entry_changed(self
, widget
):
1433 if self
.block_signal
:
1435 (model
, iter_
) = self
.proxies_treeview
.get_selection().get_selected()
1438 old_name
= model
.get_value(iter_
, 0).decode('utf-8')
1439 new_name
= widget
.get_text().decode('utf-8')
1442 if new_name
== old_name
:
1444 config
= gajim
.config
.get_per('proxies', old_name
)
1445 gajim
.config
.del_per('proxies', old_name
)
1446 gajim
.config
.add_per('proxies', new_name
)
1447 for option
in config
:
1448 gajim
.config
.set_per('proxies', new_name
, option
,
1449 config
[option
][common
.config
.OPT_VAL
])
1450 model
.set_value(iter_
, 0, new_name
)
1452 def on_proxytype_combobox_changed(self
, widget
):
1453 if self
.block_signal
:
1455 types
= ['http', 'socks5', 'bosh']
1456 type_
= self
.proxytype_combobox
.get_active()
1457 self
.show_bosh_fields(types
[type_
]=='bosh')
1458 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1459 gajim
.config
.set_per('proxies', proxy
, 'type', types
[type_
])
1461 def on_proxyhost_entry_changed(self
, widget
):
1462 if self
.block_signal
:
1464 value
= widget
.get_text().decode('utf-8')
1465 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1466 gajim
.config
.set_per('proxies', proxy
, 'host', value
)
1468 def on_proxyport_entry_changed(self
, widget
):
1469 if self
.block_signal
:
1471 value
= widget
.get_text().decode('utf-8')
1472 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1473 gajim
.config
.set_per('proxies', proxy
, 'port', value
)
1475 def on_proxyuser_entry_changed(self
, widget
):
1476 if self
.block_signal
:
1478 value
= widget
.get_text().decode('utf-8')
1479 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1480 gajim
.config
.set_per('proxies', proxy
, 'user', value
)
1482 def on_boshuri_entry_changed(self
, widget
):
1483 if self
.block_signal
:
1485 value
= widget
.get_text().decode('utf-8')
1486 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1487 gajim
.config
.set_per('proxies', proxy
, 'bosh_uri', value
)
1489 def on_proxypass_entry_changed(self
, widget
):
1490 if self
.block_signal
:
1492 value
= widget
.get_text().decode('utf-8')
1493 proxy
= self
.proxyname_entry
.get_text().decode('utf-8')
1494 gajim
.config
.set_per('proxies', proxy
, 'pass', value
)
1497 #---------- AccountsWindow class -------------#
1498 class AccountsWindow
:
1500 Class for accounts window: list of accounts
1503 def on_accounts_window_destroy(self
, widget
):
1504 del gajim
.interface
.instances
['accounts']
1506 def on_close_button_clicked(self
, widget
):
1507 self
.check_resend_relog()
1508 self
.window
.destroy()
1511 self
.xml
= gtkgui_helpers
.get_gtk_builder('accounts_window.ui')
1512 self
.window
= self
.xml
.get_object('accounts_window')
1513 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
1514 self
.accounts_treeview
= self
.xml
.get_object('accounts_treeview')
1515 self
.remove_button
= self
.xml
.get_object('remove_button')
1516 self
.rename_button
= self
.xml
.get_object('rename_button')
1517 path_to_kbd_input_img
= gtkgui_helpers
.get_icon_path('gajim-kbd_input')
1518 img
= self
.xml
.get_object('rename_image')
1519 img
.set_from_file(path_to_kbd_input_img
)
1520 self
.notebook
= self
.xml
.get_object('notebook')
1522 model
= gtk
.ListStore(str)
1523 self
.accounts_treeview
.set_model(model
)
1525 renderer
= gtk
.CellRendererText()
1526 self
.accounts_treeview
.insert_column_with_attributes(-1, _('Name'),
1529 self
.current_account
= None
1530 # When we fill info, we don't want to handle the changed signals
1531 self
.ignore_events
= False
1532 self
.need_relogin
= False
1533 self
.resend_presence
= False
1535 self
.update_proxy_list()
1536 self
.xml
.connect_signals(self
)
1537 self
.init_accounts()
1538 self
.window
.show_all()
1541 st
= gajim
.config
.get('mergeaccounts')
1542 checkbutton
= self
.xml
.get_object('merge_checkbutton')
1543 checkbutton
.set_active(st
)
1544 # prevent roster redraws by connecting the signal after button state is
1546 checkbutton
.connect('toggled', self
.on_merge_checkbutton_toggled
)
1548 self
.avahi_available
= True
1552 self
.avahi_available
= False
1554 def on_accounts_window_key_press_event(self
, widget
, event
):
1555 if event
.keyval
== gtk
.keysyms
.Escape
:
1556 self
.check_resend_relog()
1557 self
.window
.destroy()
1559 def select_account(self
, account
):
1560 model
= self
.accounts_treeview
.get_model()
1561 iter_
= model
.get_iter_root()
1563 acct
= model
[iter_
][0].decode('utf-8')
1565 self
.accounts_treeview
.set_cursor(model
.get_path(iter_
))
1567 iter_
= model
.iter_next(iter_
)
1569 def init_accounts(self
):
1571 Initialize listStore with existing accounts
1573 self
.remove_button
.set_sensitive(False)
1574 self
.rename_button
.set_sensitive(False)
1575 self
.current_account
= None
1576 model
= self
.accounts_treeview
.get_model()
1578 for account
in gajim
.config
.get_per('accounts'):
1579 iter_
= model
.append()
1580 model
.set(iter_
, 0, account
)
1582 def resend(self
, account
):
1583 if not account
in gajim
.connections
:
1585 show
= gajim
.SHOW_LIST
[gajim
.connections
[account
].connected
]
1586 status
= gajim
.connections
[account
].status
1587 gajim
.connections
[account
].change_status(show
, status
)
1589 def check_resend_relog(self
):
1590 if self
.need_relogin
and self
.current_account
== gajim
.ZEROCONF_ACC_NAME
:
1591 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
:
1592 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].update_details()
1595 elif self
.need_relogin
and self
.current_account
and \
1596 gajim
.connections
[self
.current_account
].connected
> 0:
1597 def login(account
, show_before
, status_before
):
1599 Login with previous status
1601 # first make sure connection is really closed,
1602 # 0.5 may not be enough
1603 gajim
.connections
[account
].disconnect(True)
1604 gajim
.interface
.roster
.send_status(account
, show_before
,
1608 self
.dialog
.destroy()
1609 show_before
= gajim
.SHOW_LIST
[gajim
.connections
[account
].connected
]
1610 status_before
= gajim
.connections
[account
].status
1611 gajim
.interface
.roster
.send_status(account
, 'offline',
1612 _('Be right back.'))
1613 gobject
.timeout_add(500, login
, account
, show_before
, status_before
)
1615 def on_yes(checked
, account
):
1618 if self
.resend_presence
:
1619 self
.resend(account
)
1620 if self
.current_account
in gajim
.connections
:
1621 self
.dialog
= dialogs
.YesNoDialog(_('Relogin now?'),
1622 _('If you want all the changes to apply instantly, '
1623 'you must relogin.'), on_response_yes
=(on_yes
,
1624 self
.current_account
), on_response_no
=(on_no
,
1625 self
.current_account
))
1626 elif self
.resend_presence
:
1627 self
.resend(self
.current_account
)
1629 self
.need_relogin
= False
1630 self
.resend_presence
= False
1632 def on_accounts_treeview_cursor_changed(self
, widget
):
1634 Activate modify buttons when a row is selected, update accounts info
1636 sel
= self
.accounts_treeview
.get_selection()
1637 (model
, iter_
) = sel
.get_selected()
1639 account
= model
[iter_
][0].decode('utf-8')
1642 if self
.current_account
and self
.current_account
== account
:
1643 # We're comming back to our current account, no need to update widgets
1645 # Save config for previous account if needed cause focus_out event is
1646 # called after the changed event
1647 if self
.current_account
and self
.window
.get_focus():
1648 focused_widget
= self
.window
.get_focus()
1649 focused_widget_name
= focused_widget
.get_name()
1650 if focused_widget_name
in ('jid_entry1', 'resource_entry1',
1651 'custom_port_entry', 'cert_entry1'):
1652 if focused_widget_name
== 'jid_entry1':
1653 func
= self
.on_jid_entry1_focus_out_event
1654 elif focused_widget_name
== 'resource_entry1':
1655 func
= self
.on_resource_entry1_focus_out_event
1656 elif focused_widget_name
== 'custom_port_entry':
1657 func
= self
.on_custom_port_entry_focus_out_event
1658 elif focused_widget_name
== 'cert_entry1':
1659 func
= self
.on_cert_entry1_focus_out_event
1660 if func(focused_widget
, None):
1661 # Error detected in entry, don't change account, re-put cursor on
1663 self
.select_account(self
.current_account
)
1665 self
.window
.set_focus(widget
)
1667 self
.check_resend_relog()
1670 self
.remove_button
.set_sensitive(True)
1671 self
.rename_button
.set_sensitive(True)
1673 self
.remove_button
.set_sensitive(False)
1674 self
.rename_button
.set_sensitive(False)
1676 self
.current_account
= account
1677 if account
== gajim
.ZEROCONF_ACC_NAME
:
1678 self
.remove_button
.set_sensitive(False)
1680 self
.update_proxy_list()
1682 def on_browse_for_client_cert_button_clicked(self
, widget
, data
=None):
1683 def on_ok(widget
, path_to_clientcert_file
):
1684 self
.dialog
.destroy()
1685 if not path_to_clientcert_file
:
1687 self
.xml
.get_object('cert_entry1').set_text(path_to_clientcert_file
)
1688 gajim
.config
.set_per('accounts', self
.current_account
,
1689 'client_cert', path_to_clientcert_file
)
1691 def on_cancel(widget
):
1692 self
.dialog
.destroy()
1694 path_to_clientcert_file
= self
.xml
.get_object('cert_entry1').get_text()
1695 self
.dialog
= dialogs
.ClientCertChooserDialog(path_to_clientcert_file
,
1698 def update_proxy_list(self
):
1699 if self
.current_account
:
1700 our_proxy
= gajim
.config
.get_per('accounts', self
.current_account
,
1706 our_proxy
= _('None')
1707 proxy_combobox
= self
.xml
.get_object('proxies_combobox1')
1708 model
= gtk
.ListStore(str)
1709 proxy_combobox
.set_model(model
)
1710 l
= gajim
.config
.get_per('proxies')
1711 l
.insert(0, _('None'))
1712 for i
in xrange(len(l
)):
1713 model
.append([l
[i
]])
1714 if our_proxy
== l
[i
]:
1715 proxy_combobox
.set_active(i
)
1717 def init_account(self
):
1718 if not self
.current_account
:
1719 self
.notebook
.set_current_page(0)
1721 if gajim
.config
.get_per('accounts', self
.current_account
, 'is_zeroconf'):
1722 self
.ignore_events
= True
1723 self
.init_zeroconf_account()
1724 self
.ignore_events
= False
1725 self
.notebook
.set_current_page(2)
1727 self
.ignore_events
= True
1728 self
.init_normal_account()
1729 self
.ignore_events
= False
1730 self
.notebook
.set_current_page(1)
1732 def init_zeroconf_account(self
):
1733 active
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1735 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_active(active
)
1736 if not gajim
.HAVE_ZEROCONF
:
1737 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_sensitive(
1739 self
.xml
.get_object('zeroconf_notebook').set_sensitive(active
)
1741 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1743 self
.xml
.get_object('autoconnect_checkbutton2').set_active(st
)
1745 list_no_log_for
= gajim
.config
.get_per('accounts',
1746 gajim
.ZEROCONF_ACC_NAME
, 'no_log_for').split()
1747 if gajim
.ZEROCONF_ACC_NAME
in list_no_log_for
:
1748 self
.xml
.get_object('log_history_checkbutton2').set_active(0)
1750 self
.xml
.get_object('log_history_checkbutton2').set_active(1)
1752 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1753 'sync_with_global_status')
1754 self
.xml
.get_object('sync_with_global_status_checkbutton2').set_active(st
)
1756 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1758 self
.xml
.get_object('custom_port_checkbutton2').set_active(st
)
1759 self
.xml
.get_object('custom_port_entry2').set_sensitive(st
)
1761 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1764 gajim
.config
.set_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1765 'custom_port', '5298')
1767 self
.xml
.get_object('custom_port_entry2').set_text(str(st
))
1770 gpg_key_label
= self
.xml
.get_object('gpg_key_label2')
1771 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
and \
1772 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].gpg
:
1773 self
.xml
.get_object('gpg_choose_button2').set_sensitive(True)
1774 self
.init_account_gpg()
1776 gpg_key_label
.set_text(_('OpenPGP is not usable on this computer'))
1777 self
.xml
.get_object('gpg_choose_button2').set_sensitive(False)
1779 for opt
in ('first_name', 'last_name', 'jabber_id', 'email'):
1780 st
= gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
1782 self
.xml
.get_object(opt
+ '_entry2').set_text(st
)
1784 def init_account_gpg(self
):
1785 account
= self
.current_account
1786 keyid
= gajim
.config
.get_per('accounts', account
, 'keyid')
1787 keyname
= gajim
.config
.get_per('accounts', account
, 'keyname')
1788 use_gpg_agent
= gajim
.config
.get('use_gpg_agent')
1790 if account
== gajim
.ZEROCONF_ACC_NAME
:
1791 widget_name_add
= '2'
1793 widget_name_add
= '1'
1795 gpg_key_label
= self
.xml
.get_object('gpg_key_label' + widget_name_add
)
1796 gpg_name_label
= self
.xml
.get_object('gpg_name_label' + widget_name_add
)
1797 use_gpg_agent_checkbutton
= self
.xml
.get_object(
1798 'use_gpg_agent_checkbutton' + widget_name_add
)
1801 use_gpg_agent_checkbutton
.set_sensitive(False)
1802 gpg_key_label
.set_text(_('No key selected'))
1803 gpg_name_label
.set_text('')
1806 gpg_key_label
.set_text(keyid
)
1807 gpg_name_label
.set_text(keyname
)
1808 use_gpg_agent_checkbutton
.set_sensitive(True)
1809 use_gpg_agent_checkbutton
.set_active(use_gpg_agent
)
1811 def draw_normal_jid(self
):
1812 account
= self
.current_account
1813 self
.ignore_events
= True
1814 active
= gajim
.config
.get_per('accounts', account
, 'active')
1815 self
.xml
.get_object('enable_checkbutton1').set_active(active
)
1816 self
.xml
.get_object('normal_notebook1').set_sensitive(active
)
1817 if gajim
.config
.get_per('accounts', account
, 'anonymous_auth'):
1818 self
.xml
.get_object('anonymous_checkbutton1').set_active(True)
1819 self
.xml
.get_object('jid_label1').set_text(_('Server:'))
1820 save_password
= self
.xml
.get_object('save_password_checkbutton1')
1821 save_password
.set_active(False)
1822 save_password
.set_sensitive(False)
1823 password_entry
= self
.xml
.get_object('password_entry1')
1824 password_entry
.set_text('')
1825 password_entry
.set_sensitive(False)
1826 jid
= gajim
.config
.get_per('accounts', account
, 'hostname')
1828 self
.xml
.get_object('anonymous_checkbutton1').set_active(False)
1829 self
.xml
.get_object('jid_label1').set_text(_('Jabber ID:'))
1830 savepass
= gajim
.config
.get_per('accounts', account
, 'savepass')
1831 save_password
= self
.xml
.get_object('save_password_checkbutton1')
1832 save_password
.set_sensitive(True)
1833 save_password
.set_active(savepass
)
1834 password_entry
= self
.xml
.get_object('password_entry1')
1836 passstr
= passwords
.get_password(account
) or ''
1837 password_entry
.set_sensitive(True)
1840 password_entry
.set_sensitive(False)
1841 password_entry
.set_text(passstr
)
1843 jid
= gajim
.config
.get_per('accounts', account
, 'name') \
1844 + '@' + gajim
.config
.get_per('accounts', account
, 'hostname')
1845 self
.xml
.get_object('jid_entry1').set_text(jid
)
1846 self
.ignore_events
= False
1848 def init_normal_account(self
):
1849 account
= self
.current_account
1851 self
.draw_normal_jid()
1852 self
.xml
.get_object('resource_entry1').set_text(gajim
.config
.get_per(
1853 'accounts', account
, 'resource'))
1855 client_cert
= gajim
.config
.get_per('accounts', account
, 'client_cert')
1856 self
.xml
.get_object('cert_entry1').set_text(client_cert
)
1858 self
.xml
.get_object('adjust_priority_with_status_checkbutton1').\
1859 set_active(gajim
.config
.get_per('accounts', account
,
1860 'adjust_priority_with_status'))
1861 spinbutton
= self
.xml
.get_object('priority_spinbutton1')
1862 if gajim
.config
.get('enable_negative_priority'):
1863 spinbutton
.set_range(-128, 127)
1865 spinbutton
.set_range(0, 127)
1866 spinbutton
.set_value(gajim
.config
.get_per('accounts', account
,
1870 use_env_http_proxy
= gajim
.config
.get_per('accounts', account
,
1871 'use_env_http_proxy')
1872 self
.xml
.get_object('use_env_http_proxy_checkbutton1').set_active(
1874 self
.xml
.get_object('proxy_hbox1').set_sensitive(not use_env_http_proxy
)
1876 warn_when_insecure_ssl
= gajim
.config
.get_per('accounts', account
,
1877 'warn_when_insecure_ssl_connection')
1878 self
.xml
.get_object('warn_when_insecure_connection_checkbutton1').\
1879 set_active(warn_when_insecure_ssl
)
1881 self
.xml
.get_object('send_keepalive_checkbutton1').set_active(
1882 gajim
.config
.get_per('accounts', account
, 'keep_alives_enabled'))
1884 use_custom_host
= gajim
.config
.get_per('accounts', account
,
1886 self
.xml
.get_object('custom_host_port_checkbutton1').set_active(
1888 custom_host
= gajim
.config
.get_per('accounts', account
, 'custom_host')
1890 custom_host
= gajim
.config
.get_per('accounts', account
, 'hostname')
1891 gajim
.config
.set_per('accounts', account
, 'custom_host', custom_host
)
1892 self
.xml
.get_object('custom_host_entry1').set_text(custom_host
)
1893 custom_port
= gajim
.config
.get_per('accounts', account
, 'custom_port')
1896 gajim
.config
.set_per('accounts', account
, 'custom_port', custom_port
)
1897 self
.xml
.get_object('custom_port_entry1').set_text(unicode(custom_port
))
1900 gpg_key_label
= self
.xml
.get_object('gpg_key_label1')
1902 self
.xml
.get_object('gpg_choose_button1').set_sensitive(True)
1903 self
.init_account_gpg()
1905 gpg_key_label
.set_text(_('OpenPGP is not usable on this computer'))
1906 self
.xml
.get_object('gpg_choose_button1').set_sensitive(False)
1909 self
.xml
.get_object('autoconnect_checkbutton1').set_active(gajim
.config
.\
1910 get_per('accounts', account
, 'autoconnect'))
1911 self
.xml
.get_object('autoreconnect_checkbutton1').set_active(gajim
.
1912 config
.get_per('accounts', account
, 'autoreconnect'))
1914 list_no_log_for
= gajim
.config
.get_per('accounts', account
,
1915 'no_log_for').split()
1916 if account
in list_no_log_for
:
1917 self
.xml
.get_object('log_history_checkbutton1').set_active(False)
1919 self
.xml
.get_object('log_history_checkbutton1').set_active(True)
1921 self
.xml
.get_object('sync_with_global_status_checkbutton1').set_active(
1922 gajim
.config
.get_per('accounts', account
, 'sync_with_global_status'))
1923 self
.xml
.get_object('use_ft_proxies_checkbutton1').set_active(
1924 gajim
.config
.get_per('accounts', account
, 'use_ft_proxies'))
1926 def on_add_button_clicked(self
, widget
):
1928 When add button is clicked: open an account information window
1930 if 'account_creation_wizard' in gajim
.interface
.instances
:
1931 gajim
.interface
.instances
['account_creation_wizard'].window
.present()
1933 gajim
.interface
.instances
['account_creation_wizard'] = \
1934 AccountCreationWizardWindow()
1936 def on_remove_button_clicked(self
, widget
):
1938 When delete button is clicked: Remove an account from the listStore and
1939 from the config file
1941 if not self
.current_account
:
1943 account
= self
.current_account
1944 if len(gajim
.events
.get_events(account
)):
1945 dialogs
.ErrorDialog(_('Unread events'),
1946 _('Read all pending events before removing this account.'))
1949 if gajim
.config
.get_per('accounts', account
, 'is_zeroconf'):
1950 # Should never happen as button is insensitive
1954 if gajim
.interface
.msg_win_mgr
.get_controls(acct
=account
):
1956 elif account
in gajim
.interface
.instances
:
1957 for key
in gajim
.interface
.instances
[account
]:
1958 if gajim
.interface
.instances
[account
][key
] and key
!= \
1962 # Detect if we have opened windows for this account
1963 def remove(account
):
1964 if account
in gajim
.interface
.instances
and \
1965 'remove_account' in gajim
.interface
.instances
[account
]:
1966 gajim
.interface
.instances
[account
]['remove_account'].window
.\
1969 if not account
in gajim
.interface
.instances
:
1970 gajim
.interface
.instances
[account
] = {}
1971 gajim
.interface
.instances
[account
]['remove_account'] = \
1972 RemoveAccountWindow(account
)
1974 dialogs
.ConfirmationDialog(
1975 _('You have opened chat in account %s') % account
,
1976 _('All chat and groupchat windows will be closed. Do you want to '
1978 on_response_ok
= (remove
, account
))
1982 def on_rename_button_clicked(self
, widget
):
1983 if not self
.current_account
:
1985 active
= gajim
.config
.get_per('accounts', self
.current_account
, 'active')
1986 if active
and gajim
.connections
[self
.current_account
].connected
!= 0:
1987 dialogs
.ErrorDialog(
1988 _('You are currently connected to the server'),
1989 _('To change the account name, you must be disconnected.'))
1991 if len(gajim
.events
.get_events(self
.current_account
)):
1992 dialogs
.ErrorDialog(_('Unread events'),
1993 _('To change the account name, you must read all pending '
1997 def on_renamed(new_name
, old_name
):
1998 if new_name
in gajim
.connections
:
1999 dialogs
.ErrorDialog(_('Account Name Already Used'),
2000 _('This name is already used by another of your accounts. '
2001 'Please choose another name.'))
2003 if (new_name
== ''):
2004 dialogs
.ErrorDialog(_('Invalid account name'),
2005 _('Account name cannot be empty.'))
2007 if new_name
.find(' ') != -1:
2008 dialogs
.ErrorDialog(_('Invalid account name'),
2009 _('Account name cannot contain spaces.'))
2013 gajim
.interface
.instances
[new_name
] = gajim
.interface
.instances
[
2015 gajim
.interface
.minimized_controls
[new_name
] = \
2016 gajim
.interface
.minimized_controls
[old_name
]
2017 gajim
.nicks
[new_name
] = gajim
.nicks
[old_name
]
2018 gajim
.block_signed_in_notifications
[new_name
] = \
2019 gajim
.block_signed_in_notifications
[old_name
]
2020 gajim
.groups
[new_name
] = gajim
.groups
[old_name
]
2021 gajim
.gc_connected
[new_name
] = gajim
.gc_connected
[old_name
]
2022 gajim
.automatic_rooms
[new_name
] = gajim
.automatic_rooms
[old_name
]
2023 gajim
.newly_added
[new_name
] = gajim
.newly_added
[old_name
]
2024 gajim
.to_be_removed
[new_name
] = gajim
.to_be_removed
[old_name
]
2025 gajim
.sleeper_state
[new_name
] = gajim
.sleeper_state
[old_name
]
2026 gajim
.encrypted_chats
[new_name
] = gajim
.encrypted_chats
[old_name
]
2027 gajim
.last_message_time
[new_name
] = \
2028 gajim
.last_message_time
[old_name
]
2029 gajim
.status_before_autoaway
[new_name
] = \
2030 gajim
.status_before_autoaway
[old_name
]
2031 gajim
.transport_avatar
[new_name
] = gajim
.transport_avatar
[old_name
]
2032 gajim
.gajim_optional_features
[new_name
] = \
2033 gajim
.gajim_optional_features
[old_name
]
2034 gajim
.caps_hash
[new_name
] = gajim
.caps_hash
[old_name
]
2036 gajim
.contacts
.change_account_name(old_name
, new_name
)
2037 gajim
.events
.change_account_name(old_name
, new_name
)
2039 # change account variable for chat / gc controls
2040 gajim
.interface
.msg_win_mgr
.change_account_name(old_name
, new_name
)
2041 # upgrade account variable in opened windows
2042 for kind
in ('infos', 'disco', 'gc_config', 'search',
2044 for j
in gajim
.interface
.instances
[new_name
][kind
]:
2045 gajim
.interface
.instances
[new_name
][kind
][j
].account
= \
2048 # ServiceCache object keep old property account
2049 if hasattr(gajim
.connections
[old_name
], 'services_cache'):
2050 gajim
.connections
[old_name
].services_cache
.account
= new_name
2051 del gajim
.interface
.instances
[old_name
]
2052 del gajim
.interface
.minimized_controls
[old_name
]
2053 del gajim
.nicks
[old_name
]
2054 del gajim
.block_signed_in_notifications
[old_name
]
2055 del gajim
.groups
[old_name
]
2056 del gajim
.gc_connected
[old_name
]
2057 del gajim
.automatic_rooms
[old_name
]
2058 del gajim
.newly_added
[old_name
]
2059 del gajim
.to_be_removed
[old_name
]
2060 del gajim
.sleeper_state
[old_name
]
2061 del gajim
.encrypted_chats
[old_name
]
2062 del gajim
.last_message_time
[old_name
]
2063 del gajim
.status_before_autoaway
[old_name
]
2064 del gajim
.transport_avatar
[old_name
]
2065 del gajim
.gajim_optional_features
[old_name
]
2066 del gajim
.caps_hash
[old_name
]
2067 gajim
.connections
[old_name
].name
= new_name
2068 gajim
.connections
[old_name
].pep_change_account_name(new_name
)
2069 gajim
.connections
[old_name
].caps_change_account_name(new_name
)
2070 gajim
.connections
[new_name
] = gajim
.connections
[old_name
]
2071 del gajim
.connections
[old_name
]
2072 gajim
.config
.add_per('accounts', new_name
)
2073 old_config
= gajim
.config
.get_per('accounts', old_name
)
2074 for opt
in old_config
:
2075 gajim
.config
.set_per('accounts', new_name
, opt
, old_config
[opt
][1])
2076 gajim
.config
.del_per('accounts', old_name
)
2077 if self
.current_account
== old_name
:
2078 self
.current_account
= new_name
2079 if old_name
== gajim
.ZEROCONF_ACC_NAME
:
2080 gajim
.ZEROCONF_ACC_NAME
= new_name
2082 gajim
.interface
.roster
.setup_and_draw_roster()
2083 self
.init_accounts()
2084 self
.select_account(new_name
)
2086 title
= _('Rename Account')
2087 message
= _('Enter a new name for account %s') % self
.current_account
2088 old_text
= self
.current_account
2089 dialogs
.InputDialog(title
, message
, old_text
, is_modal
=False,
2090 ok_handler
=(on_renamed
, self
.current_account
))
2092 def option_changed(self
, option
, value
):
2093 return gajim
.config
.get_per('accounts', self
.current_account
, option
) != \
2096 def on_jid_entry1_focus_out_event(self
, widget
, event
):
2097 if self
.ignore_events
:
2099 jid
= widget
.get_text()
2100 # check if jid is conform to RFC and stringprep it
2102 jid
= helpers
.parse_jid(jid
)
2103 except helpers
.InvalidFormat
, s
:
2104 if not widget
.is_focus():
2105 pritext
= _('Invalid Jabber ID')
2106 dialogs
.ErrorDialog(pritext
, str(s
))
2107 gobject
.idle_add(lambda: widget
.grab_focus())
2110 jid_splited
= jid
.split('@', 1)
2111 if len(jid_splited
) != 2 and not gajim
.config
.get_per('accounts',
2112 self
.current_account
, 'anonymous_auth'):
2113 if not widget
.is_focus():
2114 pritext
= _('Invalid Jabber ID')
2115 sectext
= _('A Jabber ID must be in the form "user@servername".')
2116 dialogs
.ErrorDialog(pritext
, sectext
)
2117 gobject
.idle_add(lambda: widget
.grab_focus())
2121 if gajim
.config
.get_per('accounts', self
.current_account
,
2123 gajim
.config
.set_per('accounts', self
.current_account
, 'hostname',
2125 if self
.option_changed('hostname', jid_splited
[0]):
2126 self
.need_relogin
= True
2128 if self
.option_changed('name', jid_splited
[0]) or \
2129 self
.option_changed('hostname', jid_splited
[1]):
2130 self
.need_relogin
= True
2132 gajim
.config
.set_per('accounts', self
.current_account
, 'name',
2134 gajim
.config
.set_per('accounts', self
.current_account
, 'hostname',
2137 def on_cert_entry1_focus_out_event(self
, widget
, event
):
2138 if self
.ignore_events
:
2140 client_cert
= widget
.get_text()
2141 if self
.option_changed('client_cert', client_cert
):
2142 self
.need_relogin
= True
2143 gajim
.config
.set_per('accounts', self
.current_account
, 'client_cert',
2146 def on_anonymous_checkbutton1_toggled(self
, widget
):
2147 if self
.ignore_events
:
2149 active
= widget
.get_active()
2150 gajim
.config
.set_per('accounts', self
.current_account
, 'anonymous_auth',
2152 self
.draw_normal_jid()
2154 def on_password_entry1_changed(self
, widget
):
2155 if self
.ignore_events
:
2157 passwords
.save_password(self
.current_account
, widget
.get_text().decode(
2160 def on_save_password_checkbutton1_toggled(self
, widget
):
2161 if self
.ignore_events
:
2163 active
= widget
.get_active()
2164 password_entry
= self
.xml
.get_object('password_entry1')
2165 password_entry
.set_sensitive(active
)
2166 gajim
.config
.set_per('accounts', self
.current_account
, 'savepass', active
)
2168 password
= password_entry
.get_text()
2169 passwords
.save_password(self
.current_account
, password
)
2171 passwords
.save_password(self
.current_account
, '')
2173 def on_resource_entry1_focus_out_event(self
, widget
, event
):
2174 if self
.ignore_events
:
2176 resource
= self
.xml
.get_object('resource_entry1').get_text().decode(
2179 resource
= helpers
.parse_resource(resource
)
2180 except helpers
.InvalidFormat
, s
:
2181 if not widget
.is_focus():
2182 pritext
= _('Invalid Jabber ID')
2183 dialogs
.ErrorDialog(pritext
, str(s
))
2184 gobject
.idle_add(lambda: widget
.grab_focus())
2187 if self
.option_changed('resource', resource
):
2188 self
.need_relogin
= True
2190 gajim
.config
.set_per('accounts', self
.current_account
, 'resource',
2193 def on_adjust_priority_with_status_checkbutton1_toggled(self
, widget
):
2194 self
.xml
.get_object('priority_spinbutton1').set_sensitive(
2195 not widget
.get_active())
2196 self
.on_checkbutton_toggled(widget
, 'adjust_priority_with_status',
2197 account
= self
.current_account
)
2199 def on_priority_spinbutton1_value_changed(self
, widget
):
2200 prio
= widget
.get_value_as_int()
2202 if self
.option_changed('priority', prio
):
2203 self
.resend_presence
= True
2205 gajim
.config
.set_per('accounts', self
.current_account
, 'priority', prio
)
2207 def on_synchronise_contacts_button1_clicked(self
, widget
):
2209 dialogs
.SynchroniseSelectAccountDialog(self
.current_account
)
2210 except GajimGeneralException
:
2211 # If we showed ErrorDialog, there will not be dialog instance
2214 def on_change_password_button1_clicked(self
, widget
):
2215 def on_changed(new_password
):
2216 if new_password
is not None:
2217 gajim
.connections
[self
.current_account
].change_password(
2219 if self
.xml
.get_object('save_password_checkbutton1').get_active():
2220 self
.xml
.get_object('password_entry1').set_text(new_password
)
2223 dialogs
.ChangePasswordDialog(self
.current_account
, on_changed
)
2224 except GajimGeneralException
:
2225 # if we showed ErrorDialog, there will not be dialog instance
2228 def on_autoconnect_checkbutton_toggled(self
, widget
):
2229 if self
.ignore_events
:
2231 self
.on_checkbutton_toggled(widget
, 'autoconnect',
2232 account
=self
.current_account
)
2234 def on_autoreconnect_checkbutton_toggled(self
, widget
):
2235 if self
.ignore_events
:
2237 self
.on_checkbutton_toggled(widget
, 'autoreconnect',
2238 account
=self
.current_account
)
2240 def on_log_history_checkbutton_toggled(self
, widget
):
2241 if self
.ignore_events
:
2243 list_no_log_for
= gajim
.config
.get_per('accounts', self
.current_account
,
2244 'no_log_for').split()
2245 if self
.current_account
in list_no_log_for
:
2246 list_no_log_for
.remove(self
.current_account
)
2248 if not widget
.get_active():
2249 list_no_log_for
.append(self
.current_account
)
2250 gajim
.config
.set_per('accounts', self
.current_account
, 'no_log_for',
2251 ' '.join(list_no_log_for
))
2253 def on_sync_with_global_status_checkbutton_toggled(self
, widget
):
2254 if self
.ignore_events
:
2256 self
.on_checkbutton_toggled(widget
, 'sync_with_global_status',
2257 account
=self
.current_account
)
2258 gajim
.interface
.roster
.update_status_combobox()
2260 def on_use_ft_proxies_checkbutton1_toggled(self
, widget
):
2261 if self
.ignore_events
:
2263 self
.on_checkbutton_toggled(widget
, 'use_ft_proxies',
2264 account
=self
.current_account
)
2266 def on_use_env_http_proxy_checkbutton1_toggled(self
, widget
):
2267 if self
.ignore_events
:
2269 self
.on_checkbutton_toggled(widget
, 'use_env_http_proxy',
2270 account
=self
.current_account
)
2271 hbox
= self
.xml
.get_object('proxy_hbox1')
2272 hbox
.set_sensitive(not widget
.get_active())
2274 def on_proxies_combobox1_changed(self
, widget
):
2275 active
= widget
.get_active()
2276 proxy
= widget
.get_model()[active
][0].decode('utf-8')
2277 if proxy
== _('None'):
2280 if self
.option_changed('proxy', proxy
):
2281 self
.need_relogin
= True
2283 gajim
.config
.set_per('accounts', self
.current_account
, 'proxy', proxy
)
2285 def on_manage_proxies_button1_clicked(self
, widget
):
2286 if 'manage_proxies' in gajim
.interface
.instances
:
2287 gajim
.interface
.instances
['manage_proxies'].window
.present()
2289 gajim
.interface
.instances
['manage_proxies'] = ManageProxiesWindow()
2291 def on_warn_when_insecure_connection_checkbutton1_toggled(self
, widget
):
2292 if self
.ignore_events
:
2295 self
.on_checkbutton_toggled(widget
, 'warn_when_insecure_ssl_connection',
2296 account
=self
.current_account
)
2298 def on_send_keepalive_checkbutton1_toggled(self
, widget
):
2299 if self
.ignore_events
:
2301 self
.on_checkbutton_toggled(widget
, 'keep_alives_enabled',
2302 account
=self
.current_account
)
2303 gajim
.config
.set_per('accounts', self
.current_account
,
2304 'ping_alives_enabled', widget
.get_active())
2306 def on_custom_host_port_checkbutton1_toggled(self
, widget
):
2307 if self
.option_changed('use_custom_host', widget
.get_active()):
2308 self
.need_relogin
= True
2310 self
.on_checkbutton_toggled(widget
, 'use_custom_host',
2311 account
=self
.current_account
)
2312 active
= widget
.get_active()
2313 self
.xml
.get_object('custom_host_port_hbox1').set_sensitive(active
)
2315 def on_custom_host_entry1_changed(self
, widget
):
2316 if self
.ignore_events
:
2318 host
= widget
.get_text().decode('utf-8')
2319 if self
.option_changed('custom_host', host
):
2320 self
.need_relogin
= True
2321 gajim
.config
.set_per('accounts', self
.current_account
, 'custom_host',
2324 def on_custom_port_entry_focus_out_event(self
, widget
, event
):
2325 if self
.ignore_events
:
2327 custom_port
= widget
.get_text()
2329 custom_port
= int(custom_port
)
2331 if not widget
.is_focus():
2332 dialogs
.ErrorDialog(_('Invalid entry'),
2333 _('Custom port must be a port number.'))
2334 gobject
.idle_add(lambda: widget
.grab_focus())
2336 if self
.option_changed('custom_port', custom_port
):
2337 self
.need_relogin
= True
2338 gajim
.config
.set_per('accounts', self
.current_account
, 'custom_port',
2341 def on_gpg_choose_button_clicked(self
, widget
, data
= None):
2342 if self
.current_account
in gajim
.connections
and \
2343 gajim
.connections
[self
.current_account
].gpg
:
2344 secret_keys
= gajim
.connections
[self
.current_account
].\
2345 ask_gpg_secrete_keys()
2347 # self.current_account is None and/or gajim.connections is {}
2350 secret_keys
= gpg
.GnuPG().get_secret_keys()
2354 dialogs
.ErrorDialog(_('Failed to get secret keys'),
2355 _('There is no OpenPGP secret key available.'))
2356 secret_keys
[_('None')] = _('None')
2358 def on_key_selected(keyID
):
2361 if self
.current_account
== gajim
.ZEROCONF_ACC_NAME
:
2362 wiget_name_ext
= '2'
2364 wiget_name_ext
= '1'
2365 gpg_key_label
= self
.xml
.get_object('gpg_key_label' + wiget_name_ext
)
2366 gpg_name_label
= self
.xml
.get_object('gpg_name_label' + wiget_name_ext
)
2367 use_gpg_agent_checkbutton
= self
.xml
.get_object(
2368 'use_gpg_agent_checkbutton' + wiget_name_ext
)
2369 if keyID
[0] == _('None'):
2370 gpg_key_label
.set_text(_('No key selected'))
2371 gpg_name_label
.set_text('')
2372 use_gpg_agent_checkbutton
.set_sensitive(False)
2373 if self
.option_changed('keyid', ''):
2374 self
.need_relogin
= True
2375 gajim
.config
.set_per('accounts', self
.current_account
, 'keyname',
2377 gajim
.config
.set_per('accounts', self
.current_account
, 'keyid', '')
2379 gpg_key_label
.set_text(keyID
[0])
2380 gpg_name_label
.set_text(keyID
[1])
2381 use_gpg_agent_checkbutton
.set_sensitive(True)
2382 if self
.option_changed('keyid', keyID
[0]):
2383 self
.need_relogin
= True
2384 gajim
.config
.set_per('accounts', self
.current_account
, 'keyname',
2386 gajim
.config
.set_per('accounts', self
.current_account
, 'keyid',
2389 dialogs
.ChooseGPGKeyDialog(_('OpenPGP Key Selection'),
2390 _('Choose your OpenPGP key'), secret_keys
, on_key_selected
)
2392 def on_use_gpg_agent_checkbutton_toggled(self
, widget
):
2393 self
.on_checkbutton_toggled(widget
, 'use_gpg_agent')
2395 def on_edit_details_button1_clicked(self
, widget
):
2396 if self
.current_account
not in gajim
.interface
.instances
:
2397 dialogs
.ErrorDialog(_('No such account available'),
2398 _('You must create your account before editing your personal '
2402 # show error dialog if account is newly created (not in gajim.connections)
2403 if self
.current_account
not in gajim
.connections
or \
2404 gajim
.connections
[self
.current_account
].connected
< 2:
2405 dialogs
.ErrorDialog(_('You are not connected to the server'),
2406 _('Without a connection, you can not edit your personal information.'))
2409 if not gajim
.connections
[self
.current_account
].vcard_supported
:
2410 dialogs
.ErrorDialog(_("Your server doesn't support Vcard"),
2411 _("Your server can't save your personal information."))
2414 gajim
.interface
.edit_own_details(self
.current_account
)
2416 def on_checkbutton_toggled(self
, widget
, config_name
,
2417 change_sensitivity_widgets
= None, account
= None):
2419 gajim
.config
.set_per('accounts', account
, config_name
,
2420 widget
.get_active())
2422 gajim
.config
.set(config_name
, widget
.get_active())
2423 if change_sensitivity_widgets
:
2424 for w
in change_sensitivity_widgets
:
2425 w
.set_sensitive(widget
.get_active())
2426 gajim
.interface
.save_config()
2428 def on_merge_checkbutton_toggled(self
, widget
):
2429 self
.on_checkbutton_toggled(widget
, 'mergeaccounts')
2430 if len(gajim
.connections
) >= 2: # Do not merge accounts if only one active
2431 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2433 gajim
.interface
.roster
.regroup
= False
2434 gajim
.interface
.roster
.setup_and_draw_roster()
2436 def _disable_account(self
, account
):
2437 gajim
.interface
.roster
.close_all(account
)
2438 if account
== gajim
.ZEROCONF_ACC_NAME
:
2439 gajim
.connections
[account
].disable_account()
2440 del gajim
.connections
[account
]
2441 gajim
.interface
.save_config()
2442 del gajim
.interface
.instances
[account
]
2443 del gajim
.interface
.minimized_controls
[account
]
2444 del gajim
.nicks
[account
]
2445 del gajim
.block_signed_in_notifications
[account
]
2446 del gajim
.groups
[account
]
2447 gajim
.contacts
.remove_account(account
)
2448 del gajim
.gc_connected
[account
]
2449 del gajim
.automatic_rooms
[account
]
2450 del gajim
.to_be_removed
[account
]
2451 del gajim
.newly_added
[account
]
2452 del gajim
.sleeper_state
[account
]
2453 del gajim
.encrypted_chats
[account
]
2454 del gajim
.last_message_time
[account
]
2455 del gajim
.status_before_autoaway
[account
]
2456 del gajim
.transport_avatar
[account
]
2457 del gajim
.gajim_optional_features
[account
]
2458 del gajim
.caps_hash
[account
]
2459 if len(gajim
.connections
) >= 2:
2460 # Do not merge accounts if only one exists
2461 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2463 gajim
.interface
.roster
.regroup
= False
2464 gajim
.interface
.roster
.setup_and_draw_roster()
2465 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
2467 def _enable_account(self
, account
):
2468 if account
== gajim
.ZEROCONF_ACC_NAME
:
2469 gajim
.connections
[account
] = connection_zeroconf
.ConnectionZeroconf(
2471 if gajim
.connections
[account
].gpg
:
2472 self
.xml
.get_object('gpg_choose_button2').set_sensitive(True)
2474 gajim
.connections
[account
] = common
.connection
.Connection(account
)
2475 if gajim
.connections
[account
].gpg
:
2476 self
.xml
.get_object('gpg_choose_button1').set_sensitive(True)
2477 self
.init_account_gpg()
2479 gajim
.interface
.instances
[account
] = {'infos': {},
2480 'disco': {}, 'gc_config': {}, 'search': {}, 'online_dialog': {}}
2481 gajim
.interface
.minimized_controls
[account
] = {}
2482 gajim
.connections
[account
].connected
= 0
2483 gajim
.groups
[account
] = {}
2484 gajim
.contacts
.add_account(account
)
2485 gajim
.gc_connected
[account
] = {}
2486 gajim
.automatic_rooms
[account
] = {}
2487 gajim
.newly_added
[account
] = []
2488 gajim
.to_be_removed
[account
] = []
2489 if account
== gajim
.ZEROCONF_ACC_NAME
:
2490 gajim
.nicks
[account
] = gajim
.ZEROCONF_ACC_NAME
2492 gajim
.nicks
[account
] = gajim
.config
.get_per('accounts', account
,
2494 gajim
.block_signed_in_notifications
[account
] = True
2495 gajim
.sleeper_state
[account
] = 'off'
2496 gajim
.encrypted_chats
[account
] = []
2497 gajim
.last_message_time
[account
] = {}
2498 gajim
.status_before_autoaway
[account
] = ''
2499 gajim
.transport_avatar
[account
] = {}
2500 gajim
.gajim_optional_features
[account
] = []
2501 gajim
.caps_hash
[account
] = ''
2503 if len(gajim
.connections
) >= 2:
2504 # Do not merge accounts if only one exists
2505 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
2507 gajim
.interface
.roster
.regroup
= False
2508 gajim
.interface
.roster
.setup_and_draw_roster()
2509 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
2510 gajim
.interface
.save_config()
2512 def on_enable_zeroconf_checkbutton2_toggled(self
, widget
):
2513 # don't do anything if there is an account with the local name but is a
2515 if self
.ignore_events
:
2517 if self
.current_account
in gajim
.connections
and \
2518 gajim
.connections
[self
.current_account
].connected
> 0:
2519 self
.ignore_events
= True
2520 self
.xml
.get_object('enable_zeroconf_checkbutton2').set_active(True)
2521 self
.ignore_events
= False
2522 dialogs
.ErrorDialog(
2523 _('You are currently connected to the server'),
2524 _('To disable the account, you must be disconnected.'))
2526 if gajim
.ZEROCONF_ACC_NAME
in gajim
.connections
and not \
2527 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].is_zeroconf
:
2528 gajim
.connections
[gajim
.ZEROCONF_ACC_NAME
].dispatch('ERROR',
2529 (_('Account Local already exists.'),
2530 _('Please rename or remove it before enabling link-local messaging'
2534 if gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
, 'active') \
2535 and not widget
.get_active():
2536 self
.xml
.get_object('zeroconf_notebook').set_sensitive(False)
2538 self
._disable
_account
(gajim
.ZEROCONF_ACC_NAME
)
2540 elif not gajim
.config
.get_per('accounts', gajim
.ZEROCONF_ACC_NAME
,
2541 'active') and widget
.get_active():
2542 self
.xml
.get_object('zeroconf_notebook').set_sensitive(True)
2543 # enable (will create new account if not present)
2544 self
._enable
_account
(gajim
.ZEROCONF_ACC_NAME
)
2546 self
.on_checkbutton_toggled(widget
, 'active',
2547 account
=gajim
.ZEROCONF_ACC_NAME
)
2549 def on_enable_checkbutton1_toggled(self
, widget
):
2550 if self
.ignore_events
:
2552 if self
.current_account
in gajim
.connections
and \
2553 gajim
.connections
[self
.current_account
].connected
> 0:
2554 # connecting or connected
2555 self
.ignore_events
= True
2556 self
.xml
.get_object('enable_checkbutton1').set_active(True)
2557 self
.ignore_events
= False
2558 dialogs
.ErrorDialog(
2559 _('You are currently connected to the server'),
2560 _('To disable the account, you must be disconnected.'))
2562 # add/remove account in roster and all variables
2563 if widget
.get_active():
2565 self
._enable
_account
(self
.current_account
)
2568 self
._disable
_account
(self
.current_account
)
2569 self
.on_checkbutton_toggled(widget
, 'active',
2570 account
=self
.current_account
, change_sensitivity_widgets
=[
2571 self
.xml
.get_object('normal_notebook1')])
2573 def on_custom_port_checkbutton2_toggled(self
, widget
):
2574 self
.xml
.get_object('custom_port_entry2').set_sensitive(
2575 widget
.get_active())
2576 self
.on_checkbutton_toggled(widget
, 'use_custom_host',
2577 account
= self
.current_account
)
2578 if not widget
.get_active():
2579 self
.xml
.get_object('custom_port_entry2').set_text('5298')
2581 def on_first_name_entry2_changed(self
, widget
):
2582 if self
.ignore_events
:
2584 name
= widget
.get_text().decode('utf-8')
2585 if self
.option_changed('zeroconf_first_name', name
):
2586 self
.need_relogin
= True
2587 gajim
.config
.set_per('accounts', self
.current_account
,
2588 'zeroconf_first_name', name
)
2590 def on_last_name_entry2_changed(self
, widget
):
2591 if self
.ignore_events
:
2593 name
= widget
.get_text().decode('utf-8')
2594 if self
.option_changed('zeroconf_last_name', name
):
2595 self
.need_relogin
= True
2596 gajim
.config
.set_per('accounts', self
.current_account
,
2597 'zeroconf_last_name', name
)
2599 def on_jabber_id_entry2_changed(self
, widget
):
2600 if self
.ignore_events
:
2602 id_
= widget
.get_text().decode('utf-8')
2603 if self
.option_changed('zeroconf_jabber_id', id_
):
2604 self
.need_relogin
= True
2605 gajim
.config
.set_per('accounts', self
.current_account
,
2606 'zeroconf_jabber_id', id_
)
2608 def on_email_entry2_changed(self
, widget
):
2609 if self
.ignore_events
:
2611 email
= widget
.get_text().decode('utf-8')
2612 if self
.option_changed('zeroconf_email', email
):
2613 self
.need_relogin
= True
2614 gajim
.config
.set_per('accounts', self
.current_account
,
2615 'zeroconf_email', email
)
2617 class FakeDataForm(gtk
.Table
, object):
2619 Class for forms that are in XML format <entry1>value1</entry1> infos in a
2620 table {entry1: value1}
2623 def __init__(self
, infos
):
2624 gtk
.Table
.__init
__(self
)
2629 def _draw_table(self
):
2634 if 'instructions' in self
.infos
:
2636 self
.resize(rows
= nbrow
, columns
= 2)
2637 label
= gtk
.Label(self
.infos
['instructions'])
2638 self
.attach(label
, 0, 2, 0, 1, 0, 0, 0, 0)
2639 for name
in self
.infos
.keys():
2640 if name
in ('key', 'instructions', 'x', 'registered'):
2646 self
.resize(rows
= nbrow
, columns
= 2)
2647 label
= gtk
.Label(name
.capitalize() + ':')
2648 self
.attach(label
, 0, 1, nbrow
- 1, nbrow
, 0, 0, 0, 0)
2650 entry
.set_activates_default(True)
2651 if self
.infos
[name
]:
2652 entry
.set_text(self
.infos
[name
])
2653 if name
== 'password':
2654 entry
.set_visibility(False)
2655 self
.attach(entry
, 1, 2, nbrow
- 1, nbrow
, 0, 0, 0, 0)
2656 self
.entries
[name
] = entry
2660 def get_infos(self
):
2661 for name
in self
.entries
.keys():
2662 self
.infos
[name
] = self
.entries
[name
].get_text().decode('utf-8')
2665 class ServiceRegistrationWindow
:
2667 Class for Service registration window. Window that appears when we want to
2668 subscribe to a service if is_form we use dataforms_widget else we use
2669 service_registarion_window
2671 def __init__(self
, service
, infos
, account
, is_form
):
2672 self
.service
= service
2673 self
.account
= account
2674 self
.is_form
= is_form
2675 self
.xml
= gtkgui_helpers
.get_gtk_builder('service_registration_window.ui')
2676 self
.window
= self
.xml
.get_object('service_registration_window')
2677 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2679 dataform
= dataforms
.ExtendForm(node
= infos
)
2680 self
.data_form_widget
= dataforms_widget
.DataFormWidget(dataform
)
2681 if self
.data_form_widget
.title
:
2682 self
.window
.set_title('%s - Gajim' % self
.data_form_widget
.title
)
2683 table
= self
.xml
.get_object('table')
2684 table
.attach(self
.data_form_widget
, 0, 2, 0, 1)
2686 if 'registered' in infos
:
2687 self
.window
.set_title(_('Edit %s') % service
)
2689 self
.window
.set_title(_('Register to %s') % service
)
2690 self
.data_form_widget
= FakeDataForm(infos
)
2691 table
= self
.xml
.get_object('table')
2692 table
.attach(self
.data_form_widget
, 0, 2, 0, 1)
2694 self
.xml
.connect_signals(self
)
2695 self
.window
.show_all()
2697 def on_cancel_button_clicked(self
, widget
):
2698 self
.window
.destroy()
2700 def on_ok_button_clicked(self
, widget
):
2701 # send registration info to the core
2703 form
= self
.data_form_widget
.data_form
2704 gajim
.connections
[self
.account
].register_agent(self
.service
,
2705 form
, True) # True is for is_form
2707 infos
= self
.data_form_widget
.get_infos()
2708 if 'instructions' in infos
:
2709 del infos
['instructions']
2710 if 'registered' in infos
:
2711 del infos
['registered']
2712 gajim
.connections
[self
.account
].register_agent(self
.service
, infos
)
2714 self
.window
.destroy()
2716 class GroupchatConfigWindow
:
2718 def __init__(self
, account
, room_jid
, form
=None):
2719 self
.account
= account
2720 self
.room_jid
= room_jid
2722 self
.remove_button
= {}
2723 self
.affiliation_treeview
= {}
2724 self
.start_users_dict
= {} # list at the beginning
2725 self
.affiliation_labels
= {'outcast': _('Ban List'),
2726 'member': _('Member List'), 'owner': _('Owner List'),
2727 'admin':_('Administrator List')}
2729 self
.xml
= gtkgui_helpers
.get_gtk_builder('data_form_window.ui',
2731 self
.window
= self
.xml
.get_object('data_form_window')
2732 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2735 config_vbox
= self
.xml
.get_object('config_vbox')
2736 self
.data_form_widget
= dataforms_widget
.DataFormWidget(self
.form
)
2737 # hide scrollbar of this data_form_widget, we already have in this
2739 sw
= self
.data_form_widget
.xml
.get_object(
2740 'single_form_scrolledwindow')
2741 sw
.set_policy(gtk
.POLICY_NEVER
, gtk
.POLICY_NEVER
)
2743 self
.xml
.get_object('title_label').set_text(self
.form
.title
)
2745 self
.xml
.get_object('title_hseparator').set_no_show_all(True)
2746 self
.xml
.get_object('title_hseparator').hide()
2748 self
.data_form_widget
.show()
2749 config_vbox
.pack_start(self
.data_form_widget
)
2751 self
.xml
.get_object('title_label').set_no_show_all(True)
2752 self
.xml
.get_object('title_label').hide()
2753 self
.xml
.get_object('title_hseparator').set_no_show_all(True)
2754 self
.xml
.get_object('title_hseparator').hide()
2755 self
.xml
.get_object('config_hseparator').set_no_show_all(True)
2756 self
.xml
.get_object('config_hseparator').hide()
2758 # Draw the edit affiliation list things
2759 add_on_vbox
= self
.xml
.get_object('add_on_vbox')
2761 for affiliation
in self
.affiliation_labels
.keys():
2762 self
.start_users_dict
[affiliation
] = {}
2763 hbox
= gtk
.HBox(spacing
=5)
2764 add_on_vbox
.pack_start(hbox
, False)
2766 label
= gtk
.Label(self
.affiliation_labels
[affiliation
])
2767 hbox
.pack_start(label
, False)
2769 bb
= gtk
.HButtonBox()
2770 bb
.set_layout(gtk
.BUTTONBOX_END
)
2773 add_button
= gtk
.Button(stock
=gtk
.STOCK_ADD
)
2774 add_button
.connect('clicked', self
.on_add_button_clicked
,
2776 bb
.pack_start(add_button
)
2777 self
.remove_button
[affiliation
] = gtk
.Button(stock
=gtk
.STOCK_REMOVE
)
2778 self
.remove_button
[affiliation
].set_sensitive(False)
2779 self
.remove_button
[affiliation
].connect('clicked',
2780 self
.on_remove_button_clicked
, affiliation
)
2781 bb
.pack_start(self
.remove_button
[affiliation
])
2783 # jid, reason, nick, role
2784 liststore
= gtk
.ListStore(str, str, str, str)
2785 self
.affiliation_treeview
[affiliation
] = gtk
.TreeView(liststore
)
2786 self
.affiliation_treeview
[affiliation
].get_selection().set_mode(
2787 gtk
.SELECTION_MULTIPLE
)
2788 self
.affiliation_treeview
[affiliation
].connect('cursor-changed',
2789 self
.on_affiliation_treeview_cursor_changed
, affiliation
)
2790 renderer
= gtk
.CellRendererText()
2791 col
= gtk
.TreeViewColumn(_('JID'), renderer
)
2792 col
.add_attribute(renderer
, 'text', 0)
2793 col
.set_resizable(True)
2794 col
.set_sort_column_id(0)
2795 self
.affiliation_treeview
[affiliation
].append_column(col
)
2797 if affiliation
== 'outcast':
2798 renderer
= gtk
.CellRendererText()
2799 renderer
.set_property('editable', True)
2800 renderer
.connect('edited', self
.on_cell_edited
)
2801 col
= gtk
.TreeViewColumn(_('Reason'), renderer
)
2802 col
.add_attribute(renderer
, 'text', 1)
2803 col
.set_resizable(True)
2804 col
.set_sort_column_id(1)
2805 self
.affiliation_treeview
[affiliation
].append_column(col
)
2806 elif affiliation
== 'member':
2807 renderer
= gtk
.CellRendererText()
2808 col
= gtk
.TreeViewColumn(_('Nick'), renderer
)
2809 col
.add_attribute(renderer
, 'text', 2)
2810 col
.set_resizable(True)
2811 col
.set_sort_column_id(2)
2812 self
.affiliation_treeview
[affiliation
].append_column(col
)
2813 renderer
= gtk
.CellRendererText()
2814 col
= gtk
.TreeViewColumn(_('Role'), renderer
)
2815 col
.add_attribute(renderer
, 'text', 3)
2816 col
.set_resizable(True)
2817 col
.set_sort_column_id(3)
2818 self
.affiliation_treeview
[affiliation
].append_column(col
)
2820 sw
= gtk
.ScrolledWindow()
2821 sw
.set_policy(gtk
.POLICY_AUTOMATIC
, gtk
.POLICY_NEVER
)
2822 sw
.add(self
.affiliation_treeview
[affiliation
])
2823 add_on_vbox
.pack_start(sw
)
2824 gajim
.connections
[self
.account
].get_affiliation_list(self
.room_jid
,
2827 self
.xml
.connect_signals(self
)
2828 self
.window
.show_all()
2830 def on_cancel_button_clicked(self
, widget
):
2831 self
.window
.destroy()
2833 def on_cell_edited(self
, cell
, path
, new_text
):
2834 model
= self
.affiliation_treeview
['outcast'].get_model()
2835 new_text
= new_text
.decode('utf-8')
2836 iter_
= model
.get_iter(path
)
2837 model
[iter_
][1] = new_text
2839 def on_add_button_clicked(self
, widget
, affiliation
):
2840 if affiliation
== 'outcast':
2841 title
= _('Banning...')
2842 #You can move '\n' before user@domain if that line is TOO BIG
2843 prompt
= _('<b>Whom do you want to ban?</b>\n\n')
2844 elif affiliation
== 'member':
2845 title
= _('Adding Member...')
2846 prompt
= _('<b>Whom do you want to make a member?</b>\n\n')
2847 elif affiliation
== 'owner':
2848 title
= _('Adding Owner...')
2849 prompt
= _('<b>Whom do you want to make an owner?</b>\n\n')
2851 title
= _('Adding Administrator...')
2852 prompt
= _('<b>Whom do you want to make an administrator?</b>\n\n')
2853 prompt
+= _('Can be one of the following:\n'
2854 '1. user@domain/resource (only that resource matches).\n'
2855 '2. user@domain (any resource matches).\n'
2856 '3. domain/resource (only that resource matches).\n'
2857 '4. domain (the domain itself matches, as does any user@domain,\n'
2858 'domain/resource, or address containing a subdomain).')
2863 model
= self
.affiliation_treeview
[affiliation
].get_model()
2864 model
.append((jid
, '', '', ''))
2865 dialogs
.InputDialog(title
, prompt
, ok_handler
=on_ok
)
2867 def on_remove_button_clicked(self
, widget
, affiliation
):
2868 selection
= self
.affiliation_treeview
[affiliation
].get_selection()
2869 model
, paths
= selection
.get_selected_rows()
2872 row_refs
.append(gtk
.TreeRowReference(model
, path
))
2873 for row_ref
in row_refs
:
2874 path
= row_ref
.get_path()
2875 iter_
= model
.get_iter(path
)
2877 self
.remove_button
[affiliation
].set_sensitive(False)
2879 def on_affiliation_treeview_cursor_changed(self
, widget
, affiliation
):
2880 self
.remove_button
[affiliation
].set_sensitive(True)
2882 def affiliation_list_received(self
, users_dict
):
2884 Fill the affiliation treeview
2886 for jid
in users_dict
:
2887 affiliation
= users_dict
[jid
]['affiliation']
2888 if affiliation
not in self
.affiliation_labels
.keys():
2889 # Unknown affiliation or 'none' affiliation, do not show it
2891 self
.start_users_dict
[affiliation
][jid
] = users_dict
[jid
]
2892 tv
= self
.affiliation_treeview
[affiliation
]
2893 model
= tv
.get_model()
2894 reason
= users_dict
[jid
].get('reason', '')
2895 nick
= users_dict
[jid
].get('nick', '')
2896 role
= users_dict
[jid
].get('role', '')
2897 model
.append((jid
, reason
, nick
, role
))
2899 def on_data_form_window_destroy(self
, widget
):
2900 del gajim
.interface
.instances
[self
.account
]['gc_config'][self
.room_jid
]
2902 def on_ok_button_clicked(self
, widget
):
2904 form
= self
.data_form_widget
.data_form
2905 gajim
.connections
[self
.account
].send_gc_config(self
.room_jid
, form
)
2906 for affiliation
in self
.affiliation_labels
.keys():
2908 actual_jid_list
= []
2909 model
= self
.affiliation_treeview
[affiliation
].get_model()
2910 iter_
= model
.get_iter_first()
2913 jid
= model
[iter_
][0].decode('utf-8')
2914 actual_jid_list
.append(jid
)
2915 if jid
not in self
.start_users_dict
[affiliation
] or \
2916 (affiliation
== 'outcast' and 'reason' in self
.start_users_dict
[
2917 affiliation
][jid
] and self
.start_users_dict
[affiliation
][jid
]\
2918 ['reason'] != model
[iter_
][1].decode('utf-8')):
2919 users_dict
[jid
] = {'affiliation': affiliation
}
2920 if affiliation
== 'outcast':
2921 users_dict
[jid
]['reason'] = model
[iter_
][1].decode(
2923 iter_
= model
.iter_next(iter_
)
2924 # remove removed one
2925 for jid
in self
.start_users_dict
[affiliation
]:
2926 if jid
not in actual_jid_list
:
2927 users_dict
[jid
] = {'affiliation': 'none'}
2929 gajim
.connections
[self
.account
].send_gc_affiliation_list(
2930 self
.room_jid
, users_dict
)
2931 self
.window
.destroy()
2933 #---------- RemoveAccountWindow class -------------#
2934 class RemoveAccountWindow
:
2936 Ask for removing from gajim only or from gajim and server too and do
2937 removing of the account given
2940 def on_remove_account_window_destroy(self
, widget
):
2941 if self
.account
in gajim
.interface
.instances
:
2942 del gajim
.interface
.instances
[self
.account
]['remove_account']
2944 def on_cancel_button_clicked(self
, widget
):
2945 self
.window
.destroy()
2947 def __init__(self
, account
):
2948 self
.account
= account
2949 xml
= gtkgui_helpers
.get_gtk_builder('remove_account_window.ui')
2950 self
.window
= xml
.get_object('remove_account_window')
2951 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
2952 self
.remove_and_unregister_radiobutton
= xml
.get_object(
2953 'remove_and_unregister_radiobutton')
2954 self
.window
.set_title(_('Removing %s account') % self
.account
)
2955 xml
.connect_signals(self
)
2956 self
.window
.show_all()
2958 def on_remove_button_clicked(self
, widget
):
2960 if self
.account
in gajim
.connections
and \
2961 gajim
.connections
[self
.account
].connected
and \
2962 not self
.remove_and_unregister_radiobutton
.get_active():
2963 # change status to offline only if we will not remove this JID from
2965 gajim
.connections
[self
.account
].change_status('offline', 'offline')
2966 if self
.remove_and_unregister_radiobutton
.get_active():
2967 if not self
.account
in gajim
.connections
:
2968 dialogs
.ErrorDialog(
2969 _('Account is disabled'),
2970 _('To unregister from a server, account must be '
2973 if not gajim
.connections
[self
.account
].password
:
2974 def on_ok(passphrase
, checked
):
2975 if passphrase
== -1:
2976 # We don't remove account cause we canceled pw window
2978 gajim
.connections
[self
.account
].password
= passphrase
2979 gajim
.connections
[self
.account
].unregister_account(
2980 self
._on
_remove
_success
)
2982 dialogs
.PassphraseDialog(
2983 _('Password Required'),
2984 _('Enter your password for account %s') % self
.account
,
2985 _('Save password'), ok_handler
=on_ok
)
2987 gajim
.connections
[self
.account
].unregister_account(
2988 self
._on
_remove
_success
)
2990 self
._on
_remove
_success
(True)
2992 if self
.account
in gajim
.connections
and \
2993 gajim
.connections
[self
.account
].connected
:
2994 dialogs
.ConfirmationDialog(
2995 _('Account "%s" is connected to the server') % self
.account
,
2996 _('If you remove it, the connection will be lost.'),
2997 on_response_ok
=remove
)
3001 def on_remove_responce_ok(self
, is_checked
):
3003 self
._on
_remove
_success
(True)
3005 def _on_remove_success(self
, res
):
3006 # action of unregistration has failed, we don't remove the account
3007 # Error message is send by connect_and_auth()
3009 dialogs
.ConfirmationDialogDoubleRadio(
3010 _('Connection to server %s failed') % self
.account
,
3011 _('What would you like to do?'),
3012 _('Remove only from Gajim'),
3013 _('Don\'t remove anything. I\'ll try again later'),
3014 on_response_ok
=self
.on_remove_responce_ok
, is_modal
=False)
3016 # Close all opened windows
3017 gajim
.interface
.roster
.close_all(self
.account
, force
=True)
3018 if self
.account
in gajim
.connections
:
3019 gajim
.connections
[self
.account
].disconnect(on_purpose
=True)
3020 gajim
.connections
[self
.account
].cleanup()
3021 del gajim
.connections
[self
.account
]
3022 gajim
.logger
.remove_roster(gajim
.get_jid_from_account(self
.account
))
3023 gajim
.config
.del_per('accounts', self
.account
)
3024 gajim
.interface
.save_config()
3025 del gajim
.interface
.instances
[self
.account
]
3026 if self
.account
in gajim
.nicks
:
3027 del gajim
.interface
.minimized_controls
[self
.account
]
3028 del gajim
.nicks
[self
.account
]
3029 del gajim
.block_signed_in_notifications
[self
.account
]
3030 del gajim
.groups
[self
.account
]
3031 gajim
.contacts
.remove_account(self
.account
)
3032 del gajim
.gc_connected
[self
.account
]
3033 del gajim
.automatic_rooms
[self
.account
]
3034 del gajim
.to_be_removed
[self
.account
]
3035 del gajim
.newly_added
[self
.account
]
3036 del gajim
.sleeper_state
[self
.account
]
3037 del gajim
.encrypted_chats
[self
.account
]
3038 del gajim
.last_message_time
[self
.account
]
3039 del gajim
.status_before_autoaway
[self
.account
]
3040 del gajim
.transport_avatar
[self
.account
]
3041 del gajim
.gajim_optional_features
[self
.account
]
3042 del gajim
.caps_hash
[self
.account
]
3043 if len(gajim
.connections
) >= 2: # Do not merge accounts if only one exists
3044 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
3046 gajim
.interface
.roster
.regroup
= False
3047 gajim
.interface
.roster
.setup_and_draw_roster()
3048 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3049 if 'accounts' in gajim
.interface
.instances
:
3050 gajim
.interface
.instances
['accounts'].init_accounts()
3051 gajim
.interface
.instances
['accounts'].init_account()
3052 self
.window
.destroy()
3054 #---------- ManageBookmarksWindow class -------------#
3055 class ManageBookmarksWindow
:
3057 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_bookmarks_window.ui')
3058 self
.window
= self
.xml
.get_object('manage_bookmarks_window')
3059 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3061 # Account-JID, RoomName, Room-JID, Autojoin, Minimize, Passowrd, Nick,
3063 self
.treestore
= gtk
.TreeStore(str, str, str, bool, bool, str, str, str)
3064 self
.treestore
.set_sort_column_id(1, gtk
.SORT_ASCENDING
)
3066 # Store bookmarks in treeview.
3067 for account
in gajim
.connections
:
3068 if gajim
.connections
[account
].connected
<= 1:
3070 if gajim
.connections
[account
].is_zeroconf
:
3072 if not gajim
.connections
[account
].private_storage_supported
:
3074 iter_
= self
.treestore
.append(None, [None, account
, None, None,
3075 None, None, None, None])
3077 for bookmark
in gajim
.connections
[account
].bookmarks
:
3078 if bookmark
['name'] == '':
3079 # No name was given for this bookmark.
3080 # Use the first part of JID instead...
3081 name
= bookmark
['jid'].split("@")[0]
3082 bookmark
['name'] = name
3084 # make '1', '0', 'true', 'false' (or other) to True/False
3085 autojoin
= helpers
.from_xs_boolean_to_python_boolean(
3086 bookmark
['autojoin'])
3088 minimize
= helpers
.from_xs_boolean_to_python_boolean(
3089 bookmark
['minimize'])
3091 print_status
= bookmark
.get('print_status', '')
3092 if print_status
not in ('', 'all', 'in_and_out', 'none'):
3094 self
.treestore
.append(iter_
, [
3100 bookmark
['password'],
3104 self
.print_status_combobox
= self
.xml
.get_object('print_status_combobox')
3105 model
= gtk
.ListStore(str, str)
3107 self
.option_list
= {'': _('Default'), 'all': Q_('?print_status:All'),
3108 'in_and_out': _('Enter and leave only'),
3109 'none': Q_('?print_status:None')}
3110 opts
= sorted(self
.option_list
.keys())
3112 model
.append([self
.option_list
[opt
], opt
])
3114 self
.print_status_combobox
.set_model(model
)
3115 self
.print_status_combobox
.set_active(1)
3117 self
.view
= self
.xml
.get_object('bookmarks_treeview')
3118 self
.view
.set_model(self
.treestore
)
3119 self
.view
.expand_all()
3121 renderer
= gtk
.CellRendererText()
3122 column
= gtk
.TreeViewColumn('Bookmarks', renderer
, text
=1)
3123 self
.view
.append_column(column
)
3125 self
.selection
= self
.view
.get_selection()
3126 self
.selection
.connect('changed', self
.bookmark_selected
)
3128 #Prepare input fields
3129 self
.title_entry
= self
.xml
.get_object('title_entry')
3130 self
.title_entry
.connect('changed', self
.on_title_entry_changed
)
3131 self
.nick_entry
= self
.xml
.get_object('nick_entry')
3132 self
.nick_entry
.connect('changed', self
.on_nick_entry_changed
)
3133 self
.server_entry
= self
.xml
.get_object('server_entry')
3134 self
.server_entry
.connect('changed', self
.on_server_entry_changed
)
3135 self
.room_entry
= self
.xml
.get_object('room_entry')
3136 self
.room_entry
.connect('changed', self
.on_room_entry_changed
)
3137 self
.pass_entry
= self
.xml
.get_object('pass_entry')
3138 self
.pass_entry
.connect('changed', self
.on_pass_entry_changed
)
3139 self
.autojoin_checkbutton
= self
.xml
.get_object('autojoin_checkbutton')
3140 self
.minimize_checkbutton
= self
.xml
.get_object('minimize_checkbutton')
3142 self
.xml
.connect_signals(self
)
3143 self
.window
.show_all()
3145 self
.selection
.select_iter(self
.treestore
.get_iter_root())
3147 def on_bookmarks_treeview_button_press_event(self
, widget
, event
):
3148 (model
, iter_
) = self
.selection
.get_selected()
3150 # Removed a bookmark before
3153 if model
.iter_parent(iter_
):
3154 # The currently selected node is a bookmark
3155 return not self
.check_valid_bookmark()
3157 def on_manage_bookmarks_window_destroy(self
, widget
, event
):
3158 del gajim
.interface
.instances
['manage_bookmarks']
3160 def on_add_bookmark_button_clicked(self
, widget
):
3164 # Get the account that is currently used
3165 # (the parent of the currently selected item)
3166 (model
, iter_
) = self
.selection
.get_selected()
3167 if not iter_
: # Nothing selected, do nothing
3170 parent
= model
.iter_parent(iter_
)
3173 # We got a bookmark selected, so we add_to the parent
3176 # No parent, so we got an account -> add to this.
3179 account
= model
[add_to
][1].decode('utf-8')
3180 nick
= gajim
.nicks
[account
]
3181 iter_
= self
.treestore
.append(add_to
, [account
, _('New Group Chat'),
3182 '@', False, False, '', nick
, 'in_and_out'])
3184 self
.view
.expand_row(model
.get_path(add_to
), True)
3185 self
.view
.set_cursor(model
.get_path(iter_
))
3187 def on_remove_bookmark_button_clicked(self
, widget
):
3189 Remove selected bookmark
3191 (model
, iter_
) = self
.selection
.get_selected()
3192 if not iter_
: # Nothing selected
3195 if not model
.iter_parent(iter_
):
3196 # Don't remove account iters
3202 def check_valid_bookmark(self
):
3204 Check if all neccessary fields are entered correctly
3206 (model
, iter_
) = self
.selection
.get_selected()
3208 if not model
.iter_parent(iter_
):
3209 #Account data can't be changed
3212 if self
.server_entry
.get_text().decode('utf-8') == '' or \
3213 self
.room_entry
.get_text().decode('utf-8') == '':
3214 dialogs
.ErrorDialog(_('This bookmark has invalid data'),
3215 _('Please be sure to fill out server and room fields or remove this'
3221 def on_ok_button_clicked(self
, widget
):
3223 Parse the treestore data into our new bookmarks array, then send the new
3224 bookmarks to the server.
3226 (model
, iter_
) = self
.selection
.get_selected()
3227 if iter_
and model
.iter_parent(iter_
):
3228 #bookmark selected, check it
3229 if not self
.check_valid_bookmark():
3232 for account
in self
.treestore
:
3233 account_unicode
= account
[1].decode('utf-8')
3234 gajim
.connections
[account_unicode
].bookmarks
= []
3236 for bm
in account
.iterchildren():
3237 # Convert True/False/None to '1' or '0'
3238 autojoin
= unicode(int(bm
[3]))
3239 minimize
= unicode(int(bm
[4]))
3242 name
= name
.decode('utf-8')
3245 jid
= jid
.decode('utf-8')
3248 pw
= pw
.decode('utf-8')
3251 nick
= nick
.decode('utf-8')
3253 # create the bookmark-dict
3254 bmdict
= { 'name': name
, 'jid': jid
, 'autojoin': autojoin
,
3255 'minimize': minimize
, 'password': pw
, 'nick': nick
,
3256 'print_status': bm
[7]}
3258 gajim
.connections
[account_unicode
].bookmarks
.append(bmdict
)
3260 gajim
.connections
[account_unicode
].store_bookmarks()
3261 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3262 self
.window
.destroy()
3264 def on_cancel_button_clicked(self
, widget
):
3265 self
.window
.destroy()
3267 def bookmark_selected(self
, selection
):
3269 Fill in the bookmark's data into the fields.
3271 (model
, iter_
) = selection
.get_selected()
3274 # After removing the last bookmark for one account
3275 # this will be None, so we will just:
3278 widgets
= [ self
.title_entry
, self
.nick_entry
, self
.room_entry
,
3279 self
.server_entry
, self
.pass_entry
, self
.autojoin_checkbutton
,
3280 self
.minimize_checkbutton
, self
.print_status_combobox
]
3282 if model
.iter_parent(iter_
):
3283 # make the fields sensitive
3284 for field
in widgets
:
3285 field
.set_sensitive(True)
3287 # Top-level has no data (it's the account fields)
3288 # clear fields & make them insensitive
3290 for field
in widgets
:
3291 field
.set_sensitive(False)
3294 # Fill in the data for childs
3295 self
.title_entry
.set_text(model
[iter_
][1])
3296 room_jid
= model
[iter_
][2].decode('utf-8')
3297 (room
, server
) = room_jid
.split('@')
3298 self
.room_entry
.set_text(room
)
3299 self
.server_entry
.set_text(server
)
3301 self
.autojoin_checkbutton
.set_active(model
[iter_
][3])
3302 self
.minimize_checkbutton
.set_active(model
[iter_
][4])
3303 # sensitive only if auto join is checked
3304 self
.minimize_checkbutton
.set_sensitive(model
[iter_
][3])
3306 if model
[iter_
][5] is not None:
3307 password
= model
[iter_
][5].decode('utf-8')
3312 self
.pass_entry
.set_text(password
)
3314 self
.pass_entry
.set_text('')
3315 nick
= model
[iter_
][6]
3317 nick
= nick
.decode('utf-8')
3318 self
.nick_entry
.set_text(nick
)
3320 self
.nick_entry
.set_text('')
3322 print_status
= model
[iter_
][7]
3323 opts
= sorted(self
.option_list
.keys())
3324 self
.print_status_combobox
.set_active(opts
.index(print_status
))
3326 def on_title_entry_changed(self
, widget
):
3327 (model
, iter_
) = self
.selection
.get_selected()
3328 if iter_
: # After removing a bookmark, we got nothing selected
3329 if model
.iter_parent(iter_
):
3330 # Don't clear the title field for account nodes
3331 model
[iter_
][1] = self
.title_entry
.get_text()
3333 def on_nick_entry_changed(self
, widget
):
3334 (model
, iter_
) = self
.selection
.get_selected()
3336 nick
= self
.nick_entry
.get_text().decode('utf-8')
3338 nick
= helpers
.parse_resource(nick
)
3339 except helpers
.InvalidFormat
, e
:
3340 dialogs
.ErrorDialog(_('Invalid nickname'),
3341 _('Character not allowed'))
3342 self
.nick_entry
.set_text(model
[iter_
][6])
3344 model
[iter_
][6] = nick
3346 def on_server_entry_changed(self
, widget
):
3347 (model
, iter_
) = self
.selection
.get_selected()
3350 server
= widget
.get_text().decode('utf-8')
3352 dialogs
.ErrorDialog(_('Invalid server'), _('Character not allowed'))
3353 widget
.set_text(server
.replace('@', ''))
3355 room_jid
= self
.room_entry
.get_text().decode('utf-8').strip() + '@' + \
3358 room_jid
= helpers
.parse_resource(room_jid
)
3359 except helpers
.InvalidFormat
, e
:
3360 dialogs
.ErrorDialog(_('Invalid server'),
3361 _('Character not allowed'))
3362 self
.server_entry
.set_text(model
[iter_
][2].split('@')[1])
3364 model
[iter_
][2] = room_jid
3366 def on_room_entry_changed(self
, widget
):
3367 (model
, iter_
) = self
.selection
.get_selected()
3370 room
= widget
.get_text().decode('utf-8')
3372 dialogs
.ErrorDialog(_('Invalid server'), _('Character not allowed'))
3373 widget
.set_text(room
.replace('@', ''))
3374 room_jid
= room
.strip() + '@' + \
3375 self
.server_entry
.get_text().decode('utf-8').strip()
3377 room_jid
= helpers
.parse_resource(room_jid
)
3378 except helpers
.InvalidFormat
, e
:
3379 dialogs
.ErrorDialog(_('Invalid room'),
3380 _('Character not allowed'))
3381 self
.room_entry
.set_text(model
[iter_
][2].split('@')[0])
3383 model
[iter_
][2] = room_jid
3385 def on_pass_entry_changed(self
, widget
):
3386 (model
, iter_
) = self
.selection
.get_selected()
3388 model
[iter_
][5] = self
.pass_entry
.get_text()
3390 def on_autojoin_checkbutton_toggled(self
, widget
):
3391 (model
, iter_
) = self
.selection
.get_selected()
3393 model
[iter_
][3] = self
.autojoin_checkbutton
.get_active()
3394 self
.minimize_checkbutton
.set_sensitive(model
[iter_
][3])
3396 def on_minimize_checkbutton_toggled(self
, widget
):
3397 (model
, iter_
) = self
.selection
.get_selected()
3399 model
[iter_
][4] = self
.minimize_checkbutton
.get_active()
3401 def on_print_status_combobox_changed(self
, widget
):
3402 active
= widget
.get_active()
3403 model
= widget
.get_model()
3404 print_status
= model
[active
][1]
3405 (model2
, iter_
) = self
.selection
.get_selected()
3407 model2
[iter_
][7] = print_status
3409 def clear_fields(self
):
3410 widgets
= [ self
.title_entry
, self
.nick_entry
, self
.room_entry
,
3411 self
.server_entry
, self
.pass_entry
]
3412 for field
in widgets
:
3414 self
.autojoin_checkbutton
.set_active(False)
3415 self
.minimize_checkbutton
.set_active(False)
3416 self
.print_status_combobox
.set_active(1)
3418 class AccountCreationWizardWindow
:
3420 self
.xml
= gtkgui_helpers
.get_gtk_builder(
3421 'account_creation_wizard_window.ui')
3422 self
.window
= self
.xml
.get_object('account_creation_wizard_window')
3423 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3425 completion
= gtk
.EntryCompletion()
3426 completion1
= gtk
.EntryCompletion()
3427 # Connect events from comboboxentry.child
3428 server_comboboxentry
= self
.xml
.get_object('server_comboboxentry')
3429 entry
= server_comboboxentry
.child
3430 entry
.connect('key_press_event',
3431 self
.on_server_comboboxentry_key_press_event
, server_comboboxentry
)
3432 entry
.set_completion(completion
)
3433 # Do the same for the other server comboboxentry
3434 server_comboboxentry1
= self
.xml
.get_object('server_comboboxentry1')
3435 entry
= server_comboboxentry1
.child
3436 entry
.set_completion(completion1
)
3438 self
.update_proxy_list()
3441 servers_xml
= os
.path
.join(gajim
.DATA_DIR
, 'other', 'servers.xml')
3442 servers
= gtkgui_helpers
.parse_server_xml(servers_xml
)
3443 servers_model
= gtk
.ListStore(str)
3444 for server
in servers
:
3445 servers_model
.append((server
,))
3447 completion
.set_model(servers_model
)
3448 completion
.set_text_column(0)
3449 completion1
.set_model(servers_model
)
3450 completion1
.set_text_column(0)
3452 # Put servers into comboboxentries
3453 server_comboboxentry
.set_model(servers_model
)
3454 server_comboboxentry
.set_text_column(0)
3455 server_comboboxentry1
.set_model(servers_model
)
3456 server_comboboxentry1
.set_text_column(0)
3459 self
.notebook
= self
.xml
.get_object('notebook')
3460 self
.cancel_button
= self
.xml
.get_object('cancel_button')
3461 self
.back_button
= self
.xml
.get_object('back_button')
3462 self
.forward_button
= self
.xml
.get_object('forward_button')
3463 self
.finish_button
= self
.xml
.get_object('finish_button')
3464 self
.advanced_button
= self
.xml
.get_object('advanced_button')
3465 self
.finish_label
= self
.xml
.get_object('finish_label')
3466 self
.go_online_checkbutton
= self
.xml
.get_object(
3467 'go_online_checkbutton')
3468 self
.show_vcard_checkbutton
= self
.xml
.get_object(
3469 'show_vcard_checkbutton')
3470 self
.progressbar
= self
.xml
.get_object('progressbar')
3473 self
.update_progressbar_timeout_id
= None
3475 self
.notebook
.set_current_page(0)
3476 self
.xml
.connect_signals(self
)
3477 self
.window
.show_all()
3478 gajim
.ged
.register_event_handler('new-account-connected', ged
.GUI1
,
3479 self
._nec
_new
_acc
_connected
)
3480 gajim
.ged
.register_event_handler('new-account-not-connected', ged
.GUI1
,
3481 self
._nec
_new
_acc
_not
_connected
)
3482 gajim
.ged
.register_event_handler('account-created', ged
.GUI1
,
3483 self
._nec
_acc
_is
_ok
)
3484 gajim
.ged
.register_event_handler('account-not-created', ged
.GUI1
,
3485 self
._nec
_acc
_is
_not
_ok
)
3487 def on_wizard_window_destroy(self
, widget
):
3488 page
= self
.notebook
.get_current_page()
3489 if page
in (4, 5) and self
.account
in gajim
.connections
:
3490 # connection instance is saved in gajim.connections and we canceled
3491 # the addition of the account
3492 del gajim
.connections
[self
.account
]
3493 if self
.account
in gajim
.config
.get_per('accounts'):
3494 gajim
.config
.del_per('accounts', self
.account
)
3495 gajim
.ged
.remove_event_handler('new-account-connected', ged
.GUI1
,
3496 self
._nec
_new
_acc
_connected
)
3497 gajim
.ged
.remove_event_handler('new-account-not-connected', ged
.GUI1
,
3498 self
._nec
_new
_acc
_not
_connected
)
3499 gajim
.ged
.remove_event_handler('account-created', ged
.GUI1
,
3500 self
._nec
_acc
_is
_ok
)
3501 gajim
.ged
.remove_event_handler('account-not-created', ged
.GUI1
,
3502 self
._nec
_acc
_is
_not
_ok
)
3503 del gajim
.interface
.instances
['account_creation_wizard']
3505 def on_register_server_features_button_clicked(self
, widget
):
3506 helpers
.launch_browser_mailer('url',
3507 'http://www.jabber.org/network/oldnetwork.shtml')
3509 def on_save_password_checkbutton_toggled(self
, widget
):
3510 self
.xml
.get_object('password_entry').grab_focus()
3512 def on_cancel_button_clicked(self
, widget
):
3513 self
.window
.destroy()
3515 def on_back_button_clicked(self
, widget
):
3516 cur_page
= self
.notebook
.get_current_page()
3517 if cur_page
in (1, 2):
3518 self
.notebook
.set_current_page(0)
3519 self
.back_button
.set_sensitive(False)
3521 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3522 self
.notebook
.set_current_page(2) # show server page
3524 if self
.account
in gajim
.connections
:
3525 del gajim
.connections
[self
.account
]
3526 self
.notebook
.set_current_page(2)
3527 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3528 elif cur_page
== 6: # finish page
3529 self
.forward_button
.show()
3531 self
.notebook
.set_current_page(1) # Go to parameters page
3533 self
.notebook
.set_current_page(2) # Go to server page
3535 def on_anonymous_checkbutton1_toggled(self
, widget
):
3536 active
= widget
.get_active()
3537 self
.xml
.get_object('username_entry').set_sensitive(not active
)
3538 self
.xml
.get_object('password_entry').set_sensitive(not active
)
3539 self
.xml
.get_object('save_password_checkbutton').set_sensitive(
3542 def show_finish_page(self
):
3543 self
.cancel_button
.hide()
3544 self
.back_button
.hide()
3545 self
.forward_button
.hide()
3547 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3548 _('Account has been added successfully'),
3549 _('You can set advanced account options by pressing the '
3550 'Advanced button, or later by choosing the Accounts menu item '
3551 'under the Edit menu from the main window.'))
3553 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3554 _('Your new account has been created successfully'),
3555 _('You can set advanced account options by pressing the '
3556 'Advanced button, or later by choosing the Accounts menu item '
3557 'under the Edit menu from the main window.'))
3558 self
.finish_label
.set_markup(finish_text
)
3559 self
.finish_button
.show()
3560 self
.finish_button
.set_property('has-default', True)
3561 self
.advanced_button
.show()
3562 self
.go_online_checkbutton
.show()
3563 img
= self
.xml
.get_object('finish_image')
3565 img
.set_from_stock(gtk
.STOCK_APPLY
, gtk
.ICON_SIZE_DIALOG
)
3567 path_to_file
= gtkgui_helpers
.get_icon_path('gajim', 48)
3568 img
.set_from_file(path_to_file
)
3569 self
.show_vcard_checkbutton
.set_active(not self
.modify
)
3570 self
.notebook
.set_current_page(6) # show finish page
3572 def on_forward_button_clicked(self
, widget
):
3573 cur_page
= self
.notebook
.get_current_page()
3576 widget
= self
.xml
.get_object('use_existing_account_radiobutton')
3577 if widget
.get_active():
3579 self
.notebook
.set_current_page(1)
3582 self
.notebook
.set_current_page(2)
3583 self
.back_button
.set_sensitive(True)
3587 # We are adding an existing account
3588 anonymous
= self
.xml
.get_object('anonymous_checkbutton1').\
3590 username
= self
.xml
.get_object('username_entry').get_text().decode(
3592 if not username
and not anonymous
:
3593 pritext
= _('Invalid username')
3595 'You must provide a username to configure this account.')
3596 dialogs
.ErrorDialog(pritext
, sectext
)
3598 server
= self
.xml
.get_object('server_comboboxentry').child
.\
3599 get_text().decode('utf-8').strip()
3600 savepass
= self
.xml
.get_object('save_password_checkbutton').\
3602 password
= self
.xml
.get_object('password_entry').get_text().decode(
3605 jid
= username
+ '@' + server
3606 # check if jid is conform to RFC and stringprep it
3608 jid
= helpers
.parse_jid(jid
)
3609 except helpers
.InvalidFormat
, s
:
3610 pritext
= _('Invalid Jabber ID')
3611 dialogs
.ErrorDialog(pritext
, str(s
))
3614 self
.account
= server
3616 while self
.account
in gajim
.connections
:
3617 self
.account
= server
+ str(i
)
3620 username
, server
= gajim
.get_name_and_server_from_jid(jid
)
3621 if self
.xml
.get_object('anonymous_checkbutton1').get_active():
3622 self
.save_account('', server
, False, '', anonymous
=True)
3624 self
.save_account(username
, server
, savepass
, password
)
3625 self
.show_finish_page()
3627 # We are creating a new account
3628 server
= self
.xml
.get_object('server_comboboxentry1').child
.\
3629 get_text().decode('utf-8')
3632 dialogs
.ErrorDialog(_('Invalid server'),
3633 _('Please provide a server on which you want to register.'))
3635 self
.account
= server
3637 while self
.account
in gajim
.connections
:
3638 self
.account
= server
+ str(i
)
3641 config
= self
.get_config('', server
, '', '')
3642 # Get advanced options
3643 proxies_combobox
= self
.xml
.get_object('proxies_combobox')
3644 active
= proxies_combobox
.get_active()
3645 proxy
= proxies_combobox
.get_model()[active
][0].decode('utf-8')
3646 if proxy
== _('None'):
3648 config
['proxy'] = proxy
3650 config
['use_custom_host'] = self
.xml
.get_object(
3651 'custom_host_port_checkbutton').get_active()
3652 custom_port
= self
.xml
.get_object('custom_port_entry').get_text()
3654 custom_port
= int(custom_port
)
3656 dialogs
.ErrorDialog(_('Invalid entry'),
3657 _('Custom port must be a port number.'))
3659 config
['custom_port'] = custom_port
3660 config
['custom_host'] = self
.xml
.get_object(
3661 'custom_host_entry').get_text().decode('utf-8')
3663 if self
.xml
.get_object('anonymous_checkbutton2').get_active():
3665 self
.save_account('', server
, False, '', anonymous
=True)
3666 self
.show_finish_page()
3668 self
.notebook
.set_current_page(5) # show creating page
3669 self
.back_button
.hide()
3670 self
.forward_button
.hide()
3671 self
.update_progressbar_timeout_id
= gobject
.timeout_add(100,
3672 self
.update_progressbar
)
3673 # Get form from serveur
3674 con
= connection
.Connection(self
.account
)
3675 gajim
.connections
[self
.account
] = con
3676 con
.new_account(self
.account
, config
)
3678 checked
= self
.xml
.get_object('ssl_checkbutton').get_active()
3680 hostname
= gajim
.connections
[self
.account
].new_account_info
[
3682 # Check if cert is already in file
3684 if os
.path
.isfile(gajim
.MY_CACERTS
):
3685 f
= open(gajim
.MY_CACERTS
)
3688 if self
.ssl_cert
in certs
:
3689 dialogs
.ErrorDialog(_('Certificate Already in File'),
3690 _('This certificate is already in file %s, so it\'s '
3691 'not added again.') % gajim
.MY_CACERTS
)
3693 f
= open(gajim
.MY_CACERTS
, 'a')
3694 f
.write(hostname
+ '\n')
3695 f
.write(self
.ssl_cert
+ '\n\n')
3697 gajim
.connections
[self
.account
].new_account_info
[
3698 'ssl_fingerprint_sha1'] = self
.ssl_fingerprint
3699 self
.notebook
.set_current_page(4) # show fom page
3702 form
= self
.data_form_widget
.data_form
3704 form
= self
.data_form_widget
.get_infos()
3705 gajim
.connections
[self
.account
].send_new_account_infos(form
,
3707 self
.xml
.get_object('form_vbox').remove(self
.data_form_widget
)
3708 self
.xml
.get_object('progressbar_label').set_markup(
3709 '<b>Account is being created</b>\n\nPlease wait...')
3710 self
.notebook
.set_current_page(5) # show creating page
3711 self
.back_button
.hide()
3712 self
.forward_button
.hide()
3713 self
.update_progressbar_timeout_id
= gobject
.timeout_add(100,
3714 self
.update_progressbar
)
3716 def update_proxy_list(self
):
3717 proxies_combobox
= self
.xml
.get_object('proxies_combobox')
3718 model
= gtk
.ListStore(str)
3719 proxies_combobox
.set_model(model
)
3720 l
= gajim
.config
.get_per('proxies')
3721 l
.insert(0, _('None'))
3722 for i
in xrange(len(l
)):
3723 model
.append([l
[i
]])
3724 proxies_combobox
.set_active(0)
3726 def on_manage_proxies_button_clicked(self
, widget
):
3727 if 'manage_proxies' in gajim
.interface
.instances
:
3728 gajim
.interface
.instances
['manage_proxies'].window
.present()
3730 gajim
.interface
.instances
['manage_proxies'] = \
3731 ManageProxiesWindow()
3733 def on_custom_host_port_checkbutton_toggled(self
, widget
):
3734 self
.xml
.get_object('custom_host_hbox').set_sensitive(widget
.\
3737 def update_progressbar(self
):
3738 self
.progressbar
.pulse()
3739 return True # loop forever
3741 def _nec_new_acc_connected(self
, obj
):
3743 Connection to server succeded, present the form to the user
3745 # We receive events from all accounts from GED
3746 if obj
.conn
.name
!= self
.account
:
3748 if self
.update_progressbar_timeout_id
is not None:
3749 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3750 self
.back_button
.show()
3751 self
.forward_button
.show()
3752 self
.is_form
= obj
.is_form
3754 dataform
= dataforms
.ExtendForm(node
=obj
.config
)
3755 self
.data_form_widget
= dataforms_widget
.DataFormWidget(dataform
)
3757 self
.data_form_widget
= FakeDataForm(obj
.config
)
3758 self
.data_form_widget
.show_all()
3759 self
.xml
.get_object('form_vbox').pack_start(self
.data_form_widget
)
3760 self
.ssl_fingerprint
= obj
.ssl_fingerprint
3761 self
.ssl_cert
= obj
.ssl_cert
3763 # An SSL warning occured, show it
3764 hostname
= gajim
.connections
[self
.account
].new_account_info
[
3766 self
.xml
.get_object('ssl_label').set_markup(_(
3767 '<b>Security Warning</b>'
3768 '\n\nThe authenticity of the %(hostname)s SSL certificate could'
3769 ' be invalid.\nSSL Error: %(error)s\n'
3770 'Do you still want to connect to this server?') % {
3771 'hostname': hostname
, 'error': obj
.ssl_msg
})
3772 if obj
.errnum
in (18, 27):
3773 text
= _('Add this certificate to the list of trusted '
3774 'certificates.\nSHA1 fingerprint of the certificate:\n%s') \
3775 % obj
.ssl_fingerprint
3776 self
.xml
.get_object('ssl_checkbutton').set_label(text
)
3778 self
.xml
.get_object('ssl_checkbutton').set_no_show_all(True)
3779 self
.xml
.get_object('ssl_checkbutton').hide()
3780 self
.notebook
.set_current_page(3) # show SSL page
3782 self
.notebook
.set_current_page(4) # show form page
3784 def _nec_new_acc_not_connected(self
, obj
):
3786 Account creation failed: connection to server failed
3788 # We receive events from all accounts from GED
3789 if obj
.conn
.name
!= self
.account
:
3791 if self
.account
not in gajim
.connections
:
3793 if self
.update_progressbar_timeout_id
is not None:
3794 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3795 del gajim
.connections
[self
.account
]
3796 if self
.account
in gajim
.config
.get_per('accounts'):
3797 gajim
.config
.del_per('accounts', self
.account
)
3798 self
.back_button
.show()
3799 self
.cancel_button
.show()
3800 self
.go_online_checkbutton
.hide()
3801 self
.show_vcard_checkbutton
.hide()
3802 img
= self
.xml
.get_object('finish_image')
3803 img
.set_from_stock(gtk
.STOCK_DIALOG_ERROR
, gtk
.ICON_SIZE_DIALOG
)
3804 finish_text
= '<big><b>%s</b></big>\n\n%s' % (
3805 _('An error occurred during account creation'), obj
.reason
)
3806 self
.finish_label
.set_markup(finish_text
)
3807 self
.notebook
.set_current_page(6) # show finish page
3809 def _nec_acc_is_ok(self
, obj
):
3811 Account creation succeeded
3813 # We receive events from all accounts from GED
3814 if obj
.conn
.name
!= self
.account
:
3816 self
.create_vars(obj
.account_info
)
3817 self
.show_finish_page()
3819 if self
.update_progressbar_timeout_id
is not None:
3820 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3822 def _nec_acc_is_not_ok(self
, obj
):
3824 Account creation failed
3826 # We receive events from all accounts from GED
3827 if obj
.conn
.name
!= self
.account
:
3829 self
.back_button
.show()
3830 self
.cancel_button
.show()
3831 self
.go_online_checkbutton
.hide()
3832 self
.show_vcard_checkbutton
.hide()
3833 del gajim
.connections
[self
.account
]
3834 if self
.account
in gajim
.config
.get_per('accounts'):
3835 gajim
.config
.del_per('accounts', self
.account
)
3836 img
= self
.xml
.get_object('finish_image')
3837 img
.set_from_stock(gtk
.STOCK_DIALOG_ERROR
, gtk
.ICON_SIZE_DIALOG
)
3838 finish_text
= '<big><b>%s</b></big>\n\n%s' % (_(
3839 'An error occurred during account creation'), obj
.reason
)
3840 self
.finish_label
.set_markup(finish_text
)
3841 self
.notebook
.set_current_page(6) # show finish page
3843 if self
.update_progressbar_timeout_id
is not None:
3844 gobject
.source_remove(self
.update_progressbar_timeout_id
)
3846 def on_advanced_button_clicked(self
, widget
):
3847 if 'accounts' in gajim
.interface
.instances
:
3848 gajim
.interface
.instances
['accounts'].window
.present()
3850 gajim
.interface
.instances
['accounts'] = AccountsWindow()
3851 gajim
.interface
.instances
['accounts'].select_account(self
.account
)
3852 self
.window
.destroy()
3854 def on_finish_button_clicked(self
, widget
):
3855 go_online
= self
.xml
.get_object('go_online_checkbutton').get_active()
3856 show_vcard
= self
.xml
.get_object('show_vcard_checkbutton').get_active()
3857 self
.window
.destroy()
3859 gajim
.interface
.show_vcard_when_connect
.append(self
.account
)
3861 gajim
.interface
.roster
.send_status(self
.account
, 'online', '')
3863 def on_username_entry_key_press_event(self
, widget
, event
):
3864 # Check for pressed @ and jump to combobox if found
3865 if event
.keyval
== gtk
.keysyms
.at
:
3866 combobox
= self
.xml
.get_object('server_comboboxentry')
3867 combobox
.grab_focus()
3868 combobox
.child
.set_position(-1)
3871 def on_server_comboboxentry_key_press_event(self
, widget
, event
, combobox
):
3872 # If backspace is pressed in empty field, return to the nick entry field
3873 backspace
= event
.keyval
== gtk
.keysyms
.BackSpace
3874 empty
= len(combobox
.get_active_text()) == 0
3875 if backspace
and empty
and self
.modify
:
3876 username_entry
= self
.xml
.get_object('username_entry')
3877 username_entry
.grab_focus()
3878 username_entry
.set_position(-1)
3881 def get_config(self
, login
, server
, savepass
, password
, anonymous
=False):
3883 config
['name'] = login
3884 config
['hostname'] = server
3885 config
['savepass'] = savepass
3886 config
['password'] = password
3887 config
['resource'] = 'Gajim'
3888 config
['anonymous_auth'] = anonymous
3889 config
['priority'] = 5
3890 config
['autoconnect'] = True
3891 config
['no_log_for'] = ''
3892 config
['sync_with_global_status'] = True
3893 config
['proxy'] = ''
3894 config
['usessl'] = False
3895 config
['use_custom_host'] = False
3896 config
['custom_port'] = 0
3897 config
['custom_host'] = ''
3898 config
['keyname'] = ''
3899 config
['keyid'] = ''
3902 def save_account(self
, login
, server
, savepass
, password
, anonymous
=False):
3903 if self
.account
in gajim
.connections
:
3904 dialogs
.ErrorDialog(_('Account name is in use'),
3905 _('You already have an account using this name.'))
3907 con
= connection
.Connection(self
.account
)
3908 con
.password
= password
3910 config
= self
.get_config(login
, server
, savepass
, password
, anonymous
)
3913 con
.new_account(self
.account
, config
)
3915 gajim
.connections
[self
.account
] = con
3916 self
.create_vars(config
)
3918 def create_vars(self
, config
):
3919 gajim
.config
.add_per('accounts', self
.account
)
3921 if not config
['savepass']:
3922 config
['password'] = ''
3925 gajim
.config
.set_per('accounts', self
.account
, opt
, config
[opt
])
3928 gajim
.interface
.instances
[self
.account
] = {'infos': {}, 'disco': {},
3929 'gc_config': {}, 'search': {}, 'online_dialog': {}}
3930 gajim
.interface
.minimized_controls
[self
.account
] = {}
3931 gajim
.connections
[self
.account
].connected
= 0
3932 gajim
.connections
[self
.account
].keepalives
= gajim
.config
.get_per(
3933 'accounts', self
.account
, 'keep_alive_every_foo_secs')
3934 gajim
.groups
[self
.account
] = {}
3935 gajim
.contacts
.add_account(self
.account
)
3936 gajim
.gc_connected
[self
.account
] = {}
3937 gajim
.automatic_rooms
[self
.account
] = {}
3938 gajim
.newly_added
[self
.account
] = []
3939 gajim
.to_be_removed
[self
.account
] = []
3940 gajim
.nicks
[self
.account
] = config
['name']
3941 gajim
.block_signed_in_notifications
[self
.account
] = True
3942 gajim
.sleeper_state
[self
.account
] = 'off'
3943 gajim
.encrypted_chats
[self
.account
] = []
3944 gajim
.last_message_time
[self
.account
] = {}
3945 gajim
.status_before_autoaway
[self
.account
] = ''
3946 gajim
.transport_avatar
[self
.account
] = {}
3947 gajim
.gajim_optional_features
[self
.account
] = []
3948 gajim
.caps_hash
[self
.account
] = ''
3949 # refresh accounts window
3950 if 'accounts' in gajim
.interface
.instances
:
3951 gajim
.interface
.instances
['accounts'].init_accounts()
3953 if len(gajim
.connections
) >= 2:
3954 # Do not merge accounts if only one exists
3955 gajim
.interface
.roster
.regroup
= gajim
.config
.get('mergeaccounts')
3957 gajim
.interface
.roster
.regroup
= False
3958 gajim
.interface
.roster
.setup_and_draw_roster()
3959 gajim
.interface
.roster
.set_actions_menu_needs_rebuild()
3960 gajim
.interface
.save_config()
3962 class ManagePEPServicesWindow
:
3963 def __init__(self
, account
):
3964 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_pep_services_window.ui')
3965 self
.window
= self
.xml
.get_object('manage_pep_services_window')
3966 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
3967 self
.xml
.get_object('configure_button').set_sensitive(False)
3968 self
.xml
.get_object('delete_button').set_sensitive(False)
3969 self
.xml
.connect_signals(self
)
3970 self
.account
= account
3972 self
.init_services()
3973 self
.xml
.get_object('services_treeview').get_selection().connect(
3974 'changed', self
.on_services_selection_changed
)
3976 gajim
.ged
.register_event_handler('pep-config-received', ged
.GUI1
,
3977 self
._nec
_pep
_config
_received
)
3978 gajim
.ged
.register_event_handler('agent-items-received', ged
.GUI1
,
3979 self
._nec
_agent
_items
_received
)
3981 self
.window
.show_all()
3983 def on_manage_pep_services_window_destroy(self
, widget
):
3985 del gajim
.interface
.instances
[self
.account
]['pep_services']
3986 gajim
.ged
.remove_event_handler('pep-config-received', ged
.GUI1
,
3987 self
._nec
_pep
_config
_received
)
3988 gajim
.ged
.remove_event_handler('agent-items-received', ged
.GUI1
,
3989 self
._nec
_agent
_items
_received
)
3991 def on_close_button_clicked(self
, widget
):
3992 self
.window
.destroy()
3994 def on_services_selection_changed(self
, sel
):
3995 self
.xml
.get_object('configure_button').set_sensitive(True)
3996 self
.xml
.get_object('delete_button').set_sensitive(True)
3998 def init_services(self
):
3999 self
.treeview
= self
.xml
.get_object('services_treeview')
4000 # service, access_model, group
4001 self
.treestore
= gtk
.ListStore(str)
4002 self
.treeview
.set_model(self
.treestore
)
4004 col
= gtk
.TreeViewColumn('Service')
4005 self
.treeview
.append_column(col
)
4007 cellrenderer_text
= gtk
.CellRendererText()
4008 col
.pack_start(cellrenderer_text
)
4009 col
.add_attribute(cellrenderer_text
, 'text', 0)
4011 our_jid
= gajim
.get_jid_from_account(self
.account
)
4012 gajim
.connections
[self
.account
].discoverItems(our_jid
)
4014 def _nec_agent_items_received(self
, obj
):
4015 our_jid
= gajim
.get_jid_from_account(self
.account
)
4016 for item
in obj
.items
:
4017 if 'jid' in item
and item
['jid'] == our_jid
and 'node' in item
:
4018 self
.treestore
.append([item
['node']])
4020 def node_removed(self
, jid
, node
):
4021 if jid
!= gajim
.get_jid_from_account(self
.account
):
4023 model
= self
.treeview
.get_model()
4024 iter_
= model
.get_iter_root()
4026 if model
[iter_
][0] == node
:
4029 iter_
= model
.iter_next(iter_
)
4031 def node_not_removed(self
, jid
, node
, msg
):
4032 if jid
!= gajim
.get_jid_from_account(self
.account
):
4034 dialogs
.WarningDialog(_('PEP node was not removed'),
4035 _('PEP node %(node)s was not removed: %(message)s') % {'node': node
,
4038 def on_delete_button_clicked(self
, widget
):
4039 selection
= self
.treeview
.get_selection()
4042 model
, iter_
= selection
.get_selected()
4043 node
= model
[iter_
][0]
4044 our_jid
= gajim
.get_jid_from_account(self
.account
)
4045 gajim
.connections
[self
.account
].send_pb_delete(our_jid
, node
,
4046 on_ok
=self
.node_removed
, on_fail
=self
.node_not_removed
)
4048 def on_configure_button_clicked(self
, widget
):
4049 selection
= self
.treeview
.get_selection()
4052 model
, iter_
= selection
.get_selected()
4053 node
= model
[iter_
][0]
4054 our_jid
= gajim
.get_jid_from_account(self
.account
)
4055 gajim
.connections
[self
.account
].request_pb_configuration(our_jid
, node
)
4057 def _nec_pep_config_received(self
, obj
):
4058 def on_ok(form
, node
):
4059 form
.type = 'submit'
4060 our_jid
= gajim
.get_jid_from_account(self
.account
)
4061 gajim
.connections
[self
.account
].send_pb_configure(our_jid
, node
, form
)
4062 window
= dialogs
.DataFormWindow(obj
.form
, (on_ok
, obj
.node
))
4063 title
= _('Configure %s') % obj
.node
4064 window
.set_title(title
)
4067 class ManageSoundsWindow
:
4069 self
.xml
= gtkgui_helpers
.get_gtk_builder('manage_sounds_window.ui')
4070 self
.window
= self
.xml
.get_object('manage_sounds_window')
4073 self
.sound_tree
= self
.xml
.get_object('sounds_treeview')
4075 # active, event ui name, path to sound file, event_config_name
4076 model
= gtk
.ListStore(bool, str, str, str)
4077 self
.sound_tree
.set_model(model
)
4079 col
= gtk
.TreeViewColumn(_('Active'))
4080 self
.sound_tree
.append_column(col
)
4081 renderer
= gtk
.CellRendererToggle()
4082 renderer
.set_property('activatable', True)
4083 renderer
.connect('toggled', self
.sound_toggled_cb
)
4084 col
.pack_start(renderer
)
4085 col
.set_attributes(renderer
, active
= 0)
4087 col
= gtk
.TreeViewColumn(_('Event'))
4088 self
.sound_tree
.append_column(col
)
4089 renderer
= gtk
.CellRendererText()
4090 col
.pack_start(renderer
)
4091 col
.set_attributes(renderer
, text
= 1)
4093 self
.fill_sound_treeview()
4095 self
.xml
.connect_signals(self
)
4097 self
.sound_tree
.get_model().connect('row-changed',
4098 self
.on_sounds_treemodel_row_changed
)
4100 self
.window
.show_all()
4102 def on_sounds_treemodel_row_changed(self
, model
, path
, iter_
):
4103 sound_event
= model
[iter_
][3].decode('utf-8')
4104 gajim
.config
.set_per('soundevents', sound_event
, 'enabled',
4105 bool(model
[path
][0]))
4106 gajim
.config
.set_per('soundevents', sound_event
, 'path',
4107 model
[iter_
][2].decode('utf-8'))
4108 gajim
.interface
.save_config()
4110 def sound_toggled_cb(self
, cell
, path
):
4111 model
= self
.sound_tree
.get_model()
4112 model
[path
][0] = not model
[path
][0]
4114 def fill_sound_treeview(self
):
4115 model
= self
.sound_tree
.get_model()
4117 model
.set_sort_column_id(1, gtk
.SORT_ASCENDING
)
4119 # NOTE: sounds_ui_names MUST have all items of
4120 # sounds = gajim.config.get_per('soundevents') as keys
4122 'first_message_received': _('First Message Received'),
4123 'next_message_received_focused': _('Next Message Received Focused'),
4124 'next_message_received_unfocused':
4125 _('Next Message Received Unfocused'),
4126 'contact_connected': _('Contact Connected'),
4127 'contact_disconnected': _('Contact Disconnected'),
4128 'message_sent': _('Message Sent'),
4129 'muc_message_highlight': _('Group Chat Message Highlight'),
4130 'muc_message_received': _('Group Chat Message Received'),
4131 'gmail_received': _('GMail Email Received')
4134 for sound_event_config_name
, sound_ui_name
in sounds_dict
.items():
4135 enabled
= gajim
.config
.get_per('soundevents',
4136 sound_event_config_name
, 'enabled')
4137 path
= gajim
.config
.get_per('soundevents',
4138 sound_event_config_name
, 'path')
4139 model
.append((enabled
, sound_ui_name
, path
, sound_event_config_name
))
4141 def on_treeview_sounds_cursor_changed(self
, widget
, data
= None):
4142 (model
, iter_
) = self
.sound_tree
.get_selection().get_selected()
4143 sounds_entry
= self
.xml
.get_object('sounds_entry')
4145 sounds_entry
.set_text('')
4147 path_to_snd_file
= model
[iter_
][2]
4148 sounds_entry
.set_text(path_to_snd_file
)
4150 def on_browse_for_sounds_button_clicked(self
, widget
, data
= None):
4151 (model
, iter_
) = self
.sound_tree
.get_selection().get_selected()
4154 def on_ok(widget
, path_to_snd_file
):
4155 self
.dialog
.destroy()
4156 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4157 if not path_to_snd_file
:
4158 model
[iter_
][2] = ''
4159 self
.xml
.get_object('sounds_entry').set_text('')
4160 model
[iter_
][0] = False
4162 directory
= os
.path
.dirname(path_to_snd_file
)
4163 gajim
.config
.set('last_sounds_dir', directory
)
4164 path_to_snd_file
= helpers
.strip_soundfile_path(path_to_snd_file
)
4165 self
.xml
.get_object('sounds_entry').set_text(path_to_snd_file
)
4167 model
[iter_
][2] = path_to_snd_file
# set new path to sounds_model
4168 model
[iter_
][0] = True # set the sound to enabled
4170 def on_cancel(widget
):
4171 self
.dialog
.destroy()
4173 path_to_snd_file
= model
[iter_
][2].decode('utf-8')
4174 self
.dialog
= dialogs
.SoundChooserDialog(path_to_snd_file
, on_ok
,
4177 def on_sounds_entry_changed(self
, widget
):
4178 path_to_snd_file
= widget
.get_text()
4179 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4180 model
[iter_
][2] = path_to_snd_file
# set new path to sounds_model
4182 def on_play_button_clicked(self
, widget
):
4183 model
, iter_
= self
.sound_tree
.get_selection().get_selected()
4186 snd_event_config_name
= model
[iter_
][3]
4187 helpers
.play_sound(snd_event_config_name
)
4189 def on_close_button_clicked(self
, widget
):
4192 def on_manage_sounds_window_delete_event(self
, widget
, event
):
4194 return True # do NOT destroy the window