2005-06-12 17:14:07 +02:00
## roster_window.py
##
## Gajim Team:
## - Yann Le Boulanger <asterix@lagaule.org>
## - Vincent Hanquez <tab@snarc.org>
## - Nikos Kouremenos <kourem@gmail.com>
2005-09-19 17:23:18 +02:00
## - Dimitur Kirov <dkirov@gmail.com>
2005-06-12 17:14:07 +02:00
##
## Copyright (C) 2003-2005 Gajim Team
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 2 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
import gtk
import gtk . glade
import pango
import gobject
import os
import time
2005-07-19 16:53:35 +02:00
import common . sleepy
2005-06-12 17:14:07 +02:00
import tabbed_chat_window
import groupchat_window
import history_window
import dialogs
import config
2005-10-30 10:58:13 +01:00
import disco
2005-07-30 12:20:46 +02:00
import gtkgui_helpers
2005-06-12 17:14:07 +02:00
import cell_renderer_image
2005-08-15 01:52:12 +02:00
import tooltips
2005-06-12 17:14:07 +02:00
2005-06-24 16:28:00 +02:00
from gajim import Contact
2005-06-12 17:14:07 +02:00
from common import gajim
from common import helpers
from common import i18n
_ = i18n . _
APP = i18n . APP
gtk . glade . bindtextdomain ( APP , i18n . DIR )
gtk . glade . textdomain ( APP )
2005-09-09 00:07:49 +02:00
#(icon, name, type, jid, account, editable, s)
(
C_IMG , # image to show state (online, new message etc)
C_NAME , # cellrenderer text that holds contact nickame
C_TYPE , # account, group or contact?
2005-09-09 22:28:25 +02:00
C_JID , # the jid of the row
2005-09-09 00:07:49 +02:00
C_ACCOUNT , # cellrenderer text that holds account name
C_EDITABLE , # cellrenderer text that holds name editable or not?
C_SECPIXBUF , # econdary_pixbuf
) = range ( 7 )
2005-06-12 17:14:07 +02:00
GTKGUI_GLADE = ' gtkgui.glade '
class RosterWindow :
2005-10-20 13:17:17 +02:00
''' Class for main window of gtkgui interface '''
2005-06-12 17:14:07 +02:00
def get_account_iter ( self , name ) :
2005-09-13 18:27:48 +02:00
if self . regroup :
2005-07-25 20:48:15 +02:00
return
2005-06-12 17:14:07 +02:00
model = self . tree . get_model ( )
2005-07-25 20:48:15 +02:00
if model is None :
return
2005-09-13 00:46:41 +02:00
account_iter = model . get_iter_root ( )
while account_iter :
account_name = model [ account_iter ] [ C_NAME ] . decode ( ' utf-8 ' )
2005-06-12 17:14:07 +02:00
if name == account_name :
break
2005-09-13 00:46:41 +02:00
account_iter = model . iter_next ( account_iter )
return account_iter
2005-06-12 17:14:07 +02:00
def get_group_iter ( self , name , account ) :
model = self . tree . get_model ( )
root = self . get_account_iter ( account )
2005-09-13 00:46:41 +02:00
group_iter = model . iter_children ( root )
while group_iter :
group_name = model [ group_iter ] [ C_NAME ] . decode ( ' utf-8 ' )
2005-06-12 17:14:07 +02:00
if name == group_name :
break
2005-09-13 00:46:41 +02:00
group_iter = model . iter_next ( group_iter )
return group_iter
2005-06-12 17:14:07 +02:00
2005-07-07 18:38:36 +02:00
def get_contact_iter ( self , jid , account ) :
2005-06-12 17:14:07 +02:00
model = self . tree . get_model ( )
acct = self . get_account_iter ( account )
found = [ ]
fin = False
2005-10-30 22:46:48 +01:00
if model is None : # when closing Gajim model can be none (async pbs?)
return found
2005-09-13 00:46:41 +02:00
group_iter = model . iter_children ( acct )
while group_iter :
user_iter = model . iter_children ( group_iter )
while user_iter :
if jid == model [ user_iter ] [ C_JID ] . decode ( ' utf-8 ' ) :
found . append ( user_iter )
user_iter = model . iter_next ( user_iter )
group_iter = model . iter_next ( group_iter )
2005-06-12 17:14:07 +02:00
return found
def add_account_to_roster ( self , account ) :
2005-09-13 18:27:48 +02:00
if self . regroup :
2005-06-12 17:14:07 +02:00
return
model = self . tree . get_model ( )
if self . get_account_iter ( account ) :
return
statuss = [ ' offline ' , ' connecting ' , ' online ' , ' chat ' ,
' away ' , ' xa ' , ' dnd ' , ' invisible ' ]
status = statuss [ gajim . connections [ account ] . connected ]
2005-06-29 14:57:46 +02:00
tls_pixbuf = None
2005-07-18 23:08:31 +02:00
if gajim . con_types . has_key ( account ) and \
2005-07-23 17:23:45 +02:00
gajim . con_types [ account ] in ( ' tls ' , ' ssl ' ) :
2005-06-29 14:57:46 +02:00
tls_pixbuf = self . window . render_icon ( gtk . STOCK_DIALOG_AUTHENTICATION ,
2005-07-07 18:38:36 +02:00
gtk . ICON_SIZE_MENU ) # the only way to create a pixbuf from stock
2005-06-29 14:57:46 +02:00
2005-09-13 00:46:41 +02:00
our_jid = gajim . get_jid_from_account ( account )
2005-09-12 19:57:16 +02:00
2005-06-29 14:57:46 +02:00
model . append ( None , [ self . jabber_state_images [ status ] , account ,
2005-09-12 19:57:16 +02:00
' account ' , our_jid , account , False , tls_pixbuf ] )
2005-06-12 17:14:07 +02:00
def remove_newly_added ( self , jid , account ) :
2005-07-18 23:08:31 +02:00
if jid in gajim . newly_added [ account ] :
gajim . newly_added [ account ] . remove ( jid )
2005-06-12 17:14:07 +02:00
self . draw_contact ( jid , account )
2005-07-07 18:38:36 +02:00
def add_contact_to_roster ( self , jid , account ) :
''' Add a contact to the roster and add groups if they aren ' t in roster '''
2005-06-12 17:14:07 +02:00
showOffline = gajim . config . get ( ' showoffline ' )
2005-07-18 23:08:31 +02:00
if not gajim . contacts [ account ] . has_key ( jid ) :
2005-06-12 17:14:07 +02:00
return
2005-07-18 23:08:31 +02:00
users = gajim . contacts [ account ] [ jid ]
2005-06-12 17:14:07 +02:00
user = users [ 0 ]
if user . jid . find ( ' @ ' ) < = 0 : # if not '@' or '@' starts the jid ==> agent
2005-07-07 19:25:04 +02:00
user . groups = [ _ ( ' Transports ' ) ]
2005-06-12 17:14:07 +02:00
elif user . groups == [ ] :
2005-07-05 01:18:29 +02:00
user . groups . append ( _ ( ' General ' ) )
2005-06-12 17:14:07 +02:00
2005-07-23 17:23:45 +02:00
if user . show in ( ' offline ' , ' error ' ) and \
2005-07-07 19:25:04 +02:00
not showOffline and ( not _ ( ' Transports ' ) in user . groups or \
2005-06-12 17:14:07 +02:00
gajim . connections [ account ] . connected < 2 ) and \
2005-10-15 22:49:08 +02:00
not gajim . awaiting_events [ account ] . has_key ( user . jid ) :
2005-06-12 17:14:07 +02:00
return
model = self . tree . get_model ( )
for g in user . groups :
iterG = self . get_group_iter ( g , account )
if not iterG :
IterAcct = self . get_account_iter ( account )
2005-08-03 21:31:16 +02:00
iterG = model . append ( IterAcct , [ self . jabber_state_images [ ' closed ' ] ,
g , ' group ' , g , account , False , None ] )
2005-07-18 23:08:31 +02:00
if not gajim . groups [ account ] . has_key ( g ) : #It can probably never append
2005-06-12 17:14:07 +02:00
if account + g in self . collapsed_rows :
ishidden = False
else :
ishidden = True
2005-07-18 23:08:31 +02:00
gajim . groups [ account ] [ g ] = { ' expand ' : ishidden }
2005-06-12 17:14:07 +02:00
if not account in self . collapsed_rows and \
2005-09-13 18:27:48 +02:00
not gajim . config . get ( ' mergeaccounts ' ) :
2005-06-12 17:14:07 +02:00
self . tree . expand_row ( ( model . get_path ( iterG ) [ 0 ] ) , False )
2005-07-07 18:38:36 +02:00
typestr = ' contact '
2005-07-07 19:25:04 +02:00
if g == _ ( ' Transports ' ) :
2005-06-12 17:14:07 +02:00
typestr = ' agent '
2005-06-29 14:57:46 +02:00
model . append ( iterG , [ self . jabber_state_images [ user . show ] , user . name ,
typestr , user . jid , account , False , None ] ) # FIXME None --> avatar
2005-06-12 17:14:07 +02:00
2005-07-18 23:08:31 +02:00
if gajim . groups [ account ] [ g ] [ ' expand ' ] :
2005-08-26 02:52:44 +02:00
self . tree . expand_row ( model . get_path ( iterG ) , False )
2005-06-12 17:14:07 +02:00
self . draw_contact ( jid , account )
2005-07-21 19:54:58 +02:00
def really_remove_contact ( self , user , account ) :
2005-07-18 23:08:31 +02:00
if user . jid in gajim . newly_added [ account ] :
2005-06-12 17:14:07 +02:00
return
if user . jid . find ( ' @ ' ) < 1 and gajim . connections [ account ] . connected > 1 : # It's an agent
return
2005-07-18 23:08:31 +02:00
if user . jid in gajim . to_be_removed [ account ] :
gajim . to_be_removed [ account ] . remove ( user . jid )
2005-06-12 17:14:07 +02:00
if gajim . config . get ( ' showoffline ' ) :
self . draw_contact ( user . jid , account )
return
2005-07-21 19:54:58 +02:00
self . remove_contact ( user , account )
2005-06-12 17:14:07 +02:00
2005-07-21 19:54:58 +02:00
def remove_contact ( self , user , account ) :
2005-06-12 17:14:07 +02:00
''' Remove a user from the roster '''
2005-07-18 23:08:31 +02:00
if user . jid in gajim . to_be_removed [ account ] :
2005-06-12 17:14:07 +02:00
return
model = self . tree . get_model ( )
2005-07-07 18:38:36 +02:00
for i in self . get_contact_iter ( user . jid , account ) :
2005-06-12 17:14:07 +02:00
parent_i = model . iter_parent ( i )
2005-08-26 02:52:44 +02:00
group = model . get_value ( parent_i , 3 ) . decode ( ' utf-8 ' )
2005-06-12 17:14:07 +02:00
model . remove ( i )
if model . iter_n_children ( parent_i ) == 0 :
model . remove ( parent_i )
# We need to check all contacts, even offline contacts
2005-07-18 23:08:31 +02:00
for jid in gajim . contacts [ account ] :
if group in gajim . contacts [ account ] [ jid ] [ 0 ] . groups :
2005-06-12 17:14:07 +02:00
break
2005-08-27 16:08:00 +02:00
else :
2005-10-11 18:35:33 +02:00
if gajim . groups [ account ] . has_key ( group ) :
del gajim . groups [ account ] [ group ]
2005-07-18 23:08:31 +02:00
2005-07-15 20:13:54 +02:00
def get_appropriate_state_images ( self , jid ) :
''' check jid and return the appropriate state images dict '''
2005-08-26 15:11:20 +02:00
transport = gajim . get_transport_name_from_jid ( jid )
2005-07-15 20:13:54 +02:00
if transport :
return self . transports_state_images [ transport ]
return self . jabber_state_images
2005-06-12 17:14:07 +02:00
2005-11-07 11:50:40 +01:00
def draw_contact ( self , jid , account , selected = False ) :
2005-06-12 17:14:07 +02:00
''' draw the correct state image and name '''
model = self . tree . get_model ( )
2005-07-07 18:38:36 +02:00
iters = self . get_contact_iter ( jid , account )
2005-06-12 17:14:07 +02:00
if len ( iters ) == 0 :
return
2005-08-10 19:26:43 +02:00
contact_instances = gajim . get_contact_instances_from_jid ( account , jid )
contact = gajim . get_highest_prio_contact_from_contacts ( contact_instances )
2005-07-21 16:56:39 +02:00
name = contact . name
2005-11-06 15:30:17 +01:00
2005-07-21 16:56:39 +02:00
if len ( contact_instances ) > 1 :
2005-08-26 02:52:44 +02:00
name + = ' ( ' + unicode ( len ( contact_instances ) ) + ' ) '
2005-07-21 16:56:39 +02:00
2005-11-06 15:30:17 +01:00
# add status msg, if not empty, under contact name in the treeview
if contact . status and gajim . config . get ( ' show_status_msgs_in_roster ' ) :
status = contact . status . strip ( )
if status != ' ' :
2005-11-06 17:29:52 +01:00
# escape markup entities and make them small italic and fg color
2005-11-07 12:07:55 +01:00
color = gtkgui_helpers . _get_fade_color ( self . tree , selected )
2005-11-07 11:50:40 +01:00
colorstring = " # %04x %04x %04x " % ( color . red , color . green , color . blue )
2005-11-06 16:08:54 +01:00
name + = ' \n <span size= " small " style= " italic " foreground= " %s " > %s </span> ' \
% ( colorstring , gtkgui_helpers . escape_for_pango_markup ( status ) )
2005-11-06 15:30:17 +01:00
2005-06-12 17:14:07 +02:00
state_images = self . get_appropriate_state_images ( jid )
2005-10-15 22:49:08 +02:00
if gajim . awaiting_events [ account ] . has_key ( jid ) :
2005-11-06 15:30:17 +01:00
#FIXME: change icon for FT
2005-06-12 17:14:07 +02:00
img = state_images [ ' message ' ]
elif jid . find ( ' @ ' ) < = 0 : # if not '@' or '@' starts the jid ==> agent
2005-07-21 16:56:39 +02:00
img = state_images [ contact . show ]
2005-06-12 17:14:07 +02:00
else :
2005-10-27 15:15:03 +02:00
if contact . sub in ( ' both ' , ' to ' ) :
2005-07-21 16:56:39 +02:00
img = state_images [ contact . show ]
2005-06-12 17:14:07 +02:00
else :
2005-07-21 16:56:39 +02:00
if contact . ask == ' subscribe ' :
2005-06-12 17:14:07 +02:00
img = state_images [ ' requested ' ]
else :
2005-08-26 15:11:20 +02:00
transport = gajim . get_transport_name_from_jid ( jid )
2005-07-21 16:56:39 +02:00
if transport and state_images . has_key ( contact . show ) :
img = state_images [ contact . show ]
2005-07-17 13:49:29 +02:00
else :
2005-08-03 14:19:18 +02:00
img = state_images [ ' not in the roster ' ]
2005-06-12 17:14:07 +02:00
for iter in iters :
2005-09-13 00:12:17 +02:00
model [ iter ] [ C_IMG ] = img
model [ iter ] [ C_NAME ] = name
2005-06-29 14:57:46 +02:00
#FIXME: add avatar
2005-06-12 17:14:07 +02:00
2005-06-13 12:49:48 +02:00
def join_gc_room ( self , account , room_jid , nick , password ) :
2005-10-20 13:17:17 +02:00
if room_jid in gajim . interface . windows [ account ] [ ' gc ' ] and \
2005-08-03 11:23:36 +02:00
gajim . gc_connected [ account ] [ room_jid ] :
2005-06-18 13:40:56 +02:00
dialogs . ErrorDialog ( _ ( ' You are already in room %s ' ) % room_jid
) . get_response ( )
2005-06-13 12:49:48 +02:00
return
2005-09-30 19:52:25 +02:00
invisible_show = gajim . SHOW_LIST . index ( ' invisible ' )
if gajim . connections [ account ] . connected == invisible_show :
2005-10-09 15:53:21 +02:00
dialogs . ErrorDialog ( _ ( ' You cannot join a room while you are invisible ' )
2005-09-30 19:52:25 +02:00
) . get_response ( )
return
2005-06-13 12:49:48 +02:00
room , server = room_jid . split ( ' @ ' )
2005-10-20 13:17:17 +02:00
if not room_jid in gajim . interface . windows [ account ] [ ' gc ' ] :
2005-08-04 23:14:43 +02:00
self . new_room ( room_jid , nick , account )
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' gc ' ] [ room_jid ] . set_active_tab ( room_jid )
gajim . interface . windows [ account ] [ ' gc ' ] [ room_jid ] . window . present ( )
2005-06-13 12:49:48 +02:00
gajim . connections [ account ] . join_gc ( nick , room , server , password )
2005-06-12 17:14:07 +02:00
def on_bookmark_menuitem_activate ( self , widget , account , bookmark ) :
2005-06-13 12:49:48 +02:00
self . join_gc_room ( account , bookmark [ ' jid ' ] , bookmark [ ' nick ' ] ,
bookmark [ ' password ' ] )
2005-06-12 17:14:07 +02:00
def on_bm_header_changed_state ( self , widget , event ) :
widget . set_state ( gtk . STATE_NORMAL ) #do not allow selected_state
2005-07-18 11:55:55 +02:00
def on_send_server_message_menuitem_activate ( self , widget , account ) :
2005-08-06 21:14:21 +02:00
server = gajim . config . get_per ( ' accounts ' , account , ' hostname ' )
server + = ' /announce/online '
2005-10-20 13:17:17 +02:00
dialogs . SingleMessageWindow ( account , server , ' send ' )
2005-08-06 21:14:21 +02:00
def on_xml_console_menuitem_activate ( self , widget , account ) :
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ account ] . has_key ( ' xml_console ' ) :
gajim . interface . windows [ account ] [ ' xml_console ' ] . window . present ( )
2005-08-06 21:14:21 +02:00
else :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' xml_console ' ] . window . show_all ( )
2005-07-18 11:55:55 +02:00
def on_set_motd_menuitem_activate ( self , widget , account ) :
2005-08-06 21:14:21 +02:00
server = gajim . config . get_per ( ' accounts ' , account , ' hostname ' )
server + = ' /announce/motd '
2005-10-20 13:17:17 +02:00
dialogs . SingleMessageWindow ( account , server , ' send ' )
2005-07-18 11:55:55 +02:00
def on_update_motd_menuitem_activate ( self , widget , account ) :
2005-08-06 21:14:21 +02:00
server = gajim . config . get_per ( ' accounts ' , account , ' hostname ' )
server + = ' /announce/motd/update '
2005-10-20 13:17:17 +02:00
dialogs . SingleMessageWindow ( account , server , ' send ' )
2005-07-18 11:55:55 +02:00
def on_delete_motd_menuitem_activate ( self , widget , account ) :
2005-08-06 21:14:21 +02:00
server = gajim . config . get_per ( ' accounts ' , account , ' hostname ' )
server + = ' /announce/motd/delete '
gajim . connections [ account ] . send_motd ( server )
def on_online_users_menuitem_activate ( self , widget , account ) :
pass #FIXME: impement disco in users for 0.9
def get_and_connect_advanced_menuitem_menu ( self , account ) :
xml = gtk . glade . XML ( GTKGUI_GLADE , ' advanced_menuitem_menu ' , APP )
advanced_menuitem_menu = xml . get_widget ( ' advanced_menuitem_menu ' )
send_single_message_menuitem = xml . get_widget (
' send_single_message_menuitem ' )
xml_console_menuitem = xml . get_widget ( ' xml_console_menuitem ' )
administrator_menuitem = xml . get_widget ( ' administrator_menuitem ' )
online_users_menuitem = xml . get_widget ( ' online_users_menuitem ' )
send_server_message_menuitem = xml . get_widget (
' send_server_message_menuitem ' )
set_motd_menuitem = xml . get_widget ( ' set_motd_menuitem ' )
update_motd_menuitem = xml . get_widget ( ' update_motd_menuitem ' )
delete_motd_menuitem = xml . get_widget ( ' delete_motd_menuitem ' )
send_single_message_menuitem . connect ( ' activate ' ,
self . on_send_single_message_menuitem_activate , account )
xml_console_menuitem . connect ( ' activate ' ,
self . on_xml_console_menuitem_activate , account )
#FIXME: 0.9 should have this: it does disco in the place where users are
online_users_menuitem . set_no_show_all ( True )
online_users_menuitem . hide ( )
online_users_menuitem . connect ( ' activate ' ,
self . on_online_users_menuitem_activate , account )
send_server_message_menuitem . connect ( ' activate ' ,
self . on_send_server_message_menuitem_activate , account )
set_motd_menuitem . connect ( ' activate ' ,
self . on_set_motd_menuitem_activate , account )
update_motd_menuitem . connect ( ' activate ' ,
self . on_update_motd_menuitem_activate , account )
delete_motd_menuitem . connect ( ' activate ' ,
self . on_delete_motd_menuitem_activate , account )
2005-08-06 22:16:50 +02:00
advanced_menuitem_menu . show_all ( )
2005-08-06 21:14:21 +02:00
return advanced_menuitem_menu
2005-07-18 11:55:55 +02:00
2005-06-12 17:14:07 +02:00
def make_menu ( self ) :
2005-07-07 17:41:03 +02:00
''' create the main window ' s menus '''
2005-06-12 17:14:07 +02:00
new_message_menuitem = self . xml . get_widget ( ' new_message_menuitem ' )
join_gc_menuitem = self . xml . get_widget ( ' join_gc_menuitem ' )
add_new_contact_menuitem = self . xml . get_widget ( ' add_new_contact_menuitem ' )
service_disco_menuitem = self . xml . get_widget ( ' service_disco_menuitem ' )
2005-07-06 15:34:47 +02:00
advanced_menuitem = self . xml . get_widget ( ' advanced_menuitem ' )
show_offline_contacts_menuitem = self . xml . get_widget (
' show_offline_contacts_menuitem ' )
profile_avatar_menuitem = self . xml . get_widget ( ' profile_avatar_menuitem ' )
2005-08-18 18:51:03 +02:00
# make it sensitive. it is insensitive only if no accounts are *available*
advanced_menuitem . set_sensitive ( True )
2005-08-06 22:16:50 +02:00
2005-07-18 11:55:55 +02:00
2005-06-12 17:14:07 +02:00
if self . add_new_contact_handler_id :
2005-07-06 15:34:47 +02:00
add_new_contact_menuitem . handler_disconnect (
self . add_new_contact_handler_id )
2005-06-12 17:14:07 +02:00
self . add_new_contact_handler_id = None
2005-07-07 17:41:03 +02:00
2005-06-12 17:14:07 +02:00
if self . service_disco_handler_id :
service_disco_menuitem . handler_disconnect (
2005-06-13 12:21:12 +02:00
self . service_disco_handler_id )
2005-06-12 17:14:07 +02:00
self . service_disco_handler_id = None
2005-07-07 17:41:03 +02:00
2005-06-12 17:14:07 +02:00
if self . new_message_menuitem_handler_id :
new_message_menuitem . handler_disconnect (
2005-06-13 12:21:12 +02:00
self . new_message_menuitem_handler_id )
2005-06-12 17:14:07 +02:00
self . new_message_menuitem_handler_id = None
2005-07-07 17:41:03 +02:00
2005-06-12 17:14:07 +02:00
#remove the existing submenus
add_new_contact_menuitem . remove_submenu ( )
service_disco_menuitem . remove_submenu ( )
join_gc_menuitem . remove_submenu ( )
new_message_menuitem . remove_submenu ( )
2005-08-14 23:52:48 +02:00
advanced_menuitem . remove_submenu ( )
2005-06-12 17:14:07 +02:00
2005-07-05 22:47:25 +02:00
#remove the existing accelerator
if self . have_new_message_accel :
ag = gtk . accel_groups_from_object ( self . window ) [ 0 ]
2005-08-06 21:14:21 +02:00
new_message_menuitem . remove_accelerator ( ag , gtk . keysyms . n ,
gtk . gdk . CONTROL_MASK )
2005-07-05 22:47:25 +02:00
self . have_new_message_accel = False
2005-06-12 17:14:07 +02:00
#join gc
sub_menu = gtk . Menu ( )
join_gc_menuitem . set_submenu ( sub_menu )
at_least_one_account_connected = False
2005-08-18 18:51:03 +02:00
multiple_accounts = len ( gajim . connections ) > = 2 #FIXME: stop using bool var here
2005-06-12 17:14:07 +02:00
for account in gajim . connections :
if gajim . connections [ account ] . connected < = 1 : #if offline or connecting
continue
if not at_least_one_account_connected :
at_least_one_account_connected = True
if multiple_accounts :
label = gtk . Label ( )
label . set_markup ( ' <u> ' + account . upper ( ) + ' </u> ' )
2005-08-09 18:33:45 +02:00
item = gtk . MenuItem ( )
2005-06-12 17:14:07 +02:00
item . add ( label )
item . connect ( ' state-changed ' , self . on_bm_header_changed_state )
sub_menu . append ( item )
2005-09-11 03:06:58 +02:00
item = gtk . MenuItem ( _ ( ' _Join New Room ' ) )
2005-06-12 17:14:07 +02:00
item . connect ( ' activate ' , self . on_join_gc_activate , account )
2005-08-06 21:14:21 +02:00
sub_menu . append ( item )
2005-06-12 17:14:07 +02:00
for bookmark in gajim . connections [ account ] . bookmarks :
item = gtk . MenuItem ( bookmark [ ' name ' ] )
item . connect ( ' activate ' , self . on_bookmark_menuitem_activate ,
account , bookmark )
2005-08-06 21:14:21 +02:00
sub_menu . append ( item )
2005-06-12 17:14:07 +02:00
2005-08-18 18:51:03 +02:00
if at_least_one_account_connected : #FIXME: move this below where we do this check
#and make sure it works
2005-08-07 17:22:51 +02:00
newitem = gtk . SeparatorMenuItem ( ) # seperator
2005-06-12 17:14:07 +02:00
sub_menu . append ( newitem )
2005-07-06 16:34:59 +02:00
newitem = gtk . ImageMenuItem ( _ ( ' Manage Bookmarks... ' ) )
img = gtk . image_new_from_stock ( gtk . STOCK_PREFERENCES ,
gtk . ICON_SIZE_MENU )
newitem . set_image ( img )
2005-08-07 14:55:59 +02:00
newitem . connect ( ' activate ' , self . on_manage_bookmarks_menuitem_activate )
2005-08-06 21:14:21 +02:00
sub_menu . append ( newitem )
2005-06-12 17:14:07 +02:00
sub_menu . show_all ( )
if multiple_accounts : # 2 or more accounts? make submenus
#add
sub_menu = gtk . Menu ( )
for account in gajim . connections :
2005-07-18 11:55:55 +02:00
if gajim . connections [ account ] . connected < = 1 :
#if offline or connecting
2005-06-20 01:01:45 +02:00
continue
2005-07-07 17:41:03 +02:00
item = gtk . MenuItem ( _ ( ' to %s account ' ) % account )
2005-06-12 17:14:07 +02:00
sub_menu . append ( item )
item . connect ( ' activate ' , self . on_add_new_contact , account )
2005-08-06 21:14:21 +02:00
add_new_contact_menuitem . set_submenu ( sub_menu )
2005-06-12 17:14:07 +02:00
sub_menu . show_all ( )
2005-07-07 17:41:03 +02:00
2005-06-12 17:14:07 +02:00
#disco
sub_menu = gtk . Menu ( )
for account in gajim . connections :
2005-07-18 11:55:55 +02:00
if gajim . connections [ account ] . connected < = 1 :
#if offline or connecting
2005-06-20 01:01:45 +02:00
continue
2005-07-07 17:41:03 +02:00
item = gtk . MenuItem ( _ ( ' using %s account ' ) % account )
2005-06-12 17:14:07 +02:00
sub_menu . append ( item )
2005-07-23 17:23:45 +02:00
item . connect ( ' activate ' , self . on_service_disco_menuitem_activate ,
account )
2005-08-06 21:14:21 +02:00
service_disco_menuitem . set_submenu ( sub_menu )
2005-06-12 17:14:07 +02:00
sub_menu . show_all ( )
#new message
sub_menu = gtk . Menu ( )
for account in gajim . connections :
2005-07-18 11:55:55 +02:00
if gajim . connections [ account ] . connected < = 1 :
#if offline or connecting
2005-06-20 01:01:45 +02:00
continue
2005-06-12 17:14:07 +02:00
our_jid = gajim . config . get_per ( ' accounts ' , account , ' name ' ) + ' @ ' + \
gajim . config . get_per ( ' accounts ' , account , ' hostname ' )
2005-07-07 17:41:03 +02:00
item = gtk . MenuItem ( _ ( ' as %s ' ) % our_jid )
2005-06-12 17:14:07 +02:00
sub_menu . append ( item )
item . connect ( ' activate ' , self . on_new_message_menuitem_activate ,
account )
2005-08-06 21:14:21 +02:00
new_message_menuitem . set_submenu ( sub_menu )
2005-06-12 17:14:07 +02:00
sub_menu . show_all ( )
2005-07-07 17:41:03 +02:00
#Advanced Actions
2005-07-18 11:55:55 +02:00
sub_menu = gtk . Menu ( )
2005-07-07 17:41:03 +02:00
for account in gajim . connections :
2005-08-06 21:14:21 +02:00
item = gtk . MenuItem ( _ ( ' for account %s ' ) % account )
2005-07-07 17:41:03 +02:00
sub_menu . append ( item )
2005-08-06 21:14:21 +02:00
advanced_menuitem_menu = self . get_and_connect_advanced_menuitem_menu (
account )
item . set_submenu ( advanced_menuitem_menu )
advanced_menuitem . set_submenu ( sub_menu )
2005-07-07 17:41:03 +02:00
sub_menu . show_all ( )
2005-06-12 17:14:07 +02:00
else :
2005-07-07 18:38:36 +02:00
if len ( gajim . connections ) == 1 : # user has only one account
2005-06-12 17:14:07 +02:00
#add
if not self . add_new_contact_handler_id :
self . add_new_contact_handler_id = add_new_contact_menuitem . connect (
' activate ' , self . on_add_new_contact , gajim . connections . keys ( ) [ 0 ] )
#disco
if not self . service_disco_handler_id :
self . service_disco_handler_id = service_disco_menuitem . connect (
' activate ' , self . on_service_disco_menuitem_activate ,
gajim . connections . keys ( ) [ 0 ] )
2005-07-07 17:41:03 +02:00
#new msg
2005-06-12 17:14:07 +02:00
if not self . new_message_menuitem_handler_id :
self . new_message_menuitem_handler_id = new_message_menuitem . \
connect ( ' activate ' , self . on_new_message_menuitem_activate ,
gajim . connections . keys ( ) [ 0 ] )
2005-07-07 17:41:03 +02:00
#new msg accel
2005-07-05 22:47:25 +02:00
if not self . have_new_message_accel :
ag = gtk . accel_groups_from_object ( self . window ) [ 0 ]
2005-07-06 16:34:59 +02:00
new_message_menuitem . add_accelerator ( ' activate ' , ag ,
gtk . keysyms . n , gtk . gdk . CONTROL_MASK , gtk . ACCEL_VISIBLE )
2005-07-05 22:47:25 +02:00
self . have_new_message_accel = True
2005-07-07 17:41:03 +02:00
2005-08-06 21:14:21 +02:00
account = gajim . connections . keys ( ) [ 0 ]
advanced_menuitem_menu = self . get_and_connect_advanced_menuitem_menu (
account )
advanced_menuitem . set_submenu ( advanced_menuitem_menu )
2005-08-18 18:51:03 +02:00
elif len ( gajim . connections ) == 0 : # user has no accounts
advanced_menuitem . set_sensitive ( False )
2005-06-12 17:14:07 +02:00
2005-08-06 21:14:21 +02:00
#FIXME: Gajim 0.9 should have this visible
profile_avatar_menuitem . set_no_show_all ( True )
profile_avatar_menuitem . hide ( )
2005-06-12 17:14:07 +02:00
if at_least_one_account_connected :
new_message_menuitem . set_sensitive ( True )
join_gc_menuitem . set_sensitive ( True )
add_new_contact_menuitem . set_sensitive ( True )
service_disco_menuitem . set_sensitive ( True )
show_offline_contacts_menuitem . set_sensitive ( True )
else :
2005-07-06 15:34:47 +02:00
# make the menuitems insensitive
2005-06-12 17:14:07 +02:00
new_message_menuitem . set_sensitive ( False )
join_gc_menuitem . set_sensitive ( False )
add_new_contact_menuitem . set_sensitive ( False )
service_disco_menuitem . set_sensitive ( False )
show_offline_contacts_menuitem . set_sensitive ( False )
2005-07-06 15:34:47 +02:00
profile_avatar_menuitem . set_sensitive ( False )
2005-06-12 17:14:07 +02:00
2005-09-19 17:23:18 +02:00
def _change_style ( self , model , path , iter , option ) :
if option is None :
model [ iter ] [ C_NAME ] = model [ iter ] [ C_NAME ]
elif model [ iter ] [ C_TYPE ] == ' account ' :
if option == ' account ' :
model [ iter ] [ C_NAME ] = model [ iter ] [ C_NAME ]
elif model [ iter ] [ C_TYPE ] == ' group ' :
if option == ' group ' :
model [ iter ] [ C_NAME ] = model [ iter ] [ C_NAME ]
elif model [ iter ] [ C_TYPE ] == ' contact ' :
if option == ' contact ' :
model [ iter ] [ C_NAME ] = model [ iter ] [ C_NAME ]
def change_roster_style ( self , option ) :
model = self . tree . get_model ( )
model . foreach ( self . _change_style , option )
2005-06-12 17:14:07 +02:00
def draw_roster ( self ) :
''' Clear and draw roster '''
self . tree . get_model ( ) . clear ( )
for acct in gajim . connections :
self . add_account_to_roster ( acct )
2005-07-18 23:08:31 +02:00
for jid in gajim . contacts [ acct ] . keys ( ) :
2005-07-07 18:38:36 +02:00
self . add_contact_to_roster ( jid , acct )
2005-08-15 00:00:48 +02:00
self . make_menu ( ) # re-make menu in case an account was removed
#FIXME: maybe move thie make_menu() in where we remove the account?
2005-06-12 17:14:07 +02:00
2005-07-22 16:30:35 +02:00
def fill_contacts_and_groups_dicts ( self , array , account ) :
2005-07-18 23:08:31 +02:00
''' fill gajim.contacts and gajim.groups '''
if not gajim . contacts . has_key ( account ) :
gajim . contacts [ account ] = { }
if not gajim . groups . has_key ( account ) :
gajim . groups [ account ] = { }
2005-06-12 17:14:07 +02:00
for jid in array . keys ( ) :
jids = jid . split ( ' / ' )
#get jid
ji = jids [ 0 ]
#get resource
resource = ' '
if len ( jids ) > 1 :
resource = ' / ' . join ( jids [ 1 : ] )
#get name
name = array [ jid ] [ ' name ' ]
if not name :
if ji . find ( ' @ ' ) < = 0 :
name = ji
else :
name = jid . split ( ' @ ' ) [ 0 ]
show = ' offline ' # show is offline by default
status = ' ' #no status message by default
keyID = ' '
attached_keys = gajim . config . get_per ( ' accounts ' , account ,
' attached_gpg_keys ' ) . split ( )
if jid in attached_keys :
keyID = attached_keys [ attached_keys . index ( jid ) + 1 ]
2005-07-22 16:30:35 +02:00
contact1 = Contact ( jid = ji , name = name , groups = array [ jid ] [ ' groups ' ] ,
2005-06-25 11:18:39 +02:00
show = show , status = status , sub = array [ jid ] [ ' subscription ' ] ,
ask = array [ jid ] [ ' ask ' ] , resource = resource , keyID = keyID )
2005-06-12 17:14:07 +02:00
# when we draw the roster, we avoid having the same contact
2005-07-22 16:30:35 +02:00
# more than once (f.e. we avoid showing it twice when 2 resources)
gajim . contacts [ account ] [ ji ] = [ contact1 ]
2005-06-12 17:14:07 +02:00
for g in array [ jid ] [ ' groups ' ] :
2005-07-18 23:08:31 +02:00
if g in gajim . groups [ account ] . keys ( ) :
2005-06-12 17:14:07 +02:00
continue
if account + g in self . collapsed_rows :
ishidden = False
else :
ishidden = True
2005-07-18 23:08:31 +02:00
gajim . groups [ account ] [ g ] = { ' expand ' : ishidden }
2005-06-12 17:14:07 +02:00
2005-07-21 19:54:58 +02:00
def chg_contact_status ( self , contact , show , status , account ) :
2005-07-07 18:38:36 +02:00
''' When a contact changes his status '''
2005-06-12 17:14:07 +02:00
showOffline = gajim . config . get ( ' showoffline ' )
model = self . tree . get_model ( )
2005-07-21 19:54:58 +02:00
contact_instances = gajim . contacts [ account ] [ contact . jid ]
contact . show = show
contact . status = status
2005-07-23 17:23:45 +02:00
if show in ( ' offline ' , ' error ' ) and \
2005-10-15 22:49:08 +02:00
not gajim . awaiting_events [ account ] . has_key ( contact . jid ) :
2005-07-21 19:54:58 +02:00
if len ( contact_instances ) > 1 : # if multiple resources
contact_instances . remove ( contact )
self . draw_contact ( contact . jid , account )
2005-06-12 17:14:07 +02:00
elif not showOffline :
2005-07-21 19:54:58 +02:00
self . remove_contact ( contact , account )
2005-06-12 17:14:07 +02:00
else :
2005-07-21 19:54:58 +02:00
self . draw_contact ( contact . jid , account )
2005-06-12 17:14:07 +02:00
else :
2005-07-21 19:54:58 +02:00
if not self . get_contact_iter ( contact . jid , account ) :
self . add_contact_to_roster ( contact . jid , account )
self . draw_contact ( contact . jid , account )
2005-10-07 15:00:44 +02:00
# print status in chat window and update status/GPG image
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ account ] [ ' chats ' ] . has_key ( contact . jid ) :
2005-07-21 19:54:58 +02:00
jid = contact . jid
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . set_state_image ( jid )
2005-07-21 19:54:58 +02:00
name = contact . name
if contact . resource != ' ' :
name + = ' / ' + contact . resource
2005-06-12 17:14:07 +02:00
uf_show = helpers . get_uf_show ( show )
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . print_conversation (
2005-06-12 17:14:07 +02:00
_ ( ' %s is now %s ( %s ) ' ) % ( name , uf_show , status ) , jid , ' status ' )
2005-07-21 19:54:58 +02:00
2005-09-12 13:51:18 +02:00
if contact == gajim . get_contact_instance_with_highest_priority ( \
account , contact . jid ) :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . draw_name_banner ( contact )
2005-06-12 17:14:07 +02:00
def on_info ( self , widget , user , account ) :
''' Call vcard_information_window class to display user ' s information '''
2005-10-20 13:17:17 +02:00
info = gajim . interface . windows [ account ] [ ' infos ' ]
2005-06-12 17:14:07 +02:00
if info . has_key ( user . jid ) :
info [ user . jid ] . window . present ( )
else :
2005-10-20 13:17:17 +02:00
info [ user . jid ] = dialogs . VcardWindow ( user , account )
2005-06-12 17:14:07 +02:00
2005-07-15 20:13:54 +02:00
def show_tooltip ( self , contact ) :
2005-07-09 00:26:46 +02:00
pointer = self . tree . get_pointer ( )
props = self . tree . get_path_at_pos ( pointer [ 0 ] , pointer [ 1 ] )
2005-07-31 21:21:11 +02:00
if props and self . tooltip . id == props [ 0 ] :
2005-07-09 00:26:46 +02:00
# check if the current pointer is at the same path
# as it was before setting the timeout
2005-10-08 18:47:35 +02:00
rect = self . tree . get_cell_area ( props [ 0 ] , props [ 1 ] )
2005-07-31 21:21:11 +02:00
position = self . tree . window . get_origin ( )
pointer = self . window . get_pointer ( )
2005-10-08 18:47:35 +02:00
self . tooltip . show_tooltip ( contact , ( pointer [ 0 ] , rect . height ) ,
2005-07-31 21:21:11 +02:00
( position [ 0 ] , position [ 1 ] + rect . y ) )
2005-07-09 00:26:46 +02:00
else :
self . tooltip . hide_tooltip ( )
2005-07-07 23:27:53 +02:00
2005-07-08 01:37:04 +02:00
def on_roster_treeview_leave_notify_event ( self , widget , event ) :
2005-07-07 23:27:53 +02:00
model = widget . get_model ( )
2005-07-08 01:37:04 +02:00
props = widget . get_path_at_pos ( int ( event . x ) , int ( event . y ) )
2005-07-07 23:27:53 +02:00
if self . tooltip . timeout > 0 :
2005-07-31 21:21:11 +02:00
if not props or self . tooltip . id == props [ 0 ] :
2005-07-07 23:27:53 +02:00
self . tooltip . hide_tooltip ( )
2005-07-08 01:37:04 +02:00
def on_roster_treeview_motion_notify_event ( self , widget , event ) :
2005-07-07 23:27:53 +02:00
model = widget . get_model ( )
2005-07-08 01:37:04 +02:00
props = widget . get_path_at_pos ( int ( event . x ) , int ( event . y ) )
2005-07-07 23:27:53 +02:00
if self . tooltip . timeout > 0 :
2005-07-31 21:21:11 +02:00
if not props or self . tooltip . id != props [ 0 ] :
2005-07-07 23:27:53 +02:00
self . tooltip . hide_tooltip ( )
if props :
[ row , col , x , y ] = props
2005-08-03 16:14:11 +02:00
iter = None
try :
iter = model . get_iter ( row )
except :
self . tooltip . hide_tooltip ( )
return
2005-09-09 00:07:49 +02:00
if model [ iter ] [ C_TYPE ] == ' contact ' :
2005-09-15 01:11:13 +02:00
# we're on a contact entry in the roster
2005-09-09 00:07:49 +02:00
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
2005-07-31 21:21:11 +02:00
if self . tooltip . timeout == 0 or self . tooltip . id != props [ 0 ] :
self . tooltip . id = row
2005-07-07 23:27:53 +02:00
self . tooltip . timeout = gobject . timeout_add ( 500 ,
2005-07-18 23:08:31 +02:00
self . show_tooltip , gajim . contacts [ account ] [ jid ] )
2005-09-13 23:13:40 +02:00
elif model [ iter ] [ C_TYPE ] == ' account ' :
2005-09-15 01:11:13 +02:00
# we're on an account entry in the roster
2005-09-13 20:46:21 +02:00
account = model [ iter ] [ C_NAME ] . decode ( ' utf-8 ' )
jid = gajim . get_jid_from_account ( account )
2005-09-13 23:13:40 +02:00
contacts = [ ]
2005-09-15 01:11:13 +02:00
connection = gajim . connections [ account ]
# get our current contact info
contact = Contact ( jid = jid , name = account ,
show = connection . get_status ( ) ,
status = connection . status ,
resource = gajim . config . get_per ( ' accounts ' , connection . name , ' resource ' ) ,
2005-10-01 05:54:44 +02:00
priority = gajim . config . get_per ( ' accounts ' , connection . name , ' priority ' ) ,
2005-09-15 01:11:13 +02:00
keyID = gajim . config . get_per ( ' accounts ' , connection . name , ' keyid ' ) )
2005-09-14 19:17:19 +02:00
contacts . append ( contact )
2005-09-15 01:11:13 +02:00
# if we're online ...
if connection . connection :
roster = connection . connection . getRoster ( )
if roster . getItem ( jid ) :
resources = roster . getResources ( jid )
# ...get the contact info for our other online resources
2005-09-14 19:17:19 +02:00
for resource in resources :
2005-09-22 17:53:27 +02:00
show = roster . getShow ( jid + ' / ' + resource )
if not show :
show = ' online '
2005-09-15 01:11:13 +02:00
contact = Contact ( jid = jid , name = account ,
2005-09-22 21:18:53 +02:00
show = show ,
2005-09-15 01:11:13 +02:00
status = roster . getStatus ( jid + ' / ' + resource ) , resource = resource ,
priority = roster . getPriority ( jid + ' / ' + resource ) )
2005-09-14 19:17:19 +02:00
contacts . append ( contact )
2005-09-13 20:46:21 +02:00
if self . tooltip . timeout == 0 or self . tooltip . id != props [ 0 ] :
self . tooltip . id = row
self . tooltip . timeout = gobject . timeout_add ( 500 ,
self . show_tooltip , contacts )
2005-07-07 23:27:53 +02:00
2005-06-12 17:14:07 +02:00
def on_agent_logging ( self , widget , jid , state , account ) :
''' When an agent is requested to log in or off '''
gajim . connections [ account ] . send_agent_status ( jid , state )
2005-07-06 16:34:59 +02:00
def on_edit_agent ( self , widget , contact , account ) :
2005-06-12 17:14:07 +02:00
''' When we want to modify the agent registration '''
2005-07-06 16:34:59 +02:00
gajim . connections [ account ] . request_register_agent_info ( contact . jid )
2005-06-12 17:14:07 +02:00
2005-07-06 16:34:59 +02:00
def on_remove_agent ( self , widget , contact , account ) :
2005-06-12 17:14:07 +02:00
''' When an agent is requested to log in or off '''
2005-08-01 21:37:18 +02:00
if gajim . config . get_per ( ' accounts ' , account , ' hostname ' ) == contact . jid :
# We remove the server contact
# remove it from treeview
self . remove_contact ( contact , account )
del gajim . contacts [ account ] [ contact . jid ]
return
2005-10-07 15:00:44 +02:00
window = dialogs . ConfirmationDialog ( _ ( ' Transport " %s " will be removed ' ) % contact . jid , _ ( ' You will no longer be able to send and receive messages to contacts from this transport. ' ) )
2005-06-12 17:14:07 +02:00
if window . get_response ( ) == gtk . RESPONSE_OK :
2005-07-06 16:34:59 +02:00
gajim . connections [ account ] . unsubscribe_agent ( contact . jid + ' / ' \
+ contact . resource )
2005-06-12 17:14:07 +02:00
# remove transport from treeview
2005-07-21 19:54:58 +02:00
self . remove_contact ( contact , account )
2005-06-12 17:14:07 +02:00
# remove transport's contacts from treeview
2005-07-18 23:08:31 +02:00
for jid , contacts in gajim . contacts [ account ] . items ( ) :
2005-06-12 17:14:07 +02:00
contact = contacts [ 0 ]
2005-07-06 16:34:59 +02:00
if jid . endswith ( ' @ ' + contact . jid ) :
gajim . log . debug (
' Removing contact %s due to unregistered transport %s ' \
% ( contact . jid , contact . name ) )
2005-07-21 19:54:58 +02:00
self . remove_contact ( contact , account )
2005-07-18 23:08:31 +02:00
del gajim . contacts [ account ] [ contact . jid ]
2005-06-12 17:14:07 +02:00
def on_rename ( self , widget , iter , path ) :
model = self . tree . get_model ( )
2005-07-19 16:53:35 +02:00
2005-09-09 00:07:49 +02:00
row_type = model [ iter ] [ C_TYPE ]
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
2005-07-21 15:16:31 +02:00
if row_type == ' contact ' :
# it's jid
2005-07-21 15:28:07 +02:00
#Remove resource indicator (Name (2))
contacts = gajim . contacts [ account ] [ jid ]
2005-07-21 15:16:31 +02:00
name = contacts [ 0 ] . name
2005-09-09 00:07:49 +02:00
model [ iter ] [ C_NAME ] = name
2005-07-21 15:16:31 +02:00
2005-09-09 00:07:49 +02:00
model [ iter ] [ C_EDITABLE ] = True # set 'editable' to True
2005-06-12 17:14:07 +02:00
self . tree . set_cursor ( path , self . tree . get_column ( 0 ) , True )
def on_assign_pgp_key ( self , widget , user , account ) :
attached_keys = gajim . config . get_per ( ' accounts ' , account ,
' attached_gpg_keys ' ) . split ( )
keys = { }
keyID = ' None '
2005-10-27 14:47:54 +02:00
for i in xrange ( 0 , len ( attached_keys ) / 2 ) :
2005-06-12 17:14:07 +02:00
keys [ attached_keys [ 2 * i ] ] = attached_keys [ 2 * i + 1 ]
if attached_keys [ 2 * i ] == user . jid :
keyID = attached_keys [ 2 * i + 1 ]
public_keys = gajim . connections [ account ] . ask_gpg_keys ( )
public_keys [ ' None ' ] = ' None '
2005-07-23 00:49:03 +02:00
instance = dialogs . ChooseGPGKeyDialog ( _ ( ' Assign OpenPGP Key ' ) ,
_ ( ' Select a key to apply to the contact ' ) , public_keys , keyID )
2005-08-02 18:27:25 +02:00
keyID = instance . run ( )
2005-07-23 00:49:03 +02:00
if keyID is None :
2005-06-12 17:14:07 +02:00
return
2005-07-06 16:26:10 +02:00
if keyID [ 0 ] == ' None ' :
2005-07-06 16:07:20 +02:00
if user . jid in keys :
del keys [ user . jid ]
2005-06-12 17:14:07 +02:00
else :
keys [ user . jid ] = keyID [ 0 ]
2005-07-18 23:08:31 +02:00
for u in gajim . contacts [ account ] [ user . jid ] :
2005-06-12 17:14:07 +02:00
u . keyID = keyID [ 0 ]
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ account ] [ ' chats ' ] . has_key ( user . jid ) :
gajim . interface . windows [ account ] [ ' chats ' ] [ user . jid ] . draw_widgets ( user )
2005-06-12 17:14:07 +02:00
keys_str = ' '
for jid in keys :
2005-07-02 10:50:11 +02:00
keys_str + = jid + ' ' + keys [ jid ] + ' '
2005-06-12 17:14:07 +02:00
gajim . config . set_per ( ' accounts ' , account , ' attached_gpg_keys ' , keys_str )
def on_edit_groups ( self , widget , user , account ) :
2005-10-20 13:17:17 +02:00
dlg = dialogs . EditGroupsDialog ( user , account )
2005-06-12 17:14:07 +02:00
dlg . run ( )
2005-08-04 16:30:41 +02:00
def on_history ( self , widget , contact , account ) :
2005-06-12 17:14:07 +02:00
''' When history menuitem is activated: call log window '''
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ ' logs ' ] . has_key ( contact . jid ) :
gajim . interface . windows [ ' logs ' ] [ contact . jid ] . window . present ( )
2005-06-12 17:14:07 +02:00
else :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ ' logs ' ] [ contact . jid ] = history_window . \
HistoryWindow ( contact . jid , account )
2005-07-01 17:15:35 +02:00
2005-08-06 21:14:21 +02:00
def on_send_single_message_menuitem_activate ( self , wiget , account ,
contact = None ) :
if contact is None :
2005-10-21 20:13:33 +02:00
dialogs . SingleMessageWindow ( account , action = ' send ' )
2005-08-06 21:14:21 +02:00
else :
2005-10-21 20:13:33 +02:00
dialogs . SingleMessageWindow ( account , contact . jid , ' send ' )
2005-08-03 16:14:11 +02:00
def on_send_file_menuitem_activate ( self , widget , account , contact ) :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ ' file_transfers ' ] . show_file_send_request (
2005-08-03 16:14:11 +02:00
account , contact )
2005-06-12 17:14:07 +02:00
def mk_menu_user ( self , event , iter ) :
2005-07-06 16:34:59 +02:00
''' Make contact ' s popup menu '''
2005-06-12 17:14:07 +02:00
model = self . tree . get_model ( )
2005-09-09 00:07:49 +02:00
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
2005-06-12 17:14:07 +02:00
path = model . get_path ( iter )
2005-09-09 00:07:49 +02:00
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
2005-08-29 13:36:57 +02:00
contact = gajim . get_highest_prio_contact_from_contacts (
gajim . contacts [ account ] [ jid ] )
2005-06-12 17:14:07 +02:00
2005-07-01 17:15:35 +02:00
xml = gtk . glade . XML ( GTKGUI_GLADE , ' roster_contact_context_menu ' ,
APP )
roster_contact_context_menu = xml . get_widget (
' roster_contact_context_menu ' )
childs = roster_contact_context_menu . get_children ( )
start_chat_menuitem = childs [ 0 ]
send_single_message_menuitem = childs [ 1 ]
rename_menuitem = childs [ 2 ]
2005-07-06 18:46:50 +02:00
edit_groups_menuitem = childs [ 3 ]
2005-07-21 11:45:55 +02:00
# separator4 goes with assign_openpgp_key_menuitem
assign_openpgp_separator = childs [ 4 ]
2005-08-03 16:14:11 +02:00
send_file_menuitem = childs [ 5 ]
assign_openpgp_key_menuitem = childs [ 6 ]
2005-07-01 17:15:35 +02:00
#skip a seperator
subscription_to_menuitem , subscription_from_menuitem = \
2005-08-03 16:14:11 +02:00
childs [ 8 ] . get_submenu ( ) . get_children ( )
add_to_roster_menuitem = childs [ 9 ]
remove_from_roster_menuitem = childs [ 10 ]
2005-07-01 17:15:35 +02:00
#skip a seperator
2005-08-03 16:14:11 +02:00
information_menuitem = childs [ 12 ]
history_menuitem = childs [ 13 ]
2005-07-01 17:15:35 +02:00
2005-10-07 16:46:10 +02:00
if contact . resource :
2005-10-07 16:21:31 +02:00
send_file_menuitem . connect ( ' activate ' ,
self . on_send_file_menuitem_activate , account , contact )
2005-10-07 16:46:10 +02:00
else : # if we do not have resource we cannot send file
send_file_menuitem . hide ( )
send_file_menuitem . set_no_show_all ( True )
2005-07-01 17:15:35 +02:00
start_chat_menuitem . connect ( ' activate ' ,
self . on_roster_treeview_row_activated , path )
send_single_message_menuitem . connect ( ' activate ' ,
self . on_send_single_message_menuitem_activate , account , contact )
rename_menuitem . connect ( ' activate ' , self . on_rename , iter , path )
remove_from_roster_menuitem . connect ( ' activate ' , self . on_req_usub ,
contact , account )
information_menuitem . connect ( ' activate ' , self . on_info , contact ,
account )
history_menuitem . connect ( ' activate ' , self . on_history , contact ,
account )
2005-07-07 19:33:15 +02:00
if _ ( ' not in the roster ' ) not in contact . groups :
2005-07-01 17:15:35 +02:00
#contact is in normal group
edit_groups_menuitem . set_no_show_all ( False )
assign_openpgp_key_menuitem . set_no_show_all ( False )
add_to_roster_menuitem . hide ( )
add_to_roster_menuitem . set_no_show_all ( True )
edit_groups_menuitem . connect ( ' activate ' , self . on_edit_groups , contact ,
account )
2005-06-20 21:18:53 +02:00
2005-06-12 17:14:07 +02:00
if gajim . config . get ( ' usegpg ' ) :
2005-07-01 17:15:35 +02:00
assign_openpgp_key_menuitem . connect ( ' activate ' ,
self . on_assign_pgp_key , contact , account )
2005-06-20 21:18:53 +02:00
2005-07-01 17:15:35 +02:00
subscription_to_menuitem . connect ( ' activate ' , self . authorize , jid ,
account )
subscription_from_menuitem . connect ( ' activate ' , self . req_sub ,
jid , _ ( ' I would like to add you to my roster ' ) , account )
2005-06-15 01:32:04 +02:00
2005-07-01 17:15:35 +02:00
else : # contact is in group 'not in the roster'
add_to_roster_menuitem . set_no_show_all ( False )
edit_groups_menuitem . hide ( )
edit_groups_menuitem . set_no_show_all ( True )
2005-07-21 11:45:55 +02:00
# hide first of the two consecutive separators
assign_openpgp_separator . hide ( )
assign_openpgp_separator . set_no_show_all ( True )
2005-07-01 17:15:35 +02:00
assign_openpgp_key_menuitem . hide ( )
assign_openpgp_key_menuitem . set_no_show_all ( True )
2005-06-15 01:32:04 +02:00
2005-07-01 17:15:35 +02:00
add_to_roster_menuitem . connect ( ' activate ' ,
self . on_add_to_roster , contact , account )
2005-06-12 17:14:07 +02:00
2005-07-17 22:29:44 +02:00
event_button = self . get_possible_button_event ( event )
roster_contact_context_menu . popup ( None , None , None , event_button ,
2005-07-01 17:15:35 +02:00
event . time )
roster_contact_context_menu . show_all ( )
2005-06-12 17:14:07 +02:00
def mk_menu_g ( self , event , iter ) :
''' Make group ' s popup menu '''
model = self . tree . get_model ( )
path = model . get_path ( iter )
2005-07-17 22:29:44 +02:00
2005-06-12 17:14:07 +02:00
menu = gtk . Menu ( )
2005-06-20 21:18:53 +02:00
2005-07-06 16:34:59 +02:00
rename_item = gtk . ImageMenuItem ( _ ( ' Rename ' ) )
rename_icon = gtk . image_new_from_stock ( gtk . STOCK_REFRESH ,
gtk . ICON_SIZE_MENU )
rename_item . set_image ( rename_icon )
2005-06-20 21:18:53 +02:00
menu . append ( rename_item )
rename_item . connect ( ' activate ' , self . on_rename , iter , path )
2005-07-17 22:29:44 +02:00
event_button = self . get_possible_button_event ( event )
menu . popup ( None , None , None , event_button , event . time )
2005-06-12 17:14:07 +02:00
menu . show_all ( )
def mk_menu_agent ( self , event , iter ) :
''' Make agent ' s popup menu '''
model = self . tree . get_model ( )
2005-09-09 00:07:49 +02:00
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
2005-06-12 17:14:07 +02:00
path = model . get_path ( iter )
2005-09-09 00:07:49 +02:00
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
2005-07-18 23:08:31 +02:00
user = gajim . contacts [ account ] [ jid ] [ 0 ]
2005-06-12 17:14:07 +02:00
menu = gtk . Menu ( )
2005-06-20 21:18:53 +02:00
2005-07-04 23:29:22 +02:00
item = gtk . ImageMenuItem ( _ ( ' _Log on ' ) )
2005-07-08 00:22:13 +02:00
icon = gtk . image_new_from_stock ( gtk . STOCK_YES , gtk . ICON_SIZE_MENU )
item . set_image ( icon )
2005-06-20 21:18:53 +02:00
menu . append ( item )
2005-07-18 23:08:31 +02:00
show = gajim . contacts [ account ] [ jid ] [ 0 ] . show
2005-06-12 17:14:07 +02:00
if show != ' offline ' and show != ' error ' :
item . set_sensitive ( False )
item . connect ( ' activate ' , self . on_agent_logging , jid , None , account )
2005-07-04 23:29:22 +02:00
item = gtk . ImageMenuItem ( _ ( ' Log _off ' ) )
2005-07-06 16:34:59 +02:00
icon = gtk . image_new_from_stock ( gtk . STOCK_NO , gtk . ICON_SIZE_MENU )
2005-07-04 23:29:22 +02:00
item . set_image ( icon )
2005-06-20 21:18:53 +02:00
menu . append ( item )
2005-07-23 17:23:45 +02:00
if show in ( ' offline ' , ' error ' ) :
2005-06-12 17:14:07 +02:00
item . set_sensitive ( False )
item . connect ( ' activate ' , self . on_agent_logging , jid , ' unavailable ' ,
account )
2005-08-07 17:22:51 +02:00
item = gtk . SeparatorMenuItem ( ) # seperator
2005-06-12 17:14:07 +02:00
menu . append ( item )
2005-11-04 16:08:49 +01:00
item = gtk . ImageMenuItem ( _ ( ' _Edit ' ) )
2005-07-06 16:34:59 +02:00
icon = gtk . image_new_from_stock ( gtk . STOCK_PREFERENCES , gtk . ICON_SIZE_MENU )
2005-07-04 23:29:22 +02:00
item . set_image ( icon )
2005-06-12 17:14:07 +02:00
menu . append ( item )
item . connect ( ' activate ' , self . on_edit_agent , user , account )
2005-07-04 23:29:22 +02:00
item = gtk . ImageMenuItem ( _ ( ' _Remove from Roster ' ) )
2005-07-06 16:34:59 +02:00
icon = gtk . image_new_from_stock ( gtk . STOCK_REMOVE , gtk . ICON_SIZE_MENU )
2005-07-04 23:29:22 +02:00
item . set_image ( icon )
2005-06-12 17:14:07 +02:00
menu . append ( item )
item . connect ( ' activate ' , self . on_remove_agent , user , account )
2005-07-17 22:29:44 +02:00
event_button = self . get_possible_button_event ( event )
menu . popup ( None , None , None , event_button , event . time )
2005-06-12 17:14:07 +02:00
menu . show_all ( )
2005-07-04 23:29:22 +02:00
2005-06-12 17:14:07 +02:00
def on_edit_account ( self , widget , account ) :
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ account ] . has_key ( ' account_modification ' ) :
gajim . interface . windows [ account ] [ ' account_modification ' ] . window . present ( )
2005-06-12 17:14:07 +02:00
else :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' account_modification ' ] = \
config . AccountModificationWindow ( account )
2005-07-17 22:29:44 +02:00
def get_possible_button_event ( self , event ) :
2005-07-17 22:32:49 +02:00
''' mouse or keyboard caused the event? '''
2005-07-17 22:29:44 +02:00
if event . type == gtk . gdk . KEY_PRESS :
event_button = 0 # no event.button so pass 0
else : # BUTTON_PRESS event, so pass event.button
event_button = event . button
return event_button
2005-10-09 16:49:14 +02:00
2005-10-09 23:08:13 +02:00
def on_change_status_message_activate ( self , widget , account ) :
2005-10-09 16:49:14 +02:00
show = gajim . SHOW_LIST [ gajim . connections [ account ] . connected ]
2005-10-20 13:17:17 +02:00
dlg = dialogs . ChangeStatusMessageDialog ( show )
2005-10-09 16:49:14 +02:00
message = dlg . run ( )
2005-10-10 23:45:59 +02:00
if message is not None : # None is if user pressed Cancel
2005-10-10 00:24:18 +02:00
self . send_status ( account , show , message )
2005-06-12 17:14:07 +02:00
def mk_menu_account ( self , event , iter ) :
''' Make account ' s popup menu '''
model = self . tree . get_model ( )
2005-09-13 00:46:41 +02:00
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
2005-07-04 18:59:43 +02:00
2005-08-24 14:47:09 +02:00
#FIXME: make most menuitems of this menu insensitive if account is offline
2005-06-20 21:18:53 +02:00
# we have to create our own set of icons for the menu
# using self.jabber_status_images is poopoo
iconset = gajim . config . get ( ' iconset ' )
if not iconset :
iconset = ' sun '
path = os . path . join ( gajim . DATA_DIR , ' iconsets/ ' + iconset + ' /16x16/ ' )
state_images = self . load_iconset ( path )
2005-07-04 18:59:43 +02:00
xml = gtk . glade . XML ( GTKGUI_GLADE , ' account_context_menu ' , APP )
account_context_menu = xml . get_widget ( ' account_context_menu ' )
childs = account_context_menu . get_children ( )
2005-06-20 21:18:53 +02:00
2005-07-04 18:59:43 +02:00
status_menuitem = childs [ 0 ]
2005-10-09 18:13:55 +02:00
# we skip the seperator
2005-07-04 18:59:43 +02:00
advanced_actions_menuitem = childs [ 2 ]
2005-08-06 14:33:20 +02:00
xml_console_menuitem = xml . get_widget ( ' xml_console_menuitem ' )
set_motd_menuitem = xml . get_widget ( ' set_motd_menuitem ' )
update_motd_menuitem = xml . get_widget ( ' update_motd_menuitem ' )
delete_motd_menuitem = xml . get_widget ( ' delete_motd_menuitem ' )
2005-07-04 18:59:43 +02:00
edit_account_menuitem = childs [ 3 ]
service_discovery_menuitem = childs [ 4 ]
add_contact_menuitem = childs [ 5 ]
join_group_chat_menuitem = childs [ 6 ]
new_message_menuitem = childs [ 7 ]
2005-06-12 17:14:07 +02:00
sub_menu = gtk . Menu ( )
2005-07-04 18:59:43 +02:00
status_menuitem . set_submenu ( sub_menu )
2005-06-20 21:18:53 +02:00
2005-10-27 15:15:03 +02:00
for show in ( ' online ' , ' chat ' , ' away ' , ' xa ' , ' dnd ' , ' invisible ' ) :
2005-10-09 18:08:18 +02:00
uf_show = helpers . get_uf_show ( show , use_mnemonic = True )
item = gtk . ImageMenuItem ( uf_show )
2005-06-20 21:18:53 +02:00
icon = state_images [ show ]
2005-07-04 18:59:43 +02:00
item . set_image ( icon )
2005-06-20 21:18:53 +02:00
sub_menu . append ( item )
item . connect ( ' activate ' , self . change_status , account , show )
2005-07-17 22:29:44 +02:00
2005-10-09 16:49:14 +02:00
item = gtk . SeparatorMenuItem ( )
sub_menu . append ( item )
2005-10-09 20:52:57 +02:00
item = gtk . ImageMenuItem ( _ ( ' _Change Status Message ' ) )
2005-10-09 20:45:03 +02:00
path = os . path . join ( gajim . DATA_DIR , ' pixmaps ' , ' rename.png ' )
img = gtk . Image ( )
img . set_from_file ( path )
item . set_image ( img )
2005-10-09 16:49:14 +02:00
sub_menu . append ( item )
2005-10-09 23:08:13 +02:00
item . connect ( ' activate ' , self . on_change_status_message_activate , account )
2005-10-09 16:49:14 +02:00
if gajim . connections [ account ] . connected < 2 :
item . set_sensitive ( False )
item = gtk . SeparatorMenuItem ( )
sub_menu . append ( item )
2005-10-09 18:08:18 +02:00
uf_show = helpers . get_uf_show ( ' offline ' , use_mnemonic = True )
item = gtk . ImageMenuItem ( uf_show )
2005-10-09 16:49:14 +02:00
icon = state_images [ ' offline ' ]
item . set_image ( icon )
sub_menu . append ( item )
item . connect ( ' activate ' , self . change_status , account , ' offline ' )
2005-08-06 21:14:21 +02:00
xml_console_menuitem . connect ( ' activate ' , self . on_xml_console_menuitem_activate ,
account )
set_motd_menuitem . connect ( ' activate ' , self . on_set_motd_menuitem_activate , account )
update_motd_menuitem . connect ( ' activate ' , self . on_update_motd_menuitem_activate , account )
delete_motd_menuitem . connect ( ' activate ' , self . on_delete_motd_menuitem_activate , account )
2005-07-04 18:59:43 +02:00
edit_account_menuitem . connect ( ' activate ' , self . on_edit_account , account )
service_discovery_menuitem . connect ( ' activate ' ,
self . on_service_disco_menuitem_activate , account )
add_contact_menuitem . connect ( ' activate ' , self . on_add_new_contact , account )
join_group_chat_menuitem . connect ( ' activate ' ,
self . on_join_gc_activate , account )
new_message_menuitem . connect ( ' activate ' ,
self . on_new_message_menuitem_activate , account )
2005-06-20 21:18:53 +02:00
2005-07-17 22:29:44 +02:00
event_button = self . get_possible_button_event ( event )
account_context_menu . popup ( None , self . tree , None , event_button ,
event . time )
2005-07-04 18:59:43 +02:00
account_context_menu . show_all ( )
2005-06-12 17:14:07 +02:00
def on_add_to_roster ( self , widget , user , account ) :
2005-10-20 13:17:17 +02:00
dialogs . AddNewContactWindow ( account , user . jid )
2005-06-12 17:14:07 +02:00
def authorize ( self , widget , jid , account ) :
2005-06-15 01:32:04 +02:00
''' Authorize a user (by re-sending auth menuitem) '''
2005-06-12 17:14:07 +02:00
gajim . connections [ account ] . send_authorization ( jid )
2005-06-15 01:32:04 +02:00
dialogs . InformationDialog ( _ ( ' Authorization has been sent ' ) ,
2005-08-14 18:12:36 +02:00
_ ( ' Now " %s " will know your status. ' ) % jid )
2005-06-12 17:14:07 +02:00
2005-06-15 09:38:58 +02:00
def req_sub ( self , widget , jid , txt , account , group = None , pseudo = None ) :
2005-06-12 17:14:07 +02:00
''' Request subscription to a user '''
if not pseudo :
pseudo = jid
gajim . connections [ account ] . request_subscription ( jid , txt )
if not group :
2005-07-05 01:18:29 +02:00
group = _ ( ' General ' )
2005-07-18 23:08:31 +02:00
if not gajim . contacts [ account ] . has_key ( jid ) :
2005-06-12 17:14:07 +02:00
keyID = ' '
attached_keys = gajim . config . get_per ( ' accounts ' , account ,
' attached_gpg_keys ' ) . split ( )
if jid in attached_keys :
keyID = attached_keys [ attached_keys . index ( jid ) + 1 ]
2005-06-25 11:18:39 +02:00
user1 = Contact ( jid = jid , name = pseudo , groups = [ group ] ,
2005-08-04 21:47:58 +02:00
show = ' requested ' , status = ' ' , ask = ' none ' ,
2005-06-25 23:18:07 +02:00
sub = ' subscribe ' , keyID = keyID )
2005-07-18 23:08:31 +02:00
gajim . contacts [ account ] [ jid ] = [ user1 ]
2005-06-12 17:14:07 +02:00
else :
2005-07-18 23:08:31 +02:00
user1 = gajim . contacts [ account ] [ jid ] [ 0 ]
2005-07-07 19:33:15 +02:00
if not _ ( ' not in the roster ' ) in user1 . groups :
2005-06-15 09:38:58 +02:00
dialogs . InformationDialog ( _ ( ' Subscription request has been sent ' ) ,
2005-08-14 18:12:36 +02:00
_ ( ' If " %s " accepts this request you will know his status. ' ) % jid )
2005-06-12 17:14:07 +02:00
return
user1 . groups = [ group ]
user1 . name = pseudo
2005-07-21 19:54:58 +02:00
self . remove_contact ( user1 , account )
2005-07-07 18:38:36 +02:00
self . add_contact_to_roster ( jid , account )
2005-06-12 17:14:07 +02:00
2005-07-09 00:26:46 +02:00
def on_roster_treeview_scroll_event ( self , widget , event ) :
self . tooltip . hide_tooltip ( )
2005-06-12 17:14:07 +02:00
def on_roster_treeview_key_press_event ( self , widget , event ) :
''' when a key is pressed in the treeviews '''
2005-07-09 00:26:46 +02:00
self . tooltip . hide_tooltip ( )
2005-07-17 22:29:44 +02:00
if event . keyval == gtk . keysyms . Menu :
2005-07-17 22:32:49 +02:00
self . show_treeview_menu ( event )
2005-08-07 22:27:34 +02:00
return True
2005-06-12 17:14:07 +02:00
if event . keyval == gtk . keysyms . Escape :
self . tree . get_selection ( ) . unselect_all ( )
if event . keyval == gtk . keysyms . F2 :
treeselection = self . tree . get_selection ( )
model , iter = treeselection . get_selected ( )
if not iter :
return
2005-09-09 00:07:49 +02:00
type = model [ iter ] [ C_TYPE ]
2005-07-23 17:23:45 +02:00
if type in ( ' contact ' , ' group ' ) :
2005-06-12 17:14:07 +02:00
path = model . get_path ( iter )
2005-07-19 16:53:35 +02:00
self . on_rename ( widget , iter , path )
2005-06-12 17:14:07 +02:00
if event . keyval == gtk . keysyms . Delete :
treeselection = self . tree . get_selection ( )
model , iter = treeselection . get_selected ( )
if not iter :
return
2005-09-09 00:07:49 +02:00
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
type = model [ iter ] [ C_TYPE ]
2005-08-27 15:26:24 +02:00
if type in ( ' account ' , ' group ' ) :
2005-08-27 14:48:02 +02:00
return
2005-07-18 23:08:31 +02:00
user = gajim . contacts [ account ] [ jid ] [ 0 ]
2005-07-07 18:38:36 +02:00
if type == ' contact ' :
2005-06-12 17:14:07 +02:00
self . on_req_usub ( widget , user , account )
elif type == ' agent ' :
self . on_remove_agent ( widget , user , account )
2005-07-17 22:29:44 +02:00
def show_appropriate_context_menu ( self , event , iter ) :
model = self . tree . get_model ( )
2005-09-09 00:07:49 +02:00
type = model [ iter ] [ C_TYPE ]
2005-07-17 22:29:44 +02:00
if type == ' group ' :
self . mk_menu_g ( event , iter )
elif type == ' agent ' :
self . mk_menu_agent ( event , iter )
elif type == ' contact ' :
self . mk_menu_user ( event , iter )
elif type == ' account ' :
self . mk_menu_account ( event , iter )
2005-07-17 22:32:49 +02:00
def show_treeview_menu ( self , event ) :
2005-07-17 22:29:44 +02:00
try :
store , iter = self . tree . get_selection ( ) . get_selected ( )
except TypeError :
self . tree . get_selection ( ) . unselect_all ( )
return
model = self . tree . get_model ( )
path = model . get_path ( iter )
self . tree . get_selection ( ) . select_path ( path )
self . show_appropriate_context_menu ( event , iter )
return True
2005-06-12 17:14:07 +02:00
def on_roster_treeview_button_press_event ( self , widget , event ) :
2005-07-09 01:43:11 +02:00
# hide tooltip, no matter the button is pressed
2005-07-09 00:26:46 +02:00
self . tooltip . hide_tooltip ( )
2005-06-13 00:19:56 +02:00
if event . button == 3 : # Right click
try :
path , column , x , y = self . tree . get_path_at_pos ( int ( event . x ) ,
int ( event . y ) )
except TypeError :
self . tree . get_selection ( ) . unselect_all ( )
return
self . tree . get_selection ( ) . select_path ( path )
model = self . tree . get_model ( )
iter = model . get_iter ( path )
2005-07-17 22:29:44 +02:00
self . show_appropriate_context_menu ( event , iter )
2005-06-13 00:19:56 +02:00
return True
2005-07-22 21:26:17 +02:00
2005-06-23 10:33:25 +02:00
if event . button == 2 : # Middle click
try :
path , column , x , y = self . tree . get_path_at_pos ( int ( event . x ) ,
int ( event . y ) )
except TypeError :
self . tree . get_selection ( ) . unselect_all ( )
return
self . tree . get_selection ( ) . select_path ( path )
model = self . tree . get_model ( )
iter = model . get_iter ( path )
2005-09-09 00:07:49 +02:00
type = model [ iter ] [ C_TYPE ]
2005-07-23 17:23:45 +02:00
if type in ( ' agent ' , ' contact ' ) :
2005-09-09 00:07:49 +02:00
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ account ] [ ' chats ' ] . has_key ( jid ) :
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . set_active_tab ( jid )
2005-07-18 23:08:31 +02:00
elif gajim . contacts [ account ] . has_key ( jid ) :
2005-08-06 12:20:04 +02:00
c = gajim . get_contact_instance_with_highest_priority ( account , jid )
self . new_chat ( c , account )
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . set_active_tab ( jid )
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . window . present ( )
2005-10-09 23:08:13 +02:00
elif type == ' account ' :
account = model [ iter ] [ C_ACCOUNT ]
show = gajim . connections [ account ] . connected
if show > 1 : # We are connected
self . on_change_status_message_activate ( widget , account )
2005-06-23 10:33:25 +02:00
return True
2005-07-22 21:26:17 +02:00
2005-06-13 00:19:56 +02:00
if event . button == 1 : # Left click
try :
path , column , x , y = self . tree . get_path_at_pos ( int ( event . x ) ,
int ( event . y ) )
except TypeError :
self . tree . get_selection ( ) . unselect_all ( )
return False
model = self . tree . get_model ( )
iter = model . get_iter ( path )
2005-09-09 00:07:49 +02:00
type = model [ iter ] [ C_TYPE ]
2005-06-13 00:19:56 +02:00
if type == ' group ' :
if x < 20 : # first cell in 1st column (the arrow SINGLE clicked)
if ( self . tree . row_expanded ( path ) ) :
self . tree . collapse_row ( path )
else :
self . tree . expand_row ( path , False )
2005-06-12 17:14:07 +02:00
def on_req_usub ( self , widget , user , account ) :
2005-09-30 22:27:57 +02:00
''' Remove a contact '''
window = dialogs . ConfirmationDialogCheck (
2005-06-12 17:14:07 +02:00
_ ( ' Contact " %s " will be removed from your roster ' ) % ( user . name ) ,
2005-09-30 22:27:57 +02:00
_ ( ' By removing this contact you also by default remove authorization resulting in him/her always seeing you as offline. ' ) ,
_ ( ' I want this contact to know my status after removal ' ) )
# FIXME:
# maybe use 2 optionboxes from which the user can select? (better)
2005-06-12 17:14:07 +02:00
if window . get_response ( ) == gtk . RESPONSE_OK :
2005-09-28 16:35:06 +02:00
remove_auth = True
if window . is_checked ( ) :
remove_auth = False
gajim . connections [ account ] . unsubscribe ( user . jid , remove_auth )
2005-07-18 23:08:31 +02:00
for u in gajim . contacts [ account ] [ user . jid ] :
2005-07-21 19:54:58 +02:00
self . remove_contact ( u , account )
2005-07-18 23:08:31 +02:00
del gajim . contacts [ account ] [ u . jid ]
2005-10-20 13:17:17 +02:00
if user . jid in gajim . interface . windows [ account ] [ ' chats ' ] :
2005-06-25 11:18:39 +02:00
user1 = Contact ( jid = user . jid , name = user . name ,
2005-08-03 14:19:18 +02:00
groups = [ _ ( ' not in the roster ' ) ] , show = ' not in the roster ' ,
2005-08-04 21:44:09 +02:00
status = ' ' , ask = ' none ' , keyID = user . keyID )
2005-07-18 23:08:31 +02:00
gajim . contacts [ account ] [ user . jid ] = [ user1 ]
2005-07-07 18:38:36 +02:00
self . add_contact_to_roster ( user . jid , account )
2005-06-12 17:14:07 +02:00
def forget_gpg_passphrase ( self , keyid ) :
if self . gpg_passphrase . has_key ( keyid ) :
del self . gpg_passphrase [ keyid ]
return False
2005-09-05 15:28:09 +02:00
def set_connecting_state ( self , account ) :
model = self . tree . get_model ( )
accountIter = self . get_account_iter ( account )
if accountIter :
model [ accountIter ] [ 0 ] = self . jabber_state_images [ ' connecting ' ]
2005-10-20 13:17:17 +02:00
if gajim . interface . systray_enabled :
gajim . interface . systray . change_status ( ' connecting ' )
2005-09-05 15:28:09 +02:00
2005-08-30 23:10:14 +02:00
def send_status ( self , account , status , txt , sync = False , auto = False ) :
2005-09-12 13:51:29 +02:00
model = self . tree . get_model ( )
2005-09-05 20:12:47 +02:00
accountIter = self . get_account_iter ( account )
2005-06-12 17:14:07 +02:00
if status != ' offline ' :
if gajim . connections [ account ] . connected < 2 :
2005-09-05 15:28:09 +02:00
self . set_connecting_state ( account )
2005-06-12 17:14:07 +02:00
save_pass = gajim . config . get_per ( ' accounts ' , account , ' savepass ' )
2005-11-05 12:21:41 +01:00
if gajim . connections [ account ] . connected < 2 and \
not gajim . connections [ account ] . password :
2005-06-12 17:14:07 +02:00
passphrase = ' '
w = dialogs . PassphraseDialog (
_ ( ' Password Required ' ) ,
_ ( ' Enter your password for account %s ' ) % account ,
_ ( ' Save password ' ) )
passphrase , save = w . run ( )
if passphrase == - 1 :
if accountIter :
2005-07-21 19:00:05 +02:00
model [ accountIter ] [ 0 ] = self . jabber_state_images [ ' offline ' ]
2005-10-20 13:17:17 +02:00
if gajim . interface . systray_enabled :
gajim . interface . systray . change_status ( ' offline ' )
2005-06-12 17:14:07 +02:00
self . update_status_comboxbox ( )
return
gajim . connections [ account ] . password = passphrase
if save :
gajim . config . set_per ( ' accounts ' , account , ' savepass ' , True )
gajim . config . set_per ( ' accounts ' , account , ' password ' , passphrase )
keyid = None
2005-08-30 23:10:14 +02:00
use_gpg_agent = gajim . config . get ( ' use_gpg_agent ' )
# we don't need to bother with the passphrase if we use the agent
if use_gpg_agent :
save_gpg_pass = False
else :
2005-11-06 16:08:54 +01:00
save_gpg_pass = gajim . config . get_per ( ' accounts ' , account ,
' savegpgpass ' )
2005-06-12 17:14:07 +02:00
keyid = gajim . config . get_per ( ' accounts ' , account , ' keyid ' )
if keyid and gajim . connections [ account ] . connected < 2 and \
gajim . config . get ( ' usegpg ' ) :
2005-08-30 23:10:14 +02:00
if use_gpg_agent :
self . gpg_passphrase [ keyid ] = None
2005-06-12 17:14:07 +02:00
else :
2005-08-30 23:10:14 +02:00
if save_gpg_pass :
passphrase = gajim . config . get_per ( ' accounts ' , account , ' gpgpassword ' )
2005-06-12 17:14:07 +02:00
else :
2005-08-30 23:10:14 +02:00
if self . gpg_passphrase . has_key ( keyid ) :
passphrase = self . gpg_passphrase [ keyid ]
save = False
else :
w = dialogs . PassphraseDialog (
_ ( ' Passphrase Required ' ) ,
_ ( ' Enter GPG key passphrase for account %s ' ) % account ,
_ ( ' Save passphrase ' ) )
passphrase , save = w . run ( )
if passphrase == - 1 :
passphrase = None
else :
self . gpg_passphrase [ keyid ] = passphrase
gobject . timeout_add ( 30000 , self . forget_gpg_passphrase , keyid )
if save :
gajim . config . set_per ( ' accounts ' , account , ' savegpgpass ' , True )
gajim . config . set_per ( ' accounts ' , account , ' gpgpassword ' ,
passphrase )
gajim . connections [ account ] . gpg_passphrase ( passphrase )
gajim . connections [ account ] . change_status ( status , txt , sync , auto )
2005-10-20 13:17:17 +02:00
for room_jid in gajim . interface . windows [ account ] [ ' gc ' ] :
2005-06-12 17:14:07 +02:00
if room_jid != ' tabbed ' :
2005-10-20 13:17:17 +02:00
nick = gajim . interface . windows [ account ] [ ' gc ' ] [ room_jid ] . nicks [ room_jid ]
2005-06-12 17:14:07 +02:00
gajim . connections [ account ] . send_gc_status ( nick , room_jid , status ,
2005-07-21 19:00:05 +02:00
txt )
2005-10-20 13:17:17 +02:00
if status == ' online ' and gajim . interface . sleeper . getState ( ) != \
2005-06-12 17:14:07 +02:00
common . sleepy . STATE_UNKNOWN :
2005-07-22 01:47:27 +02:00
gajim . sleeper_state [ account ] = ' online '
2005-06-12 17:14:07 +02:00
else :
2005-07-22 01:47:27 +02:00
gajim . sleeper_state [ account ] = ' off '
2005-06-12 17:14:07 +02:00
def get_status_message ( self , show ) :
if ( show == ' online ' and not gajim . config . get ( ' ask_online_status ' ) ) or \
( show == ' offline ' and not gajim . config . get ( ' ask_offline_status ' ) ) :
2005-09-08 09:10:59 +02:00
return ' '
2005-10-20 13:17:17 +02:00
dlg = dialogs . ChangeStatusMessageDialog ( show )
2005-06-12 17:14:07 +02:00
message = dlg . run ( )
return message
2005-09-13 19:53:31 +02:00
def connected_rooms ( self , account ) :
accounts = gajim . connections . keys ( )
if True in gajim . gc_connected [ account ] . values ( ) :
return True
return False
2005-06-12 17:14:07 +02:00
def change_status ( self , widget , account , status ) :
2005-09-13 19:53:31 +02:00
if status == ' invisible ' :
if self . connected_rooms ( account ) :
2005-09-13 23:29:38 +02:00
dialog = dialogs . ConfirmationDialog (
_ ( ' You are participating in one or more group chats ' ) ,
_ ( ' Changing your status to invisible will result in disconnection from those group chats. Are you sure you want to go invisible? ' ) )
2005-09-13 19:53:31 +02:00
if dialog . get_response ( ) != gtk . RESPONSE_OK :
return
2005-06-12 17:14:07 +02:00
message = self . get_status_message ( status )
2005-10-10 23:45:59 +02:00
if message is None : # user pressed Cancel to change status message dialog
2005-06-12 17:14:07 +02:00
return
self . send_status ( account , status , message )
def on_status_combobox_changed ( self , widget ) :
2005-10-19 13:03:01 +02:00
''' When we change our status via the combobox '''
2005-06-12 17:14:07 +02:00
model = self . status_combobox . get_model ( )
active = self . status_combobox . get_active ( )
2005-07-31 19:16:39 +02:00
if active == - 1 : # no active item
2005-06-12 17:14:07 +02:00
return
2005-11-05 19:09:57 +01:00
if not self . combobox_callback_active :
self . previous_status_combobox_active = active
return
2005-06-12 17:14:07 +02:00
accounts = gajim . connections . keys ( )
if len ( accounts ) == 0 :
2005-07-31 19:16:39 +02:00
dialogs . ErrorDialog ( _ ( ' No account available ' ) ,
_ ( ' You must create an account before you can chat with other contacts. ' )
) . get_response ( )
2005-06-12 17:14:07 +02:00
self . update_status_comboxbox ( )
return
2005-08-26 02:52:44 +02:00
status = model [ active ] [ 2 ] . decode ( ' utf-8 ' )
2005-10-09 16:49:14 +02:00
one_connected = helpers . one_account_connected ( )
2005-10-19 13:03:01 +02:00
if active == 7 : # We choose change status message (7 is that)
# do not change show, just show change status dialog
2005-11-05 18:52:49 +01:00
status = model [ self . previous_status_combobox_active ] [ 2 ] . decode ( ' utf-8 ' )
dlg = dialogs . ChangeStatusMessageDialog ( status )
2005-10-09 22:28:04 +02:00
message = dlg . run ( )
2005-10-10 00:24:18 +02:00
if message is not None : # None if user pressed Cancel
for acct in accounts :
2005-10-10 21:10:59 +02:00
if not gajim . config . get_per ( ' accounts ' , acct ,
' sync_with_global_status ' ) :
continue
2005-10-19 13:03:01 +02:00
current_show = gajim . SHOW_LIST [ gajim . connections [ acct ] . connected ]
self . send_status ( acct , current_show , message )
2005-11-05 19:09:57 +01:00
self . combobox_callback_active = False
2005-10-19 13:03:01 +02:00
self . status_combobox . set_active ( self . previous_status_combobox_active )
2005-11-05 19:09:57 +01:00
self . combobox_callback_active = True
2005-10-10 12:02:57 +02:00
return
2005-10-19 13:03:01 +02:00
# we are about to change show, so save this new show so in case
2005-10-26 19:33:37 +02:00
# after user chooses "Change status message" menuitem
# we can return to this show
2005-10-19 13:03:01 +02:00
self . previous_status_combobox_active = active
2005-09-13 19:53:31 +02:00
if status == ' invisible ' :
bug_user = False
for acct in accounts :
if not one_connected or gajim . connections [ acct ] . connected > 1 :
if not gajim . config . get_per ( ' accounts ' , acct ,
' sync_with_global_status ' ) :
continue
2005-10-11 00:46:28 +02:00
# We're going to change our status to invisible
2005-09-13 19:53:31 +02:00
if self . connected_rooms ( acct ) :
bug_user = True
break
if bug_user :
2005-09-13 23:29:38 +02:00
dialog = dialogs . ConfirmationDialog (
_ ( ' You are participating in one or more group chats ' ) ,
_ ( ' Changing your status to invisible will result in disconnection from those group chats. Are you sure you want to go invisible? ' ) )
2005-09-13 19:53:31 +02:00
if dialog . get_response ( ) != gtk . RESPONSE_OK :
return
message = self . get_status_message ( status )
2005-10-10 23:45:59 +02:00
if message is None : # user pressed Cancel to change status message dialog
2005-09-13 19:53:31 +02:00
self . update_status_comboxbox ( )
return
2005-06-12 17:14:07 +02:00
for acct in accounts :
2005-10-10 23:45:59 +02:00
if not gajim . config . get_per ( ' accounts ' , acct , ' sync_with_global_status ' ) :
2005-06-12 17:14:07 +02:00
continue
2005-10-11 00:49:20 +02:00
# we are connected (so we wanna change show and status)
# or no account is connected and we want to connect with new show and status
2005-06-21 20:32:52 +02:00
if not one_connected or gajim . connections [ acct ] . connected > 1 :
self . send_status ( acct , status , message )
2005-06-12 17:14:07 +02:00
def update_status_comboxbox ( self ) :
2005-10-20 13:17:17 +02:00
# table to change index in connection.connected to index in combobox
2005-10-09 22:28:04 +02:00
table = { 0 : 9 , 1 : 9 , 2 : 0 , 3 : 1 , 4 : 2 , 5 : 3 , 6 : 4 , 7 : 5 }
2005-06-12 17:14:07 +02:00
maxi = 0
for account in gajim . connections :
if gajim . connections [ account ] . connected > maxi :
maxi = gajim . connections [ account ] . connected
2005-10-11 00:46:28 +02:00
# temporarily block signal in order not to send status that we show
# in the combobox
2005-11-05 19:09:57 +01:00
self . combobox_callback_active = False
2005-06-12 17:14:07 +02:00
self . status_combobox . set_active ( table [ maxi ] )
2005-11-05 19:09:57 +01:00
self . combobox_callback_active = True
2005-06-12 17:14:07 +02:00
statuss = [ ' offline ' , ' connecting ' , ' online ' , ' chat ' , ' away ' ,
' xa ' , ' dnd ' , ' invisible ' ]
2005-10-20 13:17:17 +02:00
if gajim . interface . systray_enabled :
gajim . interface . systray . change_status ( statuss [ maxi ] )
2005-06-12 17:14:07 +02:00
def on_status_changed ( self , account , status ) :
''' the core tells us that our status has changed '''
2005-07-18 23:08:31 +02:00
if not gajim . contacts . has_key ( account ) :
2005-06-12 17:14:07 +02:00
return
model = self . tree . get_model ( )
accountIter = self . get_account_iter ( account )
if accountIter :
2005-07-24 17:42:19 +02:00
model [ accountIter ] [ 0 ] = self . jabber_state_images [ status ]
2005-06-12 17:14:07 +02:00
if status == ' offline ' :
2005-07-24 17:42:19 +02:00
if accountIter :
model [ accountIter ] [ 6 ] = None
2005-07-18 23:08:31 +02:00
for jid in gajim . contacts [ account ] :
luser = gajim . contacts [ account ] [ jid ]
2005-06-12 17:14:07 +02:00
luser_copy = [ ]
for user in luser :
luser_copy . append ( user )
for user in luser_copy :
2005-07-07 18:38:36 +02:00
self . chg_contact_status ( user , ' offline ' , ' Disconnected ' , account )
2005-06-12 17:14:07 +02:00
self . update_status_comboxbox ( )
2005-06-13 15:26:36 +02:00
self . make_menu ( )
2005-07-30 12:20:46 +02:00
2005-08-06 12:20:04 +02:00
def new_chat ( self , contact , account ) :
2005-10-29 00:37:14 +02:00
chats = gajim . interface . windows [ account ] [ ' chats ' ]
2005-06-12 17:14:07 +02:00
if gajim . config . get ( ' usetabbedchat ' ) :
2005-10-29 00:37:14 +02:00
if not chats . has_key ( ' tabbed ' ) :
chats [ ' tabbed ' ] = tabbed_chat_window . TabbedChatWindow ( contact ,
account )
2005-06-12 17:14:07 +02:00
else :
2005-10-29 00:37:14 +02:00
chats [ ' tabbed ' ] . new_tab ( contact )
2005-10-20 13:17:17 +02:00
2005-10-29 00:37:14 +02:00
chats [ contact . jid ] = chats [ ' tabbed ' ]
2005-06-12 17:14:07 +02:00
else :
2005-10-29 00:37:14 +02:00
chats [ contact . jid ] = tabbed_chat_window . TabbedChatWindow ( contact ,
account )
2005-06-12 17:14:07 +02:00
2005-06-30 18:45:14 +02:00
def new_chat_from_jid ( self , account , jid ) :
2005-07-18 23:08:31 +02:00
if gajim . contacts [ account ] . has_key ( jid ) :
2005-08-06 12:20:04 +02:00
contact = gajim . get_contact_instance_with_highest_priority ( account , jid )
2005-06-30 18:45:14 +02:00
else :
keyID = ' '
attached_keys = gajim . config . get_per ( ' accounts ' , account ,
' attached_gpg_keys ' ) . split ( )
if jid in attached_keys :
keyID = attached_keys [ attached_keys . index ( jid ) + 1 ]
2005-08-06 12:20:04 +02:00
contact = Contact ( jid = jid , name = jid . split ( ' @ ' ) [ 0 ] ,
2005-08-03 14:19:18 +02:00
groups = [ _ ( ' not in the roster ' ) ] , show = ' not in the roster ' ,
2005-08-04 21:44:09 +02:00
status = ' ' , sub = ' none ' , keyID = keyID )
2005-08-06 12:20:04 +02:00
gajim . contacts [ account ] [ jid ] = [ contact ]
self . add_contact_to_roster ( contact . jid , account )
2005-06-30 18:45:14 +02:00
2005-10-20 13:17:17 +02:00
if not gajim . interface . windows [ account ] [ ' chats ' ] . has_key ( jid ) :
2005-08-06 12:20:04 +02:00
self . new_chat ( contact , account )
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . set_active_tab ( jid )
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . window . present ( )
2005-06-30 18:45:14 +02:00
2005-06-12 17:14:07 +02:00
def new_room ( self , jid , nick , account ) :
if gajim . config . get ( ' usetabbedchat ' ) :
2005-10-20 13:17:17 +02:00
if not gajim . interface . windows [ account ] [ ' gc ' ] . has_key ( ' tabbed ' ) :
gajim . interface . windows [ account ] [ ' gc ' ] [ ' tabbed ' ] = \
groupchat_window . GroupchatWindow ( jid , nick , account )
2005-06-12 17:14:07 +02:00
else :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' gc ' ] [ ' tabbed ' ] . new_room ( jid , nick )
gajim . interface . windows [ account ] [ ' gc ' ] [ jid ] = \
gajim . interface . windows [ account ] [ ' gc ' ] [ ' tabbed ' ]
2005-06-12 17:14:07 +02:00
else :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' gc ' ] [ jid ] = \
groupchat_window . GroupchatWindow ( jid , nick , account )
2005-06-12 17:14:07 +02:00
2005-10-10 23:45:59 +02:00
def on_message ( self , jid , msg , tim , account , encrypted = False ,
2005-10-07 16:01:35 +02:00
msg_type = ' ' , subject = None , resource = ' ' ) :
2005-06-12 17:14:07 +02:00
''' when we receive a message '''
2005-07-18 23:08:31 +02:00
if not gajim . contacts [ account ] . has_key ( jid ) :
2005-06-12 17:14:07 +02:00
keyID = ' '
attached_keys = gajim . config . get_per ( ' accounts ' , account ,
' attached_gpg_keys ' ) . split ( )
if jid in attached_keys :
keyID = attached_keys [ attached_keys . index ( jid ) + 1 ]
2005-06-25 11:18:39 +02:00
user1 = Contact ( jid = jid , name = jid . split ( ' @ ' ) [ 0 ] ,
2005-08-03 14:19:18 +02:00
groups = [ _ ( ' not in the roster ' ) ] , show = ' not in the roster ' ,
2005-10-07 16:01:35 +02:00
status = ' ' , ask = ' none ' , keyID = keyID , resource = resource )
2005-07-18 23:08:31 +02:00
gajim . contacts [ account ] [ jid ] = [ user1 ]
2005-07-07 18:38:36 +02:00
self . add_contact_to_roster ( jid , account )
2005-07-05 23:35:37 +02:00
2005-07-07 18:38:36 +02:00
iters = self . get_contact_iter ( jid , account )
2005-06-12 17:14:07 +02:00
if iters :
path = self . tree . get_model ( ) . get_path ( iters [ 0 ] )
else :
path = None
autopopup = gajim . config . get ( ' autopopup ' )
autopopupaway = gajim . config . get ( ' autopopupaway ' )
2005-10-16 15:18:34 +02:00
save_in_queue = False
2005-07-05 23:35:37 +02:00
# Do we have a queue?
2005-10-15 22:49:08 +02:00
qs = gajim . awaiting_events [ account ]
2005-06-12 17:14:07 +02:00
no_queue = True
2005-07-02 00:20:01 +02:00
if qs . has_key ( jid ) :
2005-06-12 17:14:07 +02:00
no_queue = False
2005-10-16 15:18:34 +02:00
popup = False
2005-10-17 12:17:35 +02:00
if autopopup and ( autopopupaway or gajim . connections [ account ] . connected \
> 3 ) :
2005-10-16 15:18:34 +02:00
popup = True
2005-09-23 23:01:42 +02:00
2005-10-16 15:18:34 +02:00
if msg_type == ' normal ' : # it's single message
if popup :
contact = gajim . contacts [ account ] [ jid ] [ 0 ]
2005-10-20 13:17:17 +02:00
dialogs . SingleMessageWindow ( account , contact . jid ,
2005-10-16 15:18:34 +02:00
action = ' receive ' , from_whom = jid , subject = subject ,
message = msg )
return
# We print if window is opened and it's not a single message
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ account ] [ ' chats ' ] . has_key ( jid ) and \
2005-10-16 15:18:34 +02:00
msg_type != ' normal ' :
2005-09-15 19:33:02 +02:00
typ = ' '
if msg_type == ' error ' :
typ = ' status '
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . print_conversation ( msg ,
2005-09-15 19:33:02 +02:00
jid , typ , tim = tim , encrypted = encrypted , subject = subject )
2005-06-12 17:14:07 +02:00
return
2005-07-05 23:35:37 +02:00
2005-10-10 23:45:59 +02:00
# We save it in a queue
2005-07-02 00:20:01 +02:00
if no_queue :
qs [ jid ] = [ ]
2005-10-16 15:18:34 +02:00
kind = ' chat '
if msg_type == ' normal ' :
kind = ' normal '
qs [ jid ] . append ( ( kind , ( msg , subject , msg_type , tim , encrypted ) ) )
2005-06-12 17:14:07 +02:00
self . nb_unread + = 1
2005-10-16 15:18:34 +02:00
if popup :
2005-10-20 13:17:17 +02:00
if not gajim . interface . windows [ account ] [ ' chats ' ] . has_key ( jid ) :
2005-10-16 15:18:34 +02:00
c = gajim . get_contact_instance_with_highest_priority ( account , jid )
self . new_chat ( c , account )
if path :
self . tree . expand_row ( path [ 0 : 1 ] , False )
self . tree . expand_row ( path [ 0 : 2 ] , False )
self . tree . scroll_to_cell ( path )
self . tree . set_cursor ( path )
else :
2005-09-23 23:01:42 +02:00
if no_queue : # We didn't have a queue: we change icons
2005-06-12 17:14:07 +02:00
self . draw_contact ( jid , account )
2005-10-20 13:17:17 +02:00
if gajim . interface . systray_enabled :
gajim . interface . systray . add_jid ( jid , account , kind )
2005-06-12 17:14:07 +02:00
self . show_title ( ) # we show the * or [n]
if not path :
2005-07-07 18:38:36 +02:00
self . add_contact_to_roster ( jid , account )
iters = self . get_contact_iter ( jid , account )
2005-06-12 17:14:07 +02:00
path = self . tree . get_model ( ) . get_path ( iters [ 0 ] )
self . tree . expand_row ( path [ 0 : 1 ] , False )
self . tree . expand_row ( path [ 0 : 2 ] , False )
self . tree . scroll_to_cell ( path )
self . tree . set_cursor ( path )
def on_preferences_menuitem_activate ( self , widget ) :
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ ' preferences ' ] . window . get_property ( ' visible ' ) :
gajim . interface . windows [ ' preferences ' ] . window . present ( )
2005-06-12 17:14:07 +02:00
else :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ ' preferences ' ] . window . show_all ( )
2005-06-12 17:14:07 +02:00
def on_add_new_contact ( self , widget , account ) :
2005-10-20 13:17:17 +02:00
dialogs . AddNewContactWindow ( account )
2005-06-12 17:14:07 +02:00
def on_join_gc_activate ( self , widget , account ) :
2005-09-30 19:52:25 +02:00
invisible_show = gajim . SHOW_LIST . index ( ' invisible ' )
if gajim . connections [ account ] . connected == invisible_show :
2005-10-09 15:53:21 +02:00
dialogs . ErrorDialog ( _ ( ' You cannot join a room while you are invisible ' )
2005-09-30 19:52:25 +02:00
) . get_response ( )
return
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ account ] . has_key ( ' join_gc ' ) :
gajim . interface . windows [ account ] [ ' join_gc ' ] . window . present ( )
2005-06-12 17:14:07 +02:00
else :
2005-10-11 00:46:28 +02:00
# c http://nkour.blogspot.com/2005/05/pythons-init-return-none-doesnt-return.html
2005-06-12 17:14:07 +02:00
try :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' join_gc ' ] = \
dialogs . JoinGroupchatWindow ( account )
2005-06-12 17:14:07 +02:00
except RuntimeError :
pass
def on_new_message_menuitem_activate ( self , widget , account ) :
2005-10-20 13:17:17 +02:00
dialogs . NewMessageDialog ( account )
2005-06-12 17:14:07 +02:00
2005-10-07 01:34:23 +02:00
def on_contents_menuitem_activate ( self , widget ) :
helpers . launch_browser_mailer ( ' url ' , ' http://trac.gajim.org/wiki ' )
def on_faq_menuitem_activate ( self , widget ) :
helpers . launch_browser_mailer ( ' url ' , ' http://trac.gajim.org/wiki/GajimFaq ' )
2005-06-12 17:14:07 +02:00
def on_about_menuitem_activate ( self , widget ) :
dialogs . AboutDialog ( )
def on_accounts_menuitem_activate ( self , widget ) :
2005-10-20 13:17:17 +02:00
if gajim . interface . windows . has_key ( ' accounts ' ) :
gajim . interface . windows [ ' accounts ' ] . window . present ( )
2005-06-12 17:14:07 +02:00
else :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ ' accounts ' ] = config . AccountsWindow ( )
2005-06-12 17:14:07 +02:00
2005-08-03 17:59:44 +02:00
def on_file_transfers_menuitem_activate ( self , widget ) :
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ ' file_transfers ' ] . window . get_property ( ' visible ' ) :
gajim . interface . windows [ ' file_transfers ' ] . window . present ( )
2005-08-03 17:59:44 +02:00
else :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ ' file_transfers ' ] . window . show_all ( )
2005-08-03 17:59:44 +02:00
2005-08-07 14:55:59 +02:00
def on_manage_bookmarks_menuitem_activate ( self , widget ) :
2005-10-20 13:17:17 +02:00
config . ManageBookmarksWindow ( )
2005-06-12 17:14:07 +02:00
def close_all ( self , dic ) :
''' close all the windows in the given dictionary '''
for w in dic . values ( ) :
if type ( w ) == type ( { } ) :
self . close_all ( w )
else :
w . window . destroy ( )
def on_roster_window_delete_event ( self , widget , event ) :
''' When we want to close the window '''
2005-10-20 13:17:17 +02:00
if gajim . interface . systray_enabled and not gajim . config . get ( ' quit_on_roster_x_button ' ) :
2005-07-07 23:27:53 +02:00
self . tooltip . hide_tooltip ( )
2005-06-12 17:14:07 +02:00
self . window . hide ( )
else :
accounts = gajim . connections . keys ( )
get_msg = False
for acct in accounts :
if gajim . connections [ acct ] . connected :
get_msg = True
break
if get_msg :
message = self . get_status_message ( ' offline ' )
2005-10-10 23:45:59 +02:00
if message is None : # user pressed Cancel to change status message dialog
2005-06-12 17:14:07 +02:00
message = ' '
for acct in accounts :
if gajim . connections [ acct ] . connected :
2005-08-07 13:41:20 +02:00
self . send_status ( acct , ' offline ' , message , True )
2005-10-20 13:17:17 +02:00
self . quit_gtkgui_interface ( )
2005-06-12 17:14:07 +02:00
return True # do NOT destory the window
2005-09-04 18:57:09 +02:00
def on_roster_window_focus_in_event ( self , widget , event ) :
''' roster received focus, so if we had urgency REMOVE IT
NOTE : we do not have to read the message to remove urgency
so this functions does that '''
if gtk . gtk_version > = ( 2 , 8 , 0 ) and gtk . pygtk_version > = ( 2 , 8 , 0 ) :
if widget . props . urgency_hint :
widget . props . urgency_hint = False
2005-09-20 21:57:34 +02:00
def on_roster_window_key_press_event ( self , widget , event ) :
if event . keyval == gtk . keysyms . Escape :
2005-09-22 17:13:37 +02:00
treeselection = self . tree . get_selection ( )
model , iter = treeselection . get_selected ( )
2005-10-20 13:17:17 +02:00
if not iter and gajim . interface . systray_enabled and not gajim . config . get ( ' quit_on_roster_x_button ' ) :
2005-09-20 21:57:34 +02:00
self . tooltip . hide_tooltip ( )
self . window . hide ( )
2005-10-20 13:17:17 +02:00
def quit_gtkgui_interface ( self ) :
''' When we quit the gtk interface :
2005-06-12 17:14:07 +02:00
tell that to the core and exit gtk '''
if gajim . config . get ( ' saveposition ' ) :
2005-09-09 16:56:14 +02:00
# in case show_roster_on_start is False and roster is never shown
# window.window is None
if self . window . window is not None :
x , y = self . window . window . get_root_origin ( )
gajim . config . set ( ' roster_x-position ' , x )
gajim . config . set ( ' roster_y-position ' , y )
width , height = self . window . get_size ( )
gajim . config . set ( ' roster_width ' , width )
gajim . config . set ( ' roster_height ' , height )
2005-06-12 17:14:07 +02:00
gajim . config . set ( ' collapsed_rows ' , ' \t ' . join ( self . collapsed_rows ) )
2005-10-20 13:17:17 +02:00
gajim . interface . save_config ( )
2005-06-12 17:14:07 +02:00
for account in gajim . connections :
gajim . connections [ account ] . quit ( True )
2005-10-20 13:17:17 +02:00
self . close_all ( gajim . interface . windows )
if gajim . interface . systray_enabled :
gajim . interface . hide_systray ( )
2005-06-12 17:14:07 +02:00
gtk . main_quit ( )
def on_quit_menuitem_activate ( self , widget ) :
accounts = gajim . connections . keys ( )
get_msg = False
for acct in accounts :
if gajim . connections [ acct ] . connected :
get_msg = True
break
if get_msg :
message = self . get_status_message ( ' offline ' )
2005-10-10 23:45:59 +02:00
if message is None : # user pressed Cancel to change status message dialog
2005-06-12 17:14:07 +02:00
return
# check if we have unread or recent mesages
unread = False
recent = False
if self . nb_unread > 0 :
unread = True
for account in accounts :
2005-10-20 13:17:17 +02:00
if gajim . interface . windows [ account ] [ ' chats ' ] . has_key ( ' tabbed ' ) :
wins = [ gajim . interface . windows [ account ] [ ' chats ' ] [ ' tabbed ' ] ]
2005-06-12 17:14:07 +02:00
else :
2005-10-20 13:17:17 +02:00
wins = gajim . interface . windows [ account ] [ ' chats ' ] . values ( )
2005-06-12 17:14:07 +02:00
for win in wins :
unrd = 0
for jid in win . nb_unread :
unrd + = win . nb_unread [ jid ]
if unrd :
unread = True
break
2005-07-21 17:43:53 +02:00
for jid in win . contacts :
2005-07-03 17:27:41 +02:00
if time . time ( ) - gajim . last_message_time [ account ] [ jid ] < 2 :
2005-06-12 17:14:07 +02:00
recent = True
break
if unread :
dialog = dialogs . ConfirmationDialog ( _ ( ' You have unread messages ' ) ,
_ ( ' Messages will only be available for reading them later if you have history enabled. ' ) )
if dialog . get_response ( ) != gtk . RESPONSE_OK :
return
if recent :
dialog = dialogs . ConfirmationDialog ( _ ( ' You have unread messages ' ) ,
_ ( ' Messages will only be available for reading them later if you have history enabled. ' ) )
if dialog . get_response ( ) != gtk . RESPONSE_OK :
return
for acct in accounts :
if gajim . connections [ acct ] . connected :
2005-06-28 21:03:00 +02:00
# send status asynchronously
self . send_status ( acct , ' offline ' , message , True )
2005-10-20 13:17:17 +02:00
self . quit_gtkgui_interface ( )
2005-06-12 17:14:07 +02:00
2005-10-18 22:30:26 +02:00
def open_event ( self , account , jid , event ) :
''' If an event was handled, return True, else return False '''
typ = event [ 0 ]
2005-10-16 15:18:34 +02:00
data = event [ 1 ]
2005-10-20 13:17:17 +02:00
ft = gajim . interface . windows [ ' file_transfers ' ]
2005-10-18 22:30:26 +02:00
if typ == ' normal ' :
2005-10-20 13:17:17 +02:00
dialogs . SingleMessageWindow ( account , jid ,
2005-10-18 22:30:26 +02:00
action = ' receive ' , from_whom = jid , subject = data [ 1 ] ,
message = data [ 0 ] )
2005-10-29 00:37:58 +02:00
gajim . interface . remove_first_event ( account , jid , typ )
2005-10-18 22:30:26 +02:00
return True
elif typ == ' file-request ' :
contact = gajim . get_contact_instance_with_highest_priority ( account , jid )
ft . show_file_request ( account , contact , data )
2005-10-29 00:37:58 +02:00
gajim . interface . remove_first_event ( account , jid , typ )
2005-10-18 22:30:26 +02:00
return True
2005-10-19 22:16:22 +02:00
elif typ in ( ' file-request-error ' , ' file-send-error ' ) :
2005-10-18 22:30:26 +02:00
ft . show_send_error ( data )
2005-10-29 00:37:58 +02:00
gajim . interface . remove_first_event ( account , jid , typ )
2005-10-18 22:30:26 +02:00
return True
2005-10-19 23:14:51 +02:00
elif typ in ( ' file-error ' , ' file-stopped ' ) :
2005-10-19 22:16:22 +02:00
ft . show_stopped ( jid , data )
2005-10-29 00:37:58 +02:00
gajim . interface . remove_first_event ( account , jid , typ )
2005-10-19 22:16:22 +02:00
return True
2005-10-19 23:14:51 +02:00
elif typ == ' file-completed ' :
ft . show_completed ( jid , data )
2005-10-29 00:37:58 +02:00
gajim . interface . remove_first_event ( account , jid , typ )
2005-10-19 23:14:51 +02:00
return True
2005-10-18 22:30:26 +02:00
return False
2005-10-16 15:18:34 +02:00
2005-06-12 17:14:07 +02:00
def on_roster_treeview_row_activated ( self , widget , path , col = 0 ) :
2005-10-16 15:18:34 +02:00
''' When an iter is double clicked: open the first event window '''
2005-06-12 17:14:07 +02:00
model = self . tree . get_model ( )
iter = model . get_iter ( path )
2005-09-09 00:07:49 +02:00
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
type = model [ iter ] [ C_TYPE ]
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
2005-07-23 17:23:45 +02:00
if type in ( ' group ' , ' account ' ) :
2005-06-12 17:14:07 +02:00
if self . tree . row_expanded ( path ) :
self . tree . collapse_row ( path )
else :
self . tree . expand_row ( path , False )
else :
2005-10-18 11:07:52 +02:00
first_ev = gajim . get_first_event ( account , jid )
if first_ev :
2005-10-18 22:30:26 +02:00
if self . open_event ( account , jid , first_ev ) :
2005-10-16 15:18:34 +02:00
return
2005-10-29 00:37:14 +02:00
chats = gajim . interface . windows [ account ] [ ' chats ' ]
if chats . has_key ( jid ) :
chats [ jid ] . set_active_tab ( jid )
2005-07-18 23:08:31 +02:00
elif gajim . contacts [ account ] . has_key ( jid ) :
2005-08-06 12:20:04 +02:00
c = gajim . get_contact_instance_with_highest_priority ( account , jid )
self . new_chat ( c , account )
2005-10-29 00:37:14 +02:00
chats [ jid ] . set_active_tab ( jid )
chats [ jid ] . window . present ( )
2005-06-12 17:14:07 +02:00
def on_roster_treeview_row_expanded ( self , widget , iter , path ) :
''' When a row is expanded change the icon of the arrow '''
model = self . tree . get_model ( )
2005-09-13 18:27:48 +02:00
if gajim . config . get ( ' mergeaccounts ' ) :
2005-06-21 00:51:42 +02:00
accounts = gajim . connections . keys ( )
else :
2005-09-09 00:07:49 +02:00
accounts = [ model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' ) ]
type = model [ iter ] [ C_TYPE ]
2005-06-12 17:14:07 +02:00
if type == ' group ' :
model . set_value ( iter , 0 , self . jabber_state_images [ ' opened ' ] )
2005-09-09 00:07:49 +02:00
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
2005-06-21 00:51:42 +02:00
for account in accounts :
2005-07-18 23:08:31 +02:00
if gajim . groups [ account ] . has_key ( jid ) : # This account has this group
gajim . groups [ account ] [ jid ] [ ' expand ' ] = True
2005-06-21 00:51:42 +02:00
if account + jid in self . collapsed_rows :
self . collapsed_rows . remove ( account + jid )
2005-06-12 17:14:07 +02:00
elif type == ' account ' :
2005-06-21 00:51:42 +02:00
account = accounts [ 0 ] # There is only one cause we don't use merge
2005-06-12 17:14:07 +02:00
if account in self . collapsed_rows :
self . collapsed_rows . remove ( account )
2005-07-18 23:08:31 +02:00
for g in gajim . groups [ account ] :
2005-06-12 17:14:07 +02:00
groupIter = self . get_group_iter ( g , account )
2005-07-18 23:08:31 +02:00
if groupIter and gajim . groups [ account ] [ g ] [ ' expand ' ] :
2005-06-12 17:14:07 +02:00
pathG = model . get_path ( groupIter )
self . tree . expand_row ( pathG , False )
2005-07-18 23:08:31 +02:00
2005-06-12 17:14:07 +02:00
def on_roster_treeview_row_collapsed ( self , widget , iter , path ) :
''' When a row is collapsed :
change the icon of the arrow '''
model = self . tree . get_model ( )
2005-09-13 18:27:48 +02:00
if gajim . config . get ( ' mergeaccounts ' ) :
2005-06-21 00:51:42 +02:00
accounts = gajim . connections . keys ( )
else :
2005-09-09 00:07:49 +02:00
accounts = [ model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' ) ]
type = model [ iter ] [ C_TYPE ]
2005-06-12 17:14:07 +02:00
if type == ' group ' :
model . set_value ( iter , 0 , self . jabber_state_images [ ' closed ' ] )
2005-09-09 00:07:49 +02:00
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
2005-06-21 00:51:42 +02:00
for account in accounts :
2005-07-18 23:08:31 +02:00
if gajim . groups [ account ] . has_key ( jid ) : # This account has this group
gajim . groups [ account ] [ jid ] [ ' expand ' ] = False
2005-06-21 00:51:42 +02:00
if not account + jid in self . collapsed_rows :
self . collapsed_rows . append ( account + jid )
2005-06-12 17:14:07 +02:00
elif type == ' account ' :
2005-06-21 00:51:42 +02:00
account = accounts [ 0 ] # There is only one cause we don't use merge
2005-06-12 17:14:07 +02:00
if not account in self . collapsed_rows :
self . collapsed_rows . append ( account )
2005-09-08 21:55:47 +02:00
def on_editing_started ( self , cell , event , row ) :
2005-07-23 00:50:25 +02:00
''' start editing a cell in the tree '''
path = self . tree . get_cursor ( ) [ 0 ]
self . editing_path = path
2005-09-08 21:55:47 +02:00
def on_editing_canceled ( self , cell ) :
2005-06-12 17:14:07 +02:00
''' editing has been canceled '''
2005-07-22 16:37:15 +02:00
path = self . tree . get_cursor ( ) [ 0 ]
2005-07-23 00:50:25 +02:00
# do not set new name if row order has changed
if path != self . editing_path :
self . editing_path = None
return
self . editing_path = None
2005-07-22 16:37:15 +02:00
model = self . tree . get_model ( )
iter = model . get_iter ( path )
2005-09-09 00:07:49 +02:00
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
type = model [ iter ] [ C_TYPE ]
2005-07-22 16:37:15 +02:00
# restore the number of resources string at the end of contact name
if type == ' contact ' and len ( gajim . contacts [ account ] [ jid ] ) > 1 :
self . draw_contact ( jid , account )
2005-09-08 21:55:47 +02:00
# reset editable to False
2005-09-09 00:07:49 +02:00
model [ iter ] [ C_EDITABLE ] = False
2005-06-12 17:14:07 +02:00
def on_cell_edited ( self , cell , row , new_text ) :
2005-07-18 16:52:28 +02:00
''' When an iter is edited:
if text has changed , rename the contact '''
2005-06-12 17:14:07 +02:00
model = self . tree . get_model ( )
2005-07-23 00:50:25 +02:00
# if this is a last item in the group, row is invalid
try :
iter = model . get_iter_from_string ( row )
except :
2005-08-27 19:24:12 +02:00
self . editing_path = None
2005-07-23 00:50:25 +02:00
return
2005-06-12 17:14:07 +02:00
path = model . get_path ( iter )
2005-07-23 00:50:25 +02:00
# do not set new name if row order has changed
if path != self . editing_path :
2005-08-27 19:24:12 +02:00
self . editing_path = None
2005-07-23 00:50:25 +02:00
return
2005-08-27 19:24:12 +02:00
self . editing_path = None
2005-08-27 15:26:24 +02:00
new_text = new_text . decode ( ' utf-8 ' )
2005-09-09 00:07:49 +02:00
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
type = model [ iter ] [ C_TYPE ]
2005-07-07 18:38:36 +02:00
if type == ' contact ' :
2005-07-18 23:08:31 +02:00
old_text = gajim . contacts [ account ] [ jid ] [ 0 ] . name
2005-06-12 17:14:07 +02:00
if old_text != new_text :
2005-07-18 23:08:31 +02:00
for u in gajim . contacts [ account ] [ jid ] :
2005-06-12 17:14:07 +02:00
u . name = new_text
2005-07-18 16:52:28 +02:00
gajim . connections [ account ] . update_contact ( jid , new_text , u . groups )
2005-06-12 17:14:07 +02:00
self . draw_contact ( jid , account )
elif type == ' group ' :
2005-09-09 00:07:49 +02:00
old_name = model [ iter ] [ C_NAME ] . decode ( ' utf-8 ' )
2005-07-22 16:10:03 +02:00
# Groups maynot change name from or to 'not in the roster'
2005-07-23 17:23:45 +02:00
if _ ( ' not in the roster ' ) in ( new_text , old_name ) :
2005-07-22 16:10:03 +02:00
return
2005-06-12 17:14:07 +02:00
#get all users in that group
2005-07-18 23:08:31 +02:00
for jid in gajim . contacts [ account ] :
user = gajim . contacts [ account ] [ jid ] [ 0 ]
2005-06-12 17:14:07 +02:00
if old_name in user . groups :
#set them in the new one and remove it from the old
2005-07-21 19:54:58 +02:00
self . remove_contact ( user , account )
2005-06-12 17:14:07 +02:00
user . groups . remove ( old_name )
user . groups . append ( new_text )
2005-07-07 18:38:36 +02:00
self . add_contact_to_roster ( user . jid , account )
2005-07-18 16:52:28 +02:00
gajim . connections [ account ] . update_contact ( user . jid , user . name ,
2005-06-12 17:14:07 +02:00
user . groups )
model . set_value ( iter , 5 , False )
def on_service_disco_menuitem_activate ( self , widget , account ) :
2005-10-30 10:58:13 +01:00
server_jid = gajim . config . get_per ( ' accounts ' , account , ' hostname ' )
if gajim . interface . windows [ account ] [ ' disco ' ] . has_key ( server_jid ) :
gajim . interface . windows [ account ] [ ' disco ' ] [ server_jid ] . window . present ( )
2005-06-12 17:14:07 +02:00
else :
try :
2005-10-30 10:58:13 +01:00
# Object will add itself to the window dict
disco . ServiceDiscoveryWindow ( account , address_entry = True )
2005-06-12 17:14:07 +02:00
except RuntimeError :
pass
def load_iconset ( self , path ) :
imgs = { }
for state in ( ' connecting ' , ' online ' , ' chat ' , ' away ' , ' xa ' ,
' dnd ' , ' invisible ' , ' offline ' , ' error ' , ' requested ' ,
2005-08-03 14:19:18 +02:00
' message ' , ' opened ' , ' closed ' , ' not in the roster ' ) :
2005-06-12 17:14:07 +02:00
# try to open a pixfile with the correct method
state_file = state . replace ( ' ' , ' _ ' )
files = [ ]
files . append ( path + state_file + ' .gif ' )
files . append ( path + state_file + ' .png ' )
image = gtk . Image ( )
image . show ( )
imgs [ state ] = image
2005-08-16 22:24:56 +02:00
for file in files : # loop seeking for either gif or png
2005-06-12 17:14:07 +02:00
if os . path . exists ( file ) :
image . set_from_file ( file )
break
return imgs
def make_jabber_state_images ( self ) :
''' initialise jabber_state_images dict '''
iconset = gajim . config . get ( ' iconset ' )
if not iconset :
iconset = ' sun '
2005-08-16 21:12:51 +02:00
path = os . path . join ( gajim . DATA_DIR , ' iconsets/ ' + iconset + ' /16x16/ ' )
self . jabber_state_images = self . load_iconset ( path )
2005-06-12 17:14:07 +02:00
def reload_jabber_state_images ( self ) :
self . make_jabber_state_images ( )
# Update the roster
self . draw_roster ( )
# Update the status combobox
model = self . status_combobox . get_model ( )
iter = model . get_iter_root ( )
while iter :
2005-10-10 23:45:59 +02:00
if model [ iter ] [ 2 ] != ' ' :
# If it's not change status message iter
# eg. if it has show parameter not ''
model [ iter ] [ 1 ] = self . jabber_state_images [ model [ iter ] [ 2 ] ]
2005-06-12 17:14:07 +02:00
iter = model . iter_next ( iter )
# Update the systray
2005-10-20 13:17:17 +02:00
if gajim . interface . systray_enabled :
gajim . interface . systray . set_img ( )
2005-06-12 17:14:07 +02:00
for account in gajim . connections :
# Update opened chat windows
2005-10-20 13:17:17 +02:00
for jid in gajim . interface . windows [ account ] [ ' chats ' ] :
2005-06-12 17:14:07 +02:00
if jid != ' tabbed ' :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . set_state_image ( jid )
2005-06-12 17:14:07 +02:00
# Update opened groupchat windows
2005-10-20 13:17:17 +02:00
for jid in gajim . interface . windows [ account ] [ ' gc ' ] :
2005-06-12 17:14:07 +02:00
if jid != ' tabbed ' :
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ account ] [ ' gc ' ] [ jid ] . update_state_images ( )
2005-06-12 17:14:07 +02:00
self . update_status_comboxbox ( )
def repaint_themed_widgets ( self ) :
2005-11-07 11:50:40 +01:00
''' Notify windows that contain themed widgets to repaint them '''
2005-06-12 17:14:07 +02:00
for account in gajim . connections :
# Update opened chat windows/tabs
2005-10-20 13:17:17 +02:00
for jid in gajim . interface . windows [ account ] [ ' chats ' ] :
gajim . interface . windows [ account ] [ ' chats ' ] [ jid ] . repaint_colored_widgets ( )
for jid in gajim . interface . windows [ account ] [ ' gc ' ] :
gajim . interface . windows [ account ] [ ' gc ' ] [ jid ] . repaint_colored_widgets ( )
2005-10-30 10:58:13 +01:00
for addr in gajim . interface . windows [ account ] [ ' disco ' ] :
gajim . interface . windows [ account ] [ ' disco ' ] [ addr ] . paint_banner ( )
2005-06-12 17:14:07 +02:00
def on_show_offline_contacts_menuitem_activate ( self , widget ) :
''' when show offline option is changed:
redraw the treeview '''
2005-07-07 17:41:03 +02:00
gajim . config . set ( ' showoffline ' , not gajim . config . get ( ' showoffline ' ) )
2005-06-12 17:14:07 +02:00
self . draw_roster ( )
def iconCellDataFunc ( self , column , renderer , model , iter , data = None ) :
''' When a row is added, set properties for icon renderer '''
2005-06-14 00:11:09 +02:00
theme = gajim . config . get ( ' roster_theme ' )
2005-09-09 00:07:49 +02:00
if model [ iter ] [ C_TYPE ] == ' account ' :
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' accountbgcolor ' )
if color :
renderer . set_property ( ' cell-background ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' cell-background ' , None )
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' xalign ' , 0 )
2005-09-09 00:07:49 +02:00
elif model [ iter ] [ C_TYPE ] == ' group ' :
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' groupbgcolor ' )
if color :
renderer . set_property ( ' cell-background ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' cell-background ' , None )
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' xalign ' , 0.5 )
else :
2005-09-09 00:07:49 +02:00
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
2005-07-18 23:08:31 +02:00
if jid in gajim . newly_added [ account ] :
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' cell-background ' , ' #adc3c6 ' )
2005-07-18 23:08:31 +02:00
elif jid in gajim . to_be_removed [ account ] :
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' cell-background ' , ' #ab6161 ' )
else :
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' contactbgcolor ' )
if color :
renderer . set_property ( ' cell-background ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' cell-background ' , None )
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' xalign ' , 1 )
renderer . set_property ( ' width ' , 20 )
def nameCellDataFunc ( self , column , renderer , model , iter , data = None ) :
''' When a row is added, set properties for name renderer '''
2005-06-14 00:11:09 +02:00
theme = gajim . config . get ( ' roster_theme ' )
2005-09-09 00:07:49 +02:00
if model [ iter ] [ C_TYPE ] == ' account ' :
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' accounttextcolor ' )
if color :
renderer . set_property ( ' foreground ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' foreground ' , None )
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' accountbgcolor ' )
if color :
renderer . set_property ( ' cell-background ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' cell-background ' , None )
2005-09-17 10:34:55 +02:00
renderer . set_property ( ' font ' ,
gtkgui_helpers . get_theme_font_for_option ( theme , ' accountfont ' ) )
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' xpad ' , 0 )
2005-06-29 17:10:10 +02:00
renderer . set_property ( ' width ' , 3 )
2005-09-09 00:07:49 +02:00
elif model [ iter ] [ C_TYPE ] == ' group ' :
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' grouptextcolor ' )
if color :
renderer . set_property ( ' foreground ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' foreground ' , None )
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' groupbgcolor ' )
if color :
renderer . set_property ( ' cell-background ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' cell-background ' , None )
2005-06-14 00:11:09 +02:00
renderer . set_property ( ' font ' ,
2005-09-17 10:34:55 +02:00
gtkgui_helpers . get_theme_font_for_option ( theme , ' groupfont ' ) )
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' xpad ' , 4 )
else :
2005-09-09 00:07:49 +02:00
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' contacttextcolor ' )
if color :
renderer . set_property ( ' foreground ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' foreground ' , None )
2005-07-18 23:08:31 +02:00
if jid in gajim . newly_added [ account ] :
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' cell-background ' , ' #adc3c6 ' )
2005-07-18 23:08:31 +02:00
elif jid in gajim . to_be_removed [ account ] :
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' cell-background ' , ' #ab6161 ' )
else :
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' contactbgcolor ' )
if color :
renderer . set_property ( ' cell-background ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' cell-background ' , None )
2005-06-14 00:11:09 +02:00
renderer . set_property ( ' font ' ,
2005-09-17 10:34:55 +02:00
gtkgui_helpers . get_theme_font_for_option ( theme , ' contactfont ' ) )
2005-06-12 17:14:07 +02:00
renderer . set_property ( ' xpad ' , 8 )
2005-06-29 14:57:46 +02:00
def fill_secondary_pixbuf_rederer ( self , column , renderer , model , iter , data = None ) :
''' When a row is added, set properties for secondary renderer (avatar or tls) '''
theme = gajim . config . get ( ' roster_theme ' )
2005-09-09 00:07:49 +02:00
if model [ iter ] [ C_TYPE ] == ' account ' :
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' accountbgcolor ' )
if color :
renderer . set_property ( ' cell-background ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' cell-background ' , None )
2005-09-09 00:07:49 +02:00
elif model [ iter ] [ C_TYPE ] == ' group ' :
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' groupbgcolor ' )
if color :
renderer . set_property ( ' cell-background ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' cell-background ' , None )
2005-06-29 14:57:46 +02:00
else :
2005-09-09 00:07:49 +02:00
jid = model [ iter ] [ C_JID ] . decode ( ' utf-8 ' )
account = model [ iter ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
2005-07-18 23:08:31 +02:00
if jid in gajim . newly_added [ account ] :
2005-06-29 14:57:46 +02:00
renderer . set_property ( ' cell-background ' , ' #adc3c6 ' )
2005-07-18 23:08:31 +02:00
elif jid in gajim . to_be_removed [ account ] :
2005-06-29 14:57:46 +02:00
renderer . set_property ( ' cell-background ' , ' #ab6161 ' )
else :
2005-09-16 23:30:30 +02:00
color = gajim . config . get_per ( ' themes ' , theme , ' contactbgcolor ' )
if color :
renderer . set_property ( ' cell-background ' , color )
2005-09-19 17:23:18 +02:00
else :
renderer . set_property ( ' cell-background ' , None )
2005-06-29 14:57:46 +02:00
#renderer.set_property('width', 20)
2005-06-29 17:10:10 +02:00
#renderer.set_property('xalign', 0)
2005-06-29 14:57:46 +02:00
2005-06-12 17:14:07 +02:00
def get_show ( self , luser ) :
prio = luser [ 0 ] . priority
show = luser [ 0 ] . show
for u in luser :
if u . priority > prio :
prio = u . priority
show = u . show
return show
def compareIters ( self , model , iter1 , iter2 , data = None ) :
''' Compare two iters to sort them '''
name1 = model . get_value ( iter1 , 1 )
name2 = model . get_value ( iter2 , 1 )
if not name1 or not name2 :
return 0
2005-08-26 02:52:44 +02:00
else :
name1 = name1 . decode ( ' utf-8 ' )
name2 = name2 . decode ( ' utf-8 ' )
2005-06-12 17:14:07 +02:00
type1 = model . get_value ( iter1 , 2 )
type2 = model . get_value ( iter2 , 2 )
if type1 == ' group ' :
2005-07-07 19:25:04 +02:00
if name1 == _ ( ' Transports ' ) :
2005-06-12 17:14:07 +02:00
return 1
2005-07-07 19:25:04 +02:00
if name2 == _ ( ' Transports ' ) :
2005-06-12 17:14:07 +02:00
return - 1
2005-07-07 19:33:15 +02:00
if name1 == _ ( ' not in the roster ' ) :
2005-06-12 17:14:07 +02:00
return 1
2005-07-07 19:33:15 +02:00
if name2 == _ ( ' not in the roster ' ) :
2005-06-12 17:14:07 +02:00
return - 1
2005-07-07 18:38:36 +02:00
if type1 == ' contact ' and type2 == ' contact ' and \
2005-06-12 17:14:07 +02:00
gajim . config . get ( ' sort_by_show ' ) :
2005-10-11 18:02:57 +02:00
account1 = model . get_value ( iter1 , 4 )
account2 = model . get_value ( iter2 , 4 )
if account1 and account2 :
account1 = account1 . decode ( ' utf-8 ' )
account2 = account2 . decode ( ' utf-8 ' )
2005-09-12 23:56:50 +02:00
jid1 = model [ iter1 ] [ C_JID ] . decode ( ' utf-8 ' )
jid2 = model [ iter2 ] [ C_JID ] . decode ( ' utf-8 ' )
2005-10-11 18:02:57 +02:00
luser1 = gajim . contacts [ account1 ] [ jid1 ]
luser2 = gajim . contacts [ account2 ] [ jid2 ]
2005-06-18 17:18:15 +02:00
cshow = { ' online ' : 0 , ' chat ' : 1 , ' away ' : 2 , ' xa ' : 3 , ' dnd ' : 4 ,
2005-08-03 14:19:18 +02:00
' invisible ' : 5 , ' offline ' : 6 , ' not in the roster ' : 7 , ' error ' : 8 }
2005-06-12 17:14:07 +02:00
s = self . get_show ( luser1 )
if s in cshow :
show1 = cshow [ s ]
else :
show1 = 9
s = self . get_show ( luser2 )
if s in cshow :
show2 = cshow [ s ]
else :
show2 = 9
if show1 < show2 :
return - 1
elif show1 > show2 :
return 1
if name1 . lower ( ) < name2 . lower ( ) :
return - 1
if name2 . lower < name1 . lower ( ) :
return 1
return 0
def drag_data_get_data ( self , treeview , context , selection , target_id , etime ) :
treeselection = treeview . get_selection ( )
model , iter = treeselection . get_selected ( )
path = model . get_path ( iter )
data = ' '
2005-08-04 12:43:02 +02:00
merge = 0
2005-09-13 18:27:48 +02:00
if gajim . config . get ( ' mergeaccounts ' ) :
2005-08-04 12:43:02 +02:00
merge = 1
if len ( path ) == 3 - merge :
2005-09-09 00:07:49 +02:00
data = model [ iter ] [ C_JID ]
2005-06-12 17:14:07 +02:00
selection . set ( selection . target , 8 , data )
def drag_data_received_data ( self , treeview , context , x , y , selection , info ,
etime ) :
merge = 0
2005-09-13 18:27:48 +02:00
if gajim . config . get ( ' mergeaccounts ' ) :
2005-06-12 17:14:07 +02:00
merge = 1
model = treeview . get_model ( )
2005-08-30 22:58:40 +02:00
if not selection . data :
2005-06-12 17:14:07 +02:00
return
2005-08-30 22:58:40 +02:00
data = selection . data . decode ( ' utf-8 ' )
2005-06-12 17:14:07 +02:00
drop_info = treeview . get_dest_row_at_pos ( x , y )
if not drop_info :
return
path_dest , position = drop_info
if position == gtk . TREE_VIEW_DROP_BEFORE and len ( path_dest ) == 2 - merge \
and path_dest [ 1 - merge ] == 0 : #droped before the first group
return
if position == gtk . TREE_VIEW_DROP_BEFORE and len ( path_dest ) == 2 - merge :
#droped before a group : we drop it in the previous group
path_dest = ( path_dest [ 1 - merge ] , path_dest [ 1 - merge ] - 1 )
iter_dest = model . get_iter ( path_dest )
iter_source = treeview . get_selection ( ) . get_selected ( ) [ 1 ]
path_source = model . get_path ( iter_source )
if len ( path_dest ) == 1 and not merge : #droped on an account
return
if path_dest [ 0 ] != path_source [ 0 ] and not merge :
#droped in another account
return
iter_group_source = model . iter_parent ( iter_source )
2005-09-12 23:56:50 +02:00
grp_source = model [ iter_group_source ] [ C_JID ] . decode ( ' utf-8 ' )
2005-07-07 19:33:15 +02:00
if grp_source == _ ( ' Transports ' ) or grp_source == _ ( ' not in the roster ' ) :
2005-06-12 17:14:07 +02:00
return
2005-09-12 23:56:50 +02:00
account = model [ iter_dest ] [ C_ACCOUNT ] . decode ( ' utf-8 ' )
type_dest = model . get_value ( iter_dest , C_TYPE )
2005-06-12 17:14:07 +02:00
if type_dest == ' group ' :
2005-09-12 23:56:50 +02:00
grp_dest = model [ iter_dest ] [ C_JID ] . decode ( ' utf-8 ' )
2005-06-12 17:14:07 +02:00
else :
2005-09-12 23:56:50 +02:00
grp_dest = model [ model . iter_parent ( iter_dest ) ] [ C_JID ] . decode ( ' utf-8 ' )
2005-06-12 17:14:07 +02:00
if grp_source == grp_dest :
return
# We upgrade only the first user because user2.groups is a pointer to
# user1.groups
2005-07-18 23:08:31 +02:00
u = gajim . contacts [ account ] [ data ] [ 0 ]
2005-11-01 23:52:04 +01:00
if context . action != gtk . gdk . ACTION_COPY :
u . groups . remove ( grp_source )
if model . iter_n_children ( iter_group_source ) == 1 :
# this was the only child
model . remove ( iter_group_source )
# delete the group if it is empty (need to look for offline users too)
for jid in gajim . contacts [ account ] :
if grp_source in gajim . contacts [ account ] [ jid ] [ 0 ] . groups :
break
else :
del gajim . groups [ account ] [ grp_source ]
2005-06-12 17:14:07 +02:00
if not grp_dest in u . groups :
u . groups . append ( grp_dest )
2005-07-07 18:38:36 +02:00
self . add_contact_to_roster ( data , account )
2005-07-18 16:52:28 +02:00
gajim . connections [ account ] . update_contact ( u . jid , u . name , u . groups )
2005-11-01 23:52:04 +01:00
if context . action in ( gtk . gdk . ACTION_MOVE , gtk . gdk . ACTION_COPY ) :
2005-06-12 17:14:07 +02:00
context . finish ( True , True , etime )
return
def show_title ( self ) :
change_title_allowed = gajim . config . get ( ' change_roster_title ' )
if change_title_allowed :
start = ' '
if self . nb_unread > 1 :
2005-09-04 18:57:09 +02:00
start = ' [ ' + str ( self . nb_unread ) + ' ] '
2005-06-12 17:14:07 +02:00
elif self . nb_unread == 1 :
start = ' * '
self . window . set_title ( start + ' Gajim ' )
2005-09-04 18:57:09 +02:00
gtkgui_helpers . set_unset_urgency_hint ( self . window , self . nb_unread )
2005-06-12 17:14:07 +02:00
2005-10-09 22:28:04 +02:00
def iter_is_separator ( self , model , iter ) :
2005-10-10 00:24:18 +02:00
if model [ iter ] [ 0 ] == ' SEPARATOR ' :
2005-10-09 22:28:04 +02:00
return True
return False
2005-11-07 11:50:40 +01:00
def iter_contact_rows ( self ) :
''' iterate over all contact rows in the tree model '''
model = self . tree . get_model ( )
account_iter = model . get_iter_root ( )
while account_iter :
group_iter = model . iter_children ( account_iter )
while group_iter :
contact_iter = model . iter_children ( group_iter )
while contact_iter :
yield model [ contact_iter ]
contact_iter = model . iter_next ( contact_iter )
group_iter = model . iter_next ( group_iter )
account_iter = model . iter_next ( account_iter )
def _on_treeview_style_set ( self , treeview , style ) :
''' When style (theme) changes, redraw all contacts '''
for contact in self . iter_contact_rows ( ) :
self . draw_contact ( contact [ C_JID ] , contact [ C_ACCOUNT ] )
def _on_treeview_selection_changed ( self , selection ) :
model , selected_iter = selection . get_selected ( )
if self . _last_selected_contact is not None :
# update unselected row
jid , account = self . _last_selected_contact
self . draw_contact ( jid , account )
if selected_iter is None :
self . _last_selected_contact = None
return
contact = model [ selected_iter ]
self . _last_selected_contact = ( contact [ C_JID ] , contact [ C_ACCOUNT ] )
if contact [ C_TYPE ] != ' contact ' :
return
self . draw_contact ( contact [ C_JID ] , contact [ C_ACCOUNT ] , selected = True )
2005-10-20 13:17:17 +02:00
def __init__ ( self ) :
2005-06-12 17:14:07 +02:00
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' roster_window ' , APP )
self . window = self . xml . get_widget ( ' roster_window ' )
self . tree = self . xml . get_widget ( ' roster_treeview ' )
2005-11-07 11:50:40 +01:00
self . tree . get_selection ( ) . connect ( ' changed ' ,
self . _on_treeview_selection_changed )
self . tree . connect ( ' style-set ' , self . _on_treeview_style_set )
self . _last_selected_contact = None # None or holds jid, account tupple
2005-06-12 17:14:07 +02:00
self . nb_unread = 0
2005-07-30 16:40:58 +02:00
self . last_save_dir = None
2005-07-23 00:50:25 +02:00
self . editing_path = None # path of row with cell in edit mode
2005-06-12 17:14:07 +02:00
self . add_new_contact_handler_id = False
self . service_disco_handler_id = False
self . new_message_menuitem_handler_id = False
self . regroup = gajim . config . get ( ' mergeaccounts ' )
2005-07-05 22:47:25 +02:00
#FIXME: When list_accel_closures will be wrapped in pygtk
# no need of this variable
self . have_new_message_accel = False # Is the "Ctrl+N" shown ?
2005-06-12 17:14:07 +02:00
if gajim . config . get ( ' saveposition ' ) :
2005-10-26 18:40:59 +02:00
gtkgui_helpers . move_window ( self . window ,
gajim . config . get ( ' roster_x-position ' ) ,
2005-08-28 12:57:08 +02:00
gajim . config . get ( ' roster_y-position ' ) )
2005-10-26 18:40:59 +02:00
gtkgui_helpers . resize_window ( self . window ,
gajim . config . get ( ' roster_width ' ) ,
2005-07-21 23:19:08 +02:00
gajim . config . get ( ' roster_height ' ) )
2005-06-21 16:45:23 +02:00
2005-06-12 17:14:07 +02:00
self . popups_notification_height = 0
self . popup_notification_windows = [ ]
self . gpg_passphrase = { }
2005-11-06 15:30:17 +01:00
2005-06-29 14:57:46 +02:00
#(icon, name, type, jid, account, editable, secondary_pixbuf)
model = gtk . TreeStore ( gtk . Image , str , str , str , str , bool , gtk . gdk . Pixbuf )
2005-11-06 15:30:17 +01:00
2005-06-12 17:14:07 +02:00
model . set_sort_func ( 1 , self . compareIters )
model . set_sort_column_id ( 1 , gtk . SORT_ASCENDING )
self . tree . set_model ( model )
self . make_jabber_state_images ( )
2005-06-29 14:57:46 +02:00
self . transports_state_images = { ' aim ' : { } , ' gadugadu ' : { } , ' irc ' : { } ,
2005-08-30 00:24:13 +02:00
' icq ' : { } , ' msn ' : { } , ' sms ' : { } , ' weather ' : { } , ' yahoo ' : { } }
2005-06-12 17:14:07 +02:00
path = os . path . join ( gajim . DATA_DIR , ' iconsets/transports ' )
folders = os . listdir ( path )
for transport in folders :
if transport == ' .svn ' :
continue
folder = os . path . join ( path , transport )
2005-06-29 14:57:46 +02:00
self . transports_state_images [ transport ] = self . load_iconset (
2005-08-30 00:24:13 +02:00
folder + ' /16x16/ ' )
2005-06-12 17:14:07 +02:00
2005-10-10 23:45:59 +02:00
# uf_show, img, show, sensitive
liststore = gtk . ListStore ( str , gtk . Image , str , bool )
2005-06-21 16:45:23 +02:00
self . status_combobox = self . xml . get_widget ( ' status_combobox ' )
2005-10-09 22:28:04 +02:00
2005-06-12 17:14:07 +02:00
cell = cell_renderer_image . CellRendererImage ( )
self . status_combobox . pack_start ( cell , False )
2005-10-26 18:40:59 +02:00
# img to show is in in 2nd column of liststore
2005-06-12 17:14:07 +02:00
self . status_combobox . add_attribute ( cell , ' image ' , 1 )
2005-10-26 18:40:59 +02:00
# if it will be sensitive or not it is in the fourth column
# all items in the 'row' must have sensitive to False
# if we want False (so we add it for img_cell too)
self . status_combobox . add_attribute ( cell , ' sensitive ' , 3 )
2005-10-09 22:28:04 +02:00
2005-06-12 17:14:07 +02:00
cell = gtk . CellRendererText ( )
cell . set_property ( ' xpad ' , 5 ) # padding for status text
self . status_combobox . pack_start ( cell , True )
2005-10-10 23:45:59 +02:00
# text to show is in in first column of liststore
2005-06-12 17:14:07 +02:00
self . status_combobox . add_attribute ( cell , ' text ' , 0 )
2005-10-10 23:45:59 +02:00
# if it will be sensitive or not it is in the fourth column
self . status_combobox . add_attribute ( cell , ' sensitive ' , 3 )
2005-06-12 17:14:07 +02:00
2005-10-09 22:28:04 +02:00
self . status_combobox . set_row_separator_func ( self . iter_is_separator )
2005-10-27 15:15:03 +02:00
for show in ( ' online ' , ' chat ' , ' away ' , ' xa ' , ' dnd ' , ' invisible ' ) :
2005-06-12 17:14:07 +02:00
uf_show = helpers . get_uf_show ( show )
2005-10-10 23:45:59 +02:00
liststore . append ( [ uf_show , self . jabber_state_images [ show ] , show , True ] )
2005-10-10 00:24:18 +02:00
# Add a Separator (self.iter_is_separator() checks on string SEPARATOR)
2005-10-10 23:45:59 +02:00
liststore . append ( [ ' SEPARATOR ' , None , ' ' , True ] )
2005-10-09 22:28:04 +02:00
2005-10-09 22:57:32 +02:00
path = os . path . join ( gajim . DATA_DIR , ' pixmaps ' , ' rename.png ' )
img = gtk . Image ( )
img . set_from_file ( path )
2005-10-10 23:45:59 +02:00
# sensitivity to False because by default we're offline
self . status_message_menuitem_iter = liststore . append (
[ _ ( ' Change Status Message... ' ) , img , ' ' , False ] )
2005-10-19 13:13:41 +02:00
# Add a Separator (self.iter_is_separator() checks on string SEPARATOR)
2005-10-10 23:45:59 +02:00
liststore . append ( [ ' SEPARATOR ' , None , ' ' , True ] )
2005-10-09 22:28:04 +02:00
uf_show = helpers . get_uf_show ( ' offline ' )
liststore . append ( [ uf_show , self . jabber_state_images [ ' offline ' ] ,
2005-10-10 23:45:59 +02:00
' offline ' , True ] )
2005-10-19 13:03:01 +02:00
status_combobox_items = [ ' online ' , ' chat ' , ' away ' , ' xa ' , ' dnd ' , ' invisible ' ,
' separator1 ' , ' change_status_msg ' , ' separator2 ' , ' offline ' ]
2005-06-12 17:14:07 +02:00
self . status_combobox . set_model ( liststore )
2005-10-19 13:03:01 +02:00
# default to offline
number_of_menuitem = status_combobox_items . index ( ' offline ' )
self . status_combobox . set_active ( number_of_menuitem )
# holds index to previously selected item so if "change status message..."
# is selected we can fallback to previously selected item and not stay
# with that item selected
self . previous_status_combobox_active = number_of_menuitem
2005-06-12 17:14:07 +02:00
showOffline = gajim . config . get ( ' showoffline ' )
2005-07-07 18:38:36 +02:00
self . xml . get_widget ( ' show_offline_contacts_menuitem ' ) . set_active (
showOffline )
2005-06-12 17:14:07 +02:00
2005-10-10 23:45:59 +02:00
# columns
2005-06-12 17:14:07 +02:00
2005-10-10 23:45:59 +02:00
# this col has two cells: first one img, second one text
2005-06-12 17:14:07 +02:00
col = gtk . TreeViewColumn ( )
2005-06-29 14:57:46 +02:00
render_image = cell_renderer_image . CellRendererImage ( ) # show img or +-
col . pack_start ( render_image , expand = False )
2005-09-19 17:23:18 +02:00
col . add_attribute ( render_image , ' image ' , C_IMG )
2005-06-29 14:57:46 +02:00
col . set_cell_data_func ( render_image , self . iconCellDataFunc , None )
2005-06-12 17:14:07 +02:00
2005-06-29 14:57:46 +02:00
render_text = gtk . CellRendererText ( ) # contact or group or account name
2005-06-12 17:14:07 +02:00
render_text . connect ( ' edited ' , self . on_cell_edited )
render_text . connect ( ' editing-canceled ' , self . on_editing_canceled )
2005-07-23 00:50:25 +02:00
render_text . connect ( ' editing-started ' , self . on_editing_started )
2005-06-12 17:14:07 +02:00
col . pack_start ( render_text , expand = True )
2005-11-06 15:30:17 +01:00
col . add_attribute ( render_text , ' markup ' , C_NAME ) # where we hold the name
2005-10-10 23:45:59 +02:00
col . add_attribute ( render_text , ' editable ' , C_EDITABLE ) # where we hold if the row is editable
2005-06-12 17:14:07 +02:00
col . set_cell_data_func ( render_text , self . nameCellDataFunc , None )
2005-06-29 14:57:46 +02:00
render_pixbuf = gtk . CellRendererPixbuf ( ) # tls or avatar img
col . pack_start ( render_pixbuf , expand = False )
2005-09-19 17:23:18 +02:00
col . add_attribute ( render_pixbuf , ' pixbuf ' , C_SECPIXBUF )
2005-06-29 14:57:46 +02:00
col . set_cell_data_func ( render_pixbuf , self . fill_secondary_pixbuf_rederer ,
None )
2005-06-12 17:14:07 +02:00
self . tree . append_column ( col )
#do not show gtk arrows workaround
col = gtk . TreeViewColumn ( )
render_pixbuf = gtk . CellRendererPixbuf ( )
col . pack_start ( render_pixbuf , expand = False )
self . tree . append_column ( col )
col . set_visible ( False )
self . tree . set_expander_column ( col )
#signals
TARGETS = [ ( ' MY_TREE_MODEL_ROW ' , gtk . TARGET_SAME_WIDGET , 0 ) ]
self . tree . enable_model_drag_source ( gtk . gdk . BUTTON1_MASK , TARGETS ,
2005-11-01 23:52:04 +01:00
gtk . gdk . ACTION_DEFAULT | gtk . gdk . ACTION_MOVE | gtk . gdk . ACTION_COPY )
2005-06-12 17:14:07 +02:00
self . tree . enable_model_drag_dest ( TARGETS , gtk . gdk . ACTION_DEFAULT )
self . tree . connect ( ' drag_data_get ' , self . drag_data_get_data )
self . tree . connect ( ' drag_data_received ' , self . drag_data_received_data )
self . xml . signal_autoconnect ( self )
2005-11-05 19:09:57 +01:00
self . combobox_callback_active = True
2005-06-12 17:14:07 +02:00
self . collapsed_rows = gajim . config . get ( ' collapsed_rows ' ) . split ( ' \t ' )
2005-10-20 13:17:17 +02:00
self . tooltip = tooltips . RosterTooltip ( )
2005-07-07 17:41:03 +02:00
self . make_menu ( )
2005-06-12 17:14:07 +02:00
self . draw_roster ( )
2005-06-21 16:45:23 +02:00
if gajim . config . get ( ' show_roster_on_startup ' ) :
self . window . show_all ( )
else :
if not gajim . config . get ( ' trayicon ' ) :
# cannot happen via GUI, but I put this incase user touches config
self . window . show_all ( ) # without trayicon, he should see the roster!
gajim . config . set ( ' show_roster_on_startup ' , True )
2005-07-21 16:56:39 +02:00
if len ( gajim . connections ) == 0 : # if we have no account
2005-10-20 13:17:17 +02:00
gajim . interface . windows [ ' wizard_window ' ] = \
2005-11-03 10:27:45 +01:00
config . AccountCreationWizardWindow ( )