2005-04-18 16:05:30 +02:00
## dialogs.py
2004-05-15 18:50:38 +02:00
##
## Gajim Team:
2005-03-29 18:37:59 +02:00
## - Yann Le Boulanger <asterix@lagaule.org>
## - Vincent Hanquez <tab@snarc.org>
## - Nikos Kouremenos <kourem@gmail.com>
2005-07-30 16:14:10 +02:00
## - Dimitur Kirov <dkirov@gmail.com>
2004-05-15 18:50:38 +02:00
##
2005-01-07 22:52:38 +01:00
## Copyright (C) 2003-2005 Gajim Team
2004-05-15 18:50:38 +02:00
##
## 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
2005-03-01 14:46:22 +01:00
import gtk . glade
import gobject
2005-05-17 19:37:50 +02:00
import os
2005-05-20 17:58:23 +02:00
2005-07-21 23:42:53 +02:00
import gtkgui_helpers
2005-07-21 23:39:47 +02:00
2005-06-11 00:45:50 +02:00
from vcard import VcardWindow
2005-06-10 00:29:06 +02:00
from gajim_themes_window import GajimThemesWindow
2005-06-11 00:45:50 +02:00
from advanced import AdvancedConfigurationWindow
2005-06-24 16:28:00 +02:00
from gajim import Contact
2005-04-14 09:05:10 +02:00
from common import gajim
2004-05-17 01:47:14 +02:00
from common import i18n
2005-06-06 13:53:07 +02:00
from common import helpers
2005-05-20 17:58:23 +02:00
2004-05-17 01:47:14 +02:00
_ = i18n . _
APP = i18n . APP
gtk . glade . bindtextdomain ( APP , i18n . DIR )
gtk . glade . textdomain ( APP )
2004-05-15 18:50:38 +02:00
2005-04-22 01:20:18 +02:00
GTKGUI_GLADE = ' gtkgui.glade '
2004-05-15 18:50:38 +02:00
2005-06-10 23:14:16 +02:00
class EditGroupsDialog :
2005-04-18 14:17:43 +02:00
''' Class for the edit group dialog window '''
2005-03-17 18:41:09 +01:00
def __init__ ( self , user , account , plugin ) :
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' edit_groups_dialog ' , APP )
self . dialog = self . xml . get_widget ( ' edit_groups_dialog ' )
self . plugin = plugin
self . account = account
self . user = user
2005-04-17 23:31:18 +02:00
self . changes_made = False
2005-03-17 18:41:09 +01:00
self . list = self . xml . get_widget ( ' groups_treeview ' )
2005-05-19 19:47:40 +02:00
self . xml . get_widget ( ' nickname_label ' ) . set_markup (
_ ( " Contact ' s name: <i> %s </i> " ) % user . name )
self . xml . get_widget ( ' jid_label ' ) . set_markup (
2005-03-18 01:47:50 +01:00
_ ( ' JID: <i> %s </i> ' ) % user . jid )
2005-07-23 00:32:45 +02:00
2005-03-17 18:41:09 +01:00
self . xml . signal_autoconnect ( self )
self . init_list ( )
def run ( self ) :
2005-07-23 00:32:45 +02:00
self . dialog . show_all ( )
2005-04-17 23:31:18 +02:00
if self . changes_made :
2005-07-18 16:52:28 +02:00
gajim . connections [ self . account ] . update_contact ( self . user . jid ,
2005-04-17 23:31:18 +02:00
self . user . name , self . user . groups )
2005-03-17 18:41:09 +01:00
2005-07-23 00:32:45 +02:00
def on_edit_groups_dialog_response ( self , widget , response_id ) :
if response_id == gtk . RESPONSE_CLOSE :
self . dialog . destroy ( )
2005-07-18 16:52:28 +02:00
def update_contact ( self ) :
2005-07-21 19:54:58 +02:00
self . plugin . roster . remove_contact ( self . user , self . account )
2005-07-07 18:38:36 +02:00
self . plugin . roster . add_contact_to_roster ( self . user . jid , self . account )
2005-08-01 21:33:22 +02:00
gajim . connections [ self . account ] . update_contact ( self . user . jid ,
self . user . name , self . user . groups )
2005-03-17 18:41:09 +01:00
def on_add_button_clicked ( self , widget ) :
group = self . xml . get_widget ( ' group_entry ' ) . get_text ( )
if not group :
return
# check if it already exists
model = self . list . get_model ( )
iter = model . get_iter_root ( )
while iter :
if model . get_value ( iter , 0 ) == group :
return
iter = model . iter_next ( iter )
2005-05-23 19:21:05 +02:00
self . changes_made = True
2005-03-17 18:41:09 +01:00
model . append ( ( group , True ) )
self . user . groups . append ( group )
2005-07-18 16:52:28 +02:00
self . update_contact ( )
2005-03-17 18:41:09 +01:00
def group_toggled_cb ( self , cell , path ) :
2005-04-17 23:31:18 +02:00
self . changes_made = True
2005-03-17 18:41:09 +01:00
model = self . list . get_model ( )
if model [ path ] [ 1 ] and len ( self . user . groups ) == 1 : # we try to remove
2005-05-18 14:34:20 +02:00
# the last group
2005-08-02 00:48:58 +02:00
ErrorDialog ( _ ( ' Cannot remove last group ' ) ,
2005-06-07 03:10:24 +02:00
_ ( ' At least one contact group must be present. ' ) ) . get_response ( )
2005-03-17 18:41:09 +01:00
return
model [ path ] [ 1 ] = not model [ path ] [ 1 ]
if model [ path ] [ 1 ] :
self . user . groups . append ( model [ path ] [ 0 ] )
else :
self . user . groups . remove ( model [ path ] [ 0 ] )
2005-07-18 16:52:28 +02:00
self . update_contact ( )
2005-03-17 18:41:09 +01:00
def init_list ( self ) :
2005-06-18 15:48:43 +02:00
store = gtk . ListStore ( str , bool )
2005-03-17 18:41:09 +01:00
self . list . set_model ( store )
2005-07-18 23:08:31 +02:00
for g in gajim . groups [ self . account ] . keys ( ) :
2005-07-07 19:33:15 +02:00
if g in [ _ ( ' Transports ' ) , _ ( ' not in the roster ' ) ] :
2005-06-01 22:47:01 +02:00
continue
2005-03-17 18:41:09 +01:00
iter = store . append ( )
store . set ( iter , 0 , g )
if g in self . user . groups :
store . set ( iter , 1 , True )
else :
store . set ( iter , 1 , False )
column = gtk . TreeViewColumn ( _ ( ' Group ' ) )
self . list . append_column ( column )
renderer = gtk . CellRendererText ( )
column . pack_start ( renderer )
2005-04-22 01:20:18 +02:00
column . set_attributes ( renderer , text = 0 )
2005-03-17 18:41:09 +01:00
column = gtk . TreeViewColumn ( _ ( ' In the group ' ) )
self . list . append_column ( column )
renderer = gtk . CellRendererToggle ( )
column . pack_start ( renderer )
renderer . set_property ( ' activatable ' , True )
renderer . connect ( ' toggled ' , self . group_toggled_cb )
2005-04-22 01:20:18 +02:00
column . set_attributes ( renderer , active = 1 )
2005-03-17 18:41:09 +01:00
2005-06-10 23:14:16 +02:00
class PassphraseDialog :
2005-04-18 14:17:43 +02:00
''' Class for Passphrase dialog '''
2004-10-07 16:43:59 +02:00
def run ( self ) :
2005-04-18 14:17:43 +02:00
''' Wait for OK button to be pressed and return passphrase/password '''
2005-03-02 11:46:12 +01:00
rep = self . window . run ( )
2004-10-07 16:43:59 +02:00
if rep == gtk . RESPONSE_OK :
2005-03-02 11:46:12 +01:00
passphrase = self . passphrase_entry . get_text ( )
2004-10-07 16:43:59 +02:00
else :
2005-03-02 11:46:12 +01:00
passphrase = - 1
save_passphrase_checkbutton = self . xml . \
get_widget ( ' save_passphrase_checkbutton ' )
self . window . destroy ( )
2005-03-15 11:20:10 +01:00
return passphrase , save_passphrase_checkbutton . get_active ( )
2004-12-02 01:00:57 +01:00
2005-06-03 12:28:53 +02:00
def __init__ ( self , titletext , labeltext , checkbuttontext ) :
2005-03-02 11:46:12 +01:00
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' passphrase_dialog ' , APP )
self . window = self . xml . get_widget ( ' passphrase_dialog ' )
self . passphrase_entry = self . xml . get_widget ( ' passphrase_entry ' )
self . passphrase = - 1
2005-06-03 12:28:53 +02:00
self . window . set_title ( titletext )
2005-03-02 13:38:33 +01:00
self . xml . get_widget ( ' message_label ' ) . set_text ( labeltext )
2005-07-23 00:49:03 +02:00
self . xml . get_widget ( ' save_passphrase_checkbutton ' ) . set_label (
checkbuttontext )
2005-03-02 11:46:12 +01:00
self . xml . signal_autoconnect ( self )
2005-04-04 17:51:29 +02:00
self . window . show_all ( )
2004-05-15 18:50:38 +02:00
2005-06-08 15:45:30 +02:00
class ChooseGPGKeyDialog :
2005-04-18 14:17:43 +02:00
''' Class for GPG key dialog '''
2005-06-08 15:45:30 +02:00
def __init__ ( self , title_text , prompt_text , secret_keys , selected = None ) :
2004-10-10 20:44:38 +02:00
#list : {keyID: userName, ...}
2005-03-02 12:46:51 +01:00
xml = gtk . glade . XML ( GTKGUI_GLADE , ' choose_gpg_key_dialog ' , APP )
self . window = xml . get_widget ( ' choose_gpg_key_dialog ' )
2005-06-08 15:45:30 +02:00
self . window . set_title ( title_text )
2005-03-02 12:46:51 +01:00
self . keys_treeview = xml . get_widget ( ' keys_treeview ' )
2005-06-08 15:45:30 +02:00
prompt_label = xml . get_widget ( ' prompt_label ' )
prompt_label . set_text ( prompt_text )
2005-06-18 15:48:43 +02:00
model = gtk . ListStore ( str , str )
2005-03-02 12:46:51 +01:00
self . keys_treeview . set_model ( model )
2004-10-10 20:44:38 +02:00
#columns
renderer = gtk . CellRendererText ( )
2005-05-19 19:47:40 +02:00
self . keys_treeview . insert_column_with_attributes ( - 1 , _ ( ' KeyID ' ) ,
2005-04-22 01:20:18 +02:00
renderer , text = 0 )
2004-10-10 20:44:38 +02:00
renderer = gtk . CellRendererText ( )
2005-06-24 16:28:00 +02:00
self . keys_treeview . insert_column_with_attributes ( - 1 , _ ( ' Contact name ' ) ,
2005-04-22 01:20:18 +02:00
renderer , text = 1 )
2005-05-29 23:34:01 +02:00
self . fill_tree ( secret_keys , selected )
2005-04-04 17:51:29 +02:00
self . window . show_all ( )
2005-08-02 18:27:25 +02:00
def run ( self ) :
rep = self . window . run ( )
if rep == gtk . RESPONSE_OK :
2005-07-23 00:49:03 +02:00
selection = self . keys_treeview . get_selection ( )
( model , iter ) = selection . get_selected ( )
2005-08-02 18:27:25 +02:00
keyID = [ model [ iter ] [ 0 ] , model [ iter ] [ 1 ] ]
else :
keyID = None
2005-07-23 00:49:03 +02:00
self . window . destroy ( )
2005-08-02 18:27:25 +02:00
return keyID
2005-07-23 00:49:03 +02:00
def fill_tree ( self , list , selected ) :
model = self . keys_treeview . get_model ( )
for keyID in list . keys ( ) :
iter = model . append ( ( keyID , list [ keyID ] ) )
if keyID == selected :
path = model . get_path ( iter )
self . keys_treeview . set_cursor ( path )
2005-06-10 23:14:16 +02:00
class ChangeStatusMessageDialog :
2005-05-20 18:31:52 +02:00
def __init__ ( self , plugin , show ) :
2005-06-30 21:23:41 +02:00
self . show = show
2005-04-04 18:46:35 +02:00
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' change_status_message_dialog ' , APP )
self . window = self . xml . get_widget ( ' change_status_message_dialog ' )
2005-05-20 18:31:52 +02:00
uf_show = helpers . get_uf_show ( show )
2005-06-03 17:38:06 +02:00
self . window . set_title ( _ ( ' %s Status Message ' ) % uf_show )
2005-05-12 11:14:31 +02:00
2005-04-04 18:46:35 +02:00
message_textview = self . xml . get_widget ( ' message_textview ' )
self . message_buffer = message_textview . get_buffer ( )
2005-06-30 21:23:41 +02:00
msg = gajim . config . get ( ' last_status_msg_ ' + show )
if not msg :
msg = ' '
2005-07-02 14:43:36 +02:00
msg = helpers . from_one_line ( msg )
2005-06-30 21:23:41 +02:00
self . message_buffer . set_text ( msg )
2005-06-06 13:53:07 +02:00
self . values = { ' ' : ' ' } # have an empty string selectable, so user can clear msg
2005-04-16 19:36:27 +02:00
for msg in gajim . config . get_per ( ' statusmsg ' ) :
self . values [ msg ] = gajim . config . get_per ( ' statusmsg ' , msg , ' message ' )
2005-06-06 13:53:07 +02:00
sorted_keys_list = helpers . get_sorted_keys ( self . values )
2005-04-04 18:46:35 +02:00
liststore = gtk . ListStore ( str , str )
message_comboboxentry = self . xml . get_widget ( ' message_comboboxentry ' )
message_comboboxentry . set_model ( liststore )
message_comboboxentry . set_text_column ( 0 )
2005-07-21 22:55:00 +02:00
message_comboboxentry . child . set_property ( ' editable ' , False )
2005-06-06 13:53:07 +02:00
for val in sorted_keys_list :
2005-04-04 18:46:35 +02:00
message_comboboxentry . append_text ( val )
self . xml . signal_autoconnect ( self )
self . window . show_all ( )
2004-05-15 18:50:38 +02:00
def run ( self ) :
2005-05-19 19:47:40 +02:00
''' Wait for OK button to be pressed and return status messsage '''
2005-03-02 13:46:37 +01:00
rep = self . window . run ( )
2004-05-15 18:50:38 +02:00
if rep == gtk . RESPONSE_OK :
2005-03-02 13:46:37 +01:00
beg , end = self . message_buffer . get_bounds ( )
2005-06-04 20:06:03 +02:00
message = self . message_buffer . get_text ( beg , end , 0 ) . strip ( )
2005-07-02 14:43:36 +02:00
msg = helpers . to_one_line ( message )
gajim . config . set ( ' last_status_msg_ ' + self . show , msg )
2004-05-15 18:50:38 +02:00
else :
2005-03-02 13:46:37 +01:00
message = - 1
self . window . destroy ( )
return message
2004-10-26 00:02:16 +02:00
2005-04-22 01:20:18 +02:00
def on_message_comboboxentry_changed ( self , widget , data = None ) :
2004-10-26 00:02:16 +02:00
model = widget . get_model ( )
active = widget . get_active ( )
if active < 0 :
return None
name = model [ active ] [ 0 ]
2005-03-02 13:46:37 +01:00
self . message_buffer . set_text ( self . values [ name ] )
2004-05-15 18:50:38 +02:00
2005-03-16 02:27:37 +01:00
def on_change_status_message_dialog_key_press_event ( self , widget , event ) :
2005-03-18 02:28:59 +01:00
if event . keyval == gtk . keysyms . Return or \
2005-03-18 02:25:11 +01:00
event . keyval == gtk . keysyms . KP_Enter : # catch CTRL+ENTER
2005-01-08 15:40:08 +01:00
if ( event . state & gtk . gdk . CONTROL_MASK ) :
2005-03-02 13:46:37 +01:00
self . window . response ( gtk . RESPONSE_OK )
2005-04-04 18:46:35 +02:00
2005-06-10 23:14:16 +02:00
class AddNewContactWindow :
''' Class for AddNewContactWindow '''
2005-04-22 01:20:18 +02:00
def __init__ ( self , plugin , account , jid = None ) :
2004-10-26 00:02:16 +02:00
self . plugin = plugin
2005-04-04 18:46:35 +02:00
self . account = account
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' add_new_contact_window ' , APP )
self . window = self . xml . get_widget ( ' add_new_contact_window ' )
2005-05-04 19:44:49 +02:00
self . uid_entry = self . xml . get_widget ( ' uid_entry ' )
self . protocol_combobox = self . xml . get_widget ( ' protocol_combobox ' )
self . jid_entry = self . xml . get_widget ( ' jid_entry ' )
self . nickname_entry = self . xml . get_widget ( ' nickname_entry ' )
2005-06-13 15:19:54 +02:00
if len ( gajim . connections ) > = 2 :
prompt_text = \
_ ( ' Please fill in the data of the contact you want to add in account %s ' ) % account
else :
prompt_text = _ ( ' Please fill in the data of the contact you want to add ' )
self . xml . get_widget ( ' prompt_label ' ) . set_text ( prompt_text )
2005-04-04 18:46:35 +02:00
self . old_uid_value = ' '
2005-06-13 15:19:54 +02:00
liststore = gtk . ListStore ( str , str )
2005-04-04 18:46:35 +02:00
liststore . append ( [ ' Jabber ' , ' ' ] )
self . agents = [ ' Jabber ' ]
jid_agents = [ ]
2005-07-18 23:08:31 +02:00
for j in gajim . contacts [ account ] :
user = gajim . contacts [ account ] [ j ] [ 0 ]
2005-07-07 19:25:04 +02:00
if _ ( ' Transports ' ) in user . groups and user . show != ' offline ' and \
2005-05-25 13:00:41 +02:00
user . show != ' error ' :
2005-04-04 18:46:35 +02:00
jid_agents . append ( j )
for a in jid_agents :
if a . find ( ' aim ' ) > - 1 :
name = ' AIM '
elif a . find ( ' icq ' ) > - 1 :
name = ' ICQ '
elif a . find ( ' msn ' ) > - 1 :
name = ' MSN '
elif a . find ( ' yahoo ' ) > - 1 :
name = ' Yahoo! '
else :
name = a
iter = liststore . append ( [ name , a ] )
self . agents . append ( name )
2005-05-04 19:44:49 +02:00
self . protocol_combobox . set_model ( liststore )
self . protocol_combobox . set_active ( 0 )
2005-04-04 18:46:35 +02:00
self . fill_jid ( )
if jid :
2005-05-04 19:44:49 +02:00
self . jid_entry . set_text ( jid )
2005-04-04 18:46:35 +02:00
jid_splited = jid . split ( ' @ ' )
if jid_splited [ 1 ] in jid_agents :
2005-04-25 22:41:29 +02:00
uid = jid_splited [ 0 ] . replace ( ' % ' , ' @ ' )
2005-05-04 19:44:49 +02:00
self . uid_entry . set_text ( uid )
self . protocol_combobox . set_active ( jid_agents . index ( jid_splited [ 1 ] ) + 1 )
2005-04-25 22:41:29 +02:00
else :
2005-05-04 19:44:49 +02:00
self . uid_entry . set_text ( jid )
self . protocol_combobox . set_active ( 0 )
2005-04-25 22:41:29 +02:00
self . set_nickname ( )
2005-04-04 18:46:35 +02:00
self . group_comboboxentry = self . xml . get_widget ( ' group_comboboxentry ' )
liststore = gtk . ListStore ( str )
self . group_comboboxentry . set_model ( liststore )
2005-07-18 23:08:31 +02:00
for g in gajim . groups [ account ] . keys ( ) :
2005-07-07 19:33:15 +02:00
if g != _ ( ' not in the roster ' ) and g != _ ( ' Transports ' ) :
2005-04-04 18:46:35 +02:00
self . group_comboboxentry . append_text ( g )
2005-03-02 13:46:37 +01:00
self . xml . signal_autoconnect ( self )
2005-04-04 17:51:29 +02:00
self . window . show_all ( )
2004-05-15 18:50:38 +02:00
2005-04-28 15:01:47 +02:00
def on_add_new_contact_window_key_press_event ( self , widget , event ) :
if event . keyval == gtk . keysyms . Escape : # ESCAPE
self . window . destroy ( )
2005-03-01 00:44:52 +01:00
def on_cancel_button_clicked ( self , widget ) :
2005-04-18 14:17:43 +02:00
''' When Cancel button is clicked '''
2005-04-12 17:30:09 +02:00
self . window . destroy ( )
2004-05-15 18:50:38 +02:00
2005-03-01 00:44:52 +01:00
def on_subscribe_button_clicked ( self , widget ) :
2005-04-18 14:17:43 +02:00
''' When Subscribe button is clicked '''
2005-05-04 19:44:49 +02:00
jid = self . jid_entry . get_text ( )
nickname = self . nickname_entry . get_text ( )
2005-03-01 00:44:52 +01:00
if not jid :
2004-11-18 20:22:33 +01:00
return
2005-03-01 00:44:52 +01:00
if jid . find ( ' @ ' ) < 0 :
2005-06-10 23:14:16 +02:00
ErrorDialog ( _ ( " Invalid user name " ) ,
2005-06-24 16:28:00 +02:00
_ ( ' Contact names must be of the form " user@servername " . ' ) ) . get_response ( )
2004-11-18 20:22:33 +01:00
return
2005-03-01 00:44:52 +01:00
message_buffer = self . xml . get_widget ( ' message_textview ' ) . get_buffer ( )
start_iter = message_buffer . get_start_iter ( )
end_iter = message_buffer . get_end_iter ( )
message = message_buffer . get_text ( start_iter , end_iter , 0 )
2005-03-27 23:35:55 +02:00
group = self . group_comboboxentry . child . get_text ( )
2005-06-15 09:38:58 +02:00
self . plugin . roster . req_sub ( self , jid , message , self . account ,
group = group , pseudo = nickname )
2005-03-01 00:44:52 +01:00
if self . xml . get_widget ( ' auto_authorize_checkbutton ' ) . get_active ( ) :
2005-04-14 11:38:08 +02:00
gajim . connections [ self . account ] . send_authorization ( jid )
2005-04-12 17:30:09 +02:00
self . window . destroy ( )
2004-05-15 18:50:38 +02:00
2005-03-01 00:44:52 +01:00
def fill_jid ( self ) :
2005-05-04 19:44:49 +02:00
model = self . protocol_combobox . get_model ( )
index = self . protocol_combobox . get_active ( )
2005-06-04 15:33:38 +02:00
jid = self . uid_entry . get_text ( ) . strip ( )
2005-05-04 19:44:49 +02:00
if index > 0 : # it's not jabber but a transport
2005-03-01 00:44:52 +01:00
jid = jid . replace ( ' @ ' , ' % ' )
2005-02-03 23:21:55 +01:00
agent = model [ index ] [ 1 ]
if agent :
2005-03-01 00:44:52 +01:00
jid + = ' @ ' + agent
2005-05-04 19:44:49 +02:00
self . jid_entry . set_text ( jid )
2005-02-03 23:21:55 +01:00
2005-03-23 14:25:48 +01:00
def on_protocol_combobox_changed ( self , widget ) :
2005-03-01 00:44:52 +01:00
self . fill_jid ( )
2005-02-03 23:21:55 +01:00
def guess_agent ( self ) :
2005-05-04 19:44:49 +02:00
uid = self . uid_entry . get_text ( )
model = self . protocol_combobox . get_model ( )
2005-02-03 23:21:55 +01:00
#If login contains only numbers, it's probably an ICQ number
2005-05-04 19:44:49 +02:00
if uid . isdigit ( ) :
2005-02-03 23:21:55 +01:00
if ' ICQ ' in self . agents :
2005-05-04 19:44:49 +02:00
self . protocol_combobox . set_active ( self . agents . index ( ' ICQ ' ) )
2005-02-03 23:21:55 +01:00
return
2005-02-04 08:58:40 +01:00
2005-03-01 00:44:52 +01:00
def set_nickname ( self ) :
2005-05-04 19:44:49 +02:00
uid = self . uid_entry . get_text ( )
nickname = self . nickname_entry . get_text ( )
2005-03-01 00:44:52 +01:00
if nickname == self . old_uid_value :
2005-05-04 19:44:49 +02:00
self . nickname_entry . set_text ( uid . split ( ' @ ' ) [ 0 ] )
2005-02-03 23:21:55 +01:00
2005-03-01 00:44:52 +01:00
def on_uid_entry_changed ( self , widget ) :
2005-05-04 19:44:49 +02:00
uid = self . uid_entry . get_text ( )
2005-02-04 08:58:40 +01:00
self . guess_agent ( )
2005-03-01 00:44:52 +01:00
self . set_nickname ( )
self . fill_jid ( )
self . old_uid_value = uid . split ( ' @ ' ) [ 0 ]
2004-05-15 18:50:38 +02:00
2005-06-10 01:28:07 +02:00
class AboutDialog :
2005-04-18 14:17:43 +02:00
''' Class for about dialog '''
2005-04-04 18:46:35 +02:00
def __init__ ( self ) :
2005-06-04 00:22:29 +02:00
if gtk . pygtk_version < ( 2 , 6 , 0 ) or gtk . gtk_version < ( 2 , 6 , 0 ) :
2005-06-10 23:14:16 +02:00
InformationDialog ( _ ( ' Gajim - a GTK+ Jabber client ' ) ,
2005-06-10 01:28:07 +02:00
_ ( ' Version %s ' ) % gajim . version ) . get_response ( )
2005-03-14 21:21:49 +01:00
return
2005-04-04 18:46:35 +02:00
2005-03-09 22:29:20 +01:00
dlg = gtk . AboutDialog ( )
dlg . set_name ( ' Gajim ' )
2005-04-16 19:03:21 +02:00
dlg . set_version ( gajim . version )
2005-03-16 03:16:29 +01:00
s = u ' Copyright \xa9 2003-2005 Gajim Team '
dlg . set_copyright ( s )
2005-04-16 19:03:21 +02:00
text = open ( ' ../COPYING ' ) . read ( )
2005-03-16 03:16:29 +01:00
dlg . set_license ( text )
2005-03-09 22:29:20 +01:00
2005-03-22 20:02:27 +01:00
dlg . set_comments ( _ ( ' A GTK jabber client ' ) )
2005-03-09 22:29:20 +01:00
dlg . set_website ( ' http://www.gajim.org ' )
2005-03-18 01:47:50 +01:00
2005-07-07 20:23:43 +02:00
authors = [ ' Yann Le Boulanger <asterix@lagaule.org> ' , ' Vincent Hanquez <tab@snarc.org> ' , ' Nikos Kouremenos <kourem@gmail.com> ' , ' Alex Podaras <bigpod@gmail.com> ' , ' Gajim patchers ' ]
2005-03-16 03:16:29 +01:00
dlg . set_authors ( authors )
2005-06-03 13:41:02 +02:00
2005-06-10 01:28:07 +02:00
pixbuf = gtk . gdk . pixbuf_new_from_file ( os . path . join ( gajim . DATA_DIR , ' pixmaps/gajim_about.png ' ) )
2005-06-03 13:41:02 +02:00
dlg . set_logo ( pixbuf )
2005-03-16 03:16:29 +01:00
dlg . set_translator_credits ( _ ( ' translator_credits ' ) )
2005-03-09 22:29:20 +01:00
2005-05-12 02:00:40 +02:00
rep = dlg . run ( )
2005-03-13 00:48:08 +01:00
dlg . destroy ( )
2004-05-15 18:50:38 +02:00
2005-06-07 03:10:24 +02:00
class Dialog ( gtk . Dialog ) :
2005-06-12 19:36:27 +02:00
def __init__ ( self , parent , title , buttons , default = None ) :
gtk . Dialog . __init__ ( self , title , parent , gtk . DIALOG_DESTROY_WITH_PARENT | gtk . DIALOG_MODAL | gtk . DIALOG_NO_SEPARATOR )
2005-06-07 03:10:24 +02:00
2005-06-12 19:36:27 +02:00
self . set_border_width ( 6 )
self . vbox . set_spacing ( 12 )
self . set_resizable ( False )
2005-06-07 03:10:24 +02:00
2005-06-12 19:36:27 +02:00
for stock , response in buttons :
self . add_button ( stock , response )
2005-06-07 03:10:24 +02:00
2005-06-12 19:36:27 +02:00
if default is not None :
self . set_default_response ( default )
else :
self . set_default_response ( buttons [ - 1 ] [ 1 ] )
2005-06-07 03:10:24 +02:00
2005-06-12 19:36:27 +02:00
def get_button ( self , index ) :
buttons = self . action_area . get_children ( )
return index < len ( buttons ) and buttons [ index ] or None
2005-06-07 03:10:24 +02:00
2005-06-10 00:29:06 +02:00
2005-06-07 03:10:24 +02:00
class HigDialog ( Dialog ) :
2005-06-12 19:36:27 +02:00
def __init__ ( self , parent , pritext , sectext , stockimage , buttons , default = None ) :
""" GNOME higified version of the Dialog object. Inherit
from here if possible when you need a new dialog . """
Dialog . __init__ ( self , parent , " " , buttons , default )
# hbox separating dialog image and contents
hbox = gtk . HBox ( )
hbox . set_spacing ( 12 )
hbox . set_border_width ( 6 )
self . vbox . pack_start ( hbox )
# set up image
if stockimage is not None :
image = gtk . Image ( )
image . set_from_stock ( stockimage , gtk . ICON_SIZE_DIALOG )
image . set_alignment ( 0.5 , 0 )
hbox . pack_start ( image , False , False )
# set up main content area
self . contents = gtk . VBox ( )
self . contents . set_spacing ( 10 )
hbox . pack_start ( self . contents )
label = gtk . Label ( )
label . set_markup ( " <span size= \" larger \" weight= \" bold \" > " + pritext + " </span> \n \n " + sectext )
label . set_line_wrap ( True )
label . set_alignment ( 0 , 0 )
label . set_selectable ( True )
self . contents . pack_start ( label )
def get_response ( self ) :
self . show_all ( )
response = gtk . Dialog . run ( self )
self . destroy ( )
return response
2005-06-07 03:10:24 +02:00
2005-06-10 23:14:16 +02:00
class ConfirmationDialog ( HigDialog ) :
2005-06-12 18:56:26 +02:00
""" HIG compliant confirmation dialog. """
def __init__ ( self , pritext , sectext = ' ' ) :
HigDialog . __init__ ( self , None , pritext , sectext ,
gtk . STOCK_DIALOG_WARNING , [ [ gtk . STOCK_CANCEL , gtk . RESPONSE_CANCEL ] ,
[ gtk . STOCK_OK , gtk . RESPONSE_OK ] ] )
2005-07-29 19:18:51 +02:00
class ConfirmationDialogCheck ( ConfirmationDialog ) :
''' HIG compliant confirmation dialog with checkbutton. '''
def __init__ ( self , pritext , sectext = ' ' , checktext = ' ' ) :
HigDialog . __init__ ( self , None , pritext , sectext ,
2005-07-30 02:27:58 +02:00
gtk . STOCK_DIALOG_WARNING , [ [ gtk . STOCK_CANCEL , gtk . RESPONSE_CANCEL ] ] )
2005-08-03 01:03:21 +02:00
2005-07-30 02:27:58 +02:00
# add ok button manually, because we need to focus on it
2005-08-03 01:03:21 +02:00
ok_button = self . add_button ( gtk . STOCK_OK , gtk . RESPONSE_OK )
2005-07-29 19:18:51 +02:00
self . checkbutton = gtk . CheckButton ( checktext )
self . vbox . pack_start ( self . checkbutton , expand = False , fill = True )
2005-07-30 02:27:58 +02:00
ok_button . grab_focus ( )
2005-07-29 19:18:51 +02:00
def is_checked ( self ) :
''' Get active state of the checkbutton '''
return self . checkbutton . get_active ( )
2005-06-10 23:14:16 +02:00
class WarningDialog ( HigDialog ) :
2005-06-12 19:36:27 +02:00
def __init__ ( self , pritext , sectext = ' ' ) :
""" HIG compliant warning dialog. """
HigDialog . __init__ (
self , None , pritext , sectext , gtk . STOCK_DIALOG_WARNING ,
[ [ gtk . STOCK_OK , gtk . RESPONSE_OK ] ]
)
2005-06-07 03:10:24 +02:00
2005-06-10 23:14:16 +02:00
class InformationDialog ( HigDialog ) :
2005-06-12 19:36:27 +02:00
def __init__ ( self , pritext , sectext = ' ' ) :
""" HIG compliant info dialog. """
HigDialog . __init__ (
self , None , pritext , sectext , gtk . STOCK_DIALOG_INFO ,
[ [ gtk . STOCK_OK , gtk . RESPONSE_OK ] ]
)
2005-07-31 21:21:11 +02:00
class BaseTooltip :
''' Base Tooltip . Usage:
tooltip = BaseTooltip ( )
. . . .
tooltip . show_tooltip ( ' ' , window_postions , widget_postions )
. . . .
if tooltip . timeout != 0 :
tooltip . hide_tooltip ( )
'''
def __init__ ( self ) :
2005-07-08 01:37:04 +02:00
self . timeout = 0
self . prefered_position = [ 0 , 0 ]
2005-07-31 21:21:11 +02:00
self . win = None
self . id = None
def populate ( self , data ) :
2005-08-02 01:17:53 +02:00
''' this method must be overriden by all extenders '''
2005-07-30 21:19:48 +02:00
self . create_window ( )
2005-07-31 21:21:11 +02:00
self . win . add ( gtk . Label ( data ) )
2005-07-18 13:03:53 +02:00
2005-07-30 21:19:48 +02:00
def create_window ( self ) :
''' create a popup window each time tooltip is requested '''
self . win = gtk . Window ( gtk . WINDOW_POPUP )
2005-07-31 21:21:11 +02:00
self . win . set_border_width ( 3 )
2005-07-30 21:19:48 +02:00
self . win . set_resizable ( False )
self . win . set_name ( ' gtk-tooltips ' )
2005-07-31 21:21:11 +02:00
2005-07-07 23:27:53 +02:00
2005-07-30 21:19:48 +02:00
self . win . set_events ( gtk . gdk . POINTER_MOTION_MASK )
self . win . connect_after ( ' expose_event ' , self . expose )
self . win . connect ( ' size-request ' , self . size_request )
self . win . connect ( ' motion-notify-event ' , self . motion_notify_event )
2005-07-20 19:50:50 +02:00
2005-07-07 23:27:53 +02:00
def motion_notify_event ( self , widget , event ) :
self . hide_tooltip ( )
def size_request ( self , widget , requisition ) :
2005-07-30 21:19:48 +02:00
screen = self . win . get_screen ( )
2005-07-07 23:27:53 +02:00
half_width = requisition . width / 2 + 1
if self . prefered_position [ 0 ] < half_width :
self . prefered_position [ 0 ] = 0
elif self . prefered_position [ 0 ] + requisition . width > screen . get_width ( ) \
+ half_width :
self . prefered_position [ 0 ] = screen . get_width ( ) - requisition . width
else :
self . prefered_position [ 0 ] - = half_width
2005-07-31 21:21:11 +02:00
screen . get_height ( )
2005-07-07 23:27:53 +02:00
if self . prefered_position [ 1 ] + requisition . height > screen . get_height ( ) :
2005-07-31 21:21:11 +02:00
# flip tooltip up
self . prefered_position [ 1 ] - = requisition . height + self . widget_height + 8
2005-07-07 23:27:53 +02:00
if self . prefered_position [ 1 ] < 0 :
self . prefered_position [ 1 ] = 0
2005-07-30 21:19:48 +02:00
self . win . move ( self . prefered_position [ 0 ] , self . prefered_position [ 1 ] )
2005-07-07 23:27:53 +02:00
def expose ( self , widget , event ) :
2005-07-30 21:19:48 +02:00
style = self . win . get_style ( )
size = self . win . get_size ( )
style . paint_flat_box ( self . win . window , gtk . STATE_NORMAL , gtk . SHADOW_OUT , None ,
self . win , ' tooltip ' , 0 , 0 , - 1 , 1 )
style . paint_flat_box ( self . win . window , gtk . STATE_NORMAL , gtk . SHADOW_OUT , None ,
self . win , ' tooltip ' , 0 , size [ 1 ] - 1 , - 1 , 1 )
style . paint_flat_box ( self . win . window , gtk . STATE_NORMAL , gtk . SHADOW_OUT , None ,
self . win , ' tooltip ' , 0 , 0 , 1 , - 1 )
style . paint_flat_box ( self . win . window , gtk . STATE_NORMAL , gtk . SHADOW_OUT , None ,
self . win , ' tooltip ' , size [ 0 ] - 1 , 0 , 1 , - 1 )
2005-07-07 23:27:53 +02:00
return True
2005-07-31 21:21:11 +02:00
def show_tooltip ( self , data , widget_pos , win_size ) :
self . populate ( data )
new_x = win_size [ 0 ] + widget_pos [ 0 ]
new_y = win_size [ 1 ] + widget_pos [ 1 ] + 4
2005-07-07 23:27:53 +02:00
self . prefered_position = [ new_x , new_y ]
2005-07-31 21:21:11 +02:00
self . widget_height = widget_pos [ 1 ]
2005-07-30 21:19:48 +02:00
self . win . ensure_style ( )
self . win . show_all ( )
2005-07-07 23:27:53 +02:00
def hide_tooltip ( self ) :
if ( self . timeout > 0 ) :
gobject . source_remove ( self . timeout )
2005-07-18 11:06:54 +02:00
self . timeout = 0
2005-07-31 21:21:11 +02:00
if self . win :
self . win . destroy ( )
self . win = None
self . id = None
class StatusTable :
''' Contains methods for creating status table. This
is used in Roster and NotificationArea tooltips '''
def __init__ ( self ) :
self . current_row = 1
self . table = None
self . text_lable = None
def create_table ( self ) :
self . table = gtk . Table ( 3 , 1 )
self . table . set_property ( ' column-spacing ' , 6 )
self . text_lable = gtk . Label ( )
self . text_lable . set_line_wrap ( True )
self . text_lable . set_alignment ( 0 , 0 )
self . text_lable . set_selectable ( False )
self . table . attach ( self . text_lable , 1 , 4 , 1 , 2 )
def get_status_info ( self , resource , priority , show , status ) :
2005-08-02 01:17:53 +02:00
str_status = resource + ' ( ' + str ( priority ) + ' ) '
2005-07-31 21:21:11 +02:00
if status :
status = status . strip ( )
if status != ' ' :
2005-08-01 18:14:35 +02:00
if gtk . gtk_version < ( 2 , 6 , 0 ) or gtk . pygtk_version < ( 2 , 6 , 0 ) :
# FIXME: check and do the same if we have more than one \n
status = self . strip_text ( status , 50 )
2005-07-31 21:21:11 +02:00
str_status + = ' - ' + status
return gtkgui_helpers . escape_for_pango_markup ( str_status )
2005-07-31 23:16:20 +02:00
2005-08-02 01:17:53 +02:00
# fix "too long status make the tooltip large than the screen" problem
2005-07-31 23:16:20 +02:00
def strip_text ( self , text , max_length ) :
text = text . strip ( )
if len ( text ) > max_length :
text = text [ : max_length - 3 ] + ' ... '
return text
2005-07-31 21:21:11 +02:00
def add_status_row ( self , file_path , show , str_status ) :
2005-07-20 19:50:50 +02:00
''' appends a new row with status icon to the table '''
self . current_row + = 1
state_file = show . replace ( ' ' , ' _ ' )
files = [ ]
files . append ( os . path . join ( file_path , state_file + ' .png ' ) )
files . append ( os . path . join ( file_path , state_file + ' .gif ' ) )
image = gtk . Image ( )
image . set_from_pixbuf ( None )
2005-07-31 21:21:11 +02:00
spacer = gtk . Label ( ' ' )
2005-07-20 19:50:50 +02:00
for file in files :
if os . path . exists ( file ) :
image . set_from_file ( file )
break
2005-07-21 16:09:17 +02:00
image . set_alignment ( 0.01 , 1 )
2005-07-20 19:50:50 +02:00
self . table . attach ( spacer , 1 , 2 , self . current_row ,
self . current_row + 1 , 0 , 0 , 0 , 0 )
self . table . attach ( image , 2 , 3 , self . current_row ,
self . current_row + 1 , 0 , 0 , 3 , 0 )
2005-07-21 16:09:17 +02:00
image . set_alignment ( 0.01 , 1 )
2005-07-31 21:21:11 +02:00
status_label = gtk . Label ( )
status_label . set_markup ( str_status )
2005-07-20 19:50:50 +02:00
status_label . set_alignment ( 00 , 0 )
2005-07-21 23:39:47 +02:00
self . table . attach ( status_label , 3 , 4 , self . current_row ,
self . current_row + 1 , gtk . EXPAND | gtk . FILL , 0 , 0 , 0 )
2005-07-31 21:21:11 +02:00
class NotificationAreaTooltip ( BaseTooltip , StatusTable ) :
''' Tooltip that is shown in the notification area '''
def __init__ ( self , plugin ) :
self . plugin = plugin
BaseTooltip . __init__ ( self )
StatusTable . __init__ ( self )
2005-08-02 01:17:53 +02:00
2005-07-31 21:21:11 +02:00
def populate ( self , data ) :
self . create_window ( )
self . create_table ( )
self . hbox = gtk . HBox ( )
self . table . set_property ( ' column-spacing ' , 1 )
text , single_line , accounts = ' ' , ' ' , [ ]
if gajim . contacts :
for account in gajim . contacts . keys ( ) :
status_idx = gajim . connections [ account ] . connected
# uncomment the following to hide offline accounts
# if status_idx == 0: continue
from common . connection import STATUS_LIST
status = STATUS_LIST [ status_idx ]
message = gajim . connections [ account ] . status
single_line = helpers . get_uf_show ( status )
if message is None :
message = ' '
else :
message = message . strip ( )
if message != ' ' :
single_line + = ' : ' + message
2005-08-01 17:54:26 +02:00
# the other solution is to hide offline accounts
elif status == ' offline ' :
message = helpers . get_uf_show ( status )
2005-08-02 01:17:53 +02:00
accounts . append ( { ' name ' : account , ' status_line ' : single_line ,
' show ' : status , ' message ' : message } )
2005-07-31 21:21:11 +02:00
unread_messages_no = self . plugin . roster . nb_unread
if unread_messages_no > 1 :
text = _ ( ' Gajim - %s unread messages ' ) % unread_messages_no
elif unread_messages_no == 1 :
text = _ ( ' Gajim - 1 unread message ' )
elif len ( accounts ) > 1 :
text = _ ( ' Gajim ' )
self . current_row = 1
self . table . resize ( 2 , 1 )
iconset = gajim . config . get ( ' iconset ' )
if not iconset :
iconset = ' sun '
file_path = os . path . join ( gajim . DATA_DIR , ' iconsets ' , iconset , ' 16x16 ' )
for acct in accounts :
2005-07-31 23:16:20 +02:00
mesage = gtkgui_helpers . escape_for_pango_markup ( acct [ ' message ' ] )
mesage = self . strip_text ( mesage , 50 )
2005-07-31 21:21:11 +02:00
self . add_status_row ( file_path , acct [ ' show ' ] , ' <span weight= " bold " > ' +
gtkgui_helpers . escape_for_pango_markup ( acct [ ' name ' ] ) + ' </span> '
2005-07-31 23:16:20 +02:00
+ ' - ' + mesage )
2005-07-31 21:21:11 +02:00
elif len ( accounts ) == 1 :
text = _ ( ' Gajim - %s ' ) % accounts [ 0 ] [ ' status_line ' ]
else :
text = _ ( ' Gajim - %s ' ) % helpers . get_uf_show ( ' offline ' )
self . text_lable . set_markup ( text )
self . hbox . add ( self . table )
self . win . add ( self . hbox )
class RosterTooltip ( BaseTooltip , StatusTable ) :
''' Tooltip that is shown in the roster treeview '''
def __init__ ( self , plugin ) :
self . account = None
self . plugin = plugin
self . image = gtk . Image ( )
self . image . set_alignment ( 0.5 , 0.025 )
BaseTooltip . __init__ ( self )
StatusTable . __init__ ( self )
2005-07-21 16:09:17 +02:00
2005-07-15 20:13:54 +02:00
def populate ( self , contacts ) :
2005-07-08 02:04:59 +02:00
if not contacts or len ( contacts ) == 0 :
return
2005-07-30 21:19:48 +02:00
self . create_window ( )
2005-07-31 21:21:11 +02:00
self . hbox = gtk . HBox ( )
self . hbox . set_homogeneous ( False )
self . create_table ( )
2005-07-08 02:04:59 +02:00
prim_contact = None # primary contact
for contact in contacts :
if prim_contact == None or contact . priority > prim_contact . priority :
prim_contact = contact
2005-07-09 01:43:11 +02:00
# try to find the image for the contact status
state_file = prim_contact . show . replace ( ' ' , ' _ ' )
2005-07-15 20:13:54 +02:00
transport = self . plugin . roster . get_transport_name_by_jid ( prim_contact . jid )
if transport :
2005-07-19 17:05:01 +02:00
file_path = os . path . join ( gajim . DATA_DIR , ' iconsets ' , ' transports ' ,
transport , ' 16x16 ' )
2005-07-15 20:13:54 +02:00
else :
iconset = gajim . config . get ( ' iconset ' )
if not iconset :
iconset = ' sun '
file_path = os . path . join ( gajim . DATA_DIR , ' iconsets ' , iconset , ' 16x16 ' )
2005-07-09 01:43:11 +02:00
files = [ ]
2005-07-20 19:50:50 +02:00
file_full_path = os . path . join ( file_path , state_file )
files . append ( file_full_path + ' .png ' )
files . append ( file_full_path + ' .gif ' )
2005-07-15 20:13:54 +02:00
self . image . set_from_pixbuf ( None )
2005-07-09 01:43:11 +02:00
for file in files :
if os . path . exists ( file ) :
self . image . set_from_file ( file )
break
2005-07-31 21:21:11 +02:00
2005-07-08 02:04:59 +02:00
info = ' <span size= " large " weight= " bold " > ' + prim_contact . jid + ' </span> '
2005-07-07 23:27:53 +02:00
info + = ' \n <span weight= " bold " > ' + _ ( ' Name: ' ) + ' </span> ' + \
2005-07-21 23:39:47 +02:00
gtkgui_helpers . escape_for_pango_markup ( prim_contact . name )
2005-07-08 01:37:04 +02:00
info + = ' \n <span weight= " bold " > ' + _ ( ' Subscription: ' ) + ' </span> ' + \
2005-07-21 23:39:47 +02:00
gtkgui_helpers . escape_for_pango_markup ( prim_contact . sub )
2005-07-08 02:04:59 +02:00
if prim_contact . keyID :
2005-07-07 23:27:53 +02:00
keyID = None
2005-07-08 02:04:59 +02:00
if len ( prim_contact . keyID ) == 8 :
keyID = prim_contact . keyID
elif len ( prim_contact . keyID ) == 16 :
keyID = prim_contact . keyID [ 8 : ]
2005-07-07 23:27:53 +02:00
if keyID :
2005-07-08 02:04:59 +02:00
info + = ' \n <span weight= " bold " > ' + _ ( ' OpenPGP: ' ) + \
2005-07-21 23:39:47 +02:00
' </span> ' + gtkgui_helpers . escape_for_pango_markup ( keyID )
2005-07-08 02:04:59 +02:00
2005-07-19 17:05:01 +02:00
single_line , resource_str , multiple_resource = ' ' , ' ' , False
2005-07-20 19:50:50 +02:00
num_resources = 0
2005-07-08 02:04:59 +02:00
for contact in contacts :
if contact . resource :
2005-07-20 19:50:50 +02:00
num_resources + = 1
if num_resources > 1 :
self . current_row = 1
self . table . resize ( 2 , 1 )
2005-07-19 17:05:01 +02:00
info + = ' \n <span weight= " bold " > ' + _ ( ' Status: ' ) + ' </span> '
2005-07-20 19:50:50 +02:00
for contact in contacts :
if contact . resource :
2005-07-31 21:21:11 +02:00
status_line = self . get_status_info ( contact . resource , contact . priority ,
2005-07-20 19:50:50 +02:00
contact . show , contact . status )
2005-07-31 21:21:11 +02:00
self . add_status_row ( file_path , contact . show , status_line )
2005-07-20 19:50:50 +02:00
else : # only one resource
if contact . resource :
info + = ' \n <span weight= " bold " > ' + _ ( ' Resource: ' ) + \
2005-07-22 02:01:05 +02:00
' </span> ' + gtkgui_helpers . escape_for_pango_markup (
contact . resource ) + ' ( ' + str ( contact . priority ) + ' ) '
2005-07-20 19:50:50 +02:00
if contact . show :
info + = ' \n <span weight= " bold " > ' + _ ( ' Status: ' ) + \
' </span> ' + helpers . get_uf_show ( contact . show )
2005-07-21 15:11:35 +02:00
if contact . status :
status = contact . status . strip ( )
if status != ' ' :
2005-07-21 16:09:17 +02:00
# escape markup entities. Is it posible to have markup in status?
2005-07-21 23:39:47 +02:00
info + = ' - ' + gtkgui_helpers . escape_for_pango_markup ( status )
2005-07-21 16:09:17 +02:00
2005-07-31 21:21:11 +02:00
self . text_lable . set_markup ( info )
self . hbox . pack_start ( self . image , False , False )
self . hbox . pack_start ( self . table , True , True )
self . win . add ( self . hbox )
2005-07-07 23:27:53 +02:00
2005-06-10 23:14:16 +02:00
class InputDialog :
2005-05-14 03:29:53 +02:00
''' Class for Input dialog '''
2005-07-25 09:47:05 +02:00
def __init__ ( self , title , label_str , input_str = None , is_modal = True , ok_handler = None ) :
2005-05-14 03:29:53 +02:00
xml = gtk . glade . XML ( GTKGUI_GLADE , ' input_dialog ' , APP )
self . dialog = xml . get_widget ( ' input_dialog ' )
label = xml . get_widget ( ' label ' )
self . input_entry = xml . get_widget ( ' input_entry ' )
self . dialog . set_title ( title )
label . set_text ( label_str )
2005-05-14 18:34:07 +02:00
if input_str :
self . input_entry . set_text ( input_str )
2005-06-19 01:44:33 +02:00
self . input_entry . select_region ( 0 , - 1 ) # select all
2005-07-25 09:47:05 +02:00
self . is_modal = is_modal
if not is_modal and ok_handler is not None :
self . ok_handler = ok_handler
okbutton = xml . get_widget ( ' okbutton ' )
okbutton . connect ( ' clicked ' , self . on_okbutton_clicked )
2005-07-25 16:21:01 +02:00
cancelbutton = xml . get_widget ( ' cancelbutton ' )
cancelbutton . connect ( ' clicked ' , self . on_cancelbutton_clicked )
2005-07-25 09:47:05 +02:00
self . dialog . show_all ( )
def on_okbutton_clicked ( self , widget ) :
response = self . input_entry . get_text ( )
2005-06-19 01:44:33 +02:00
self . dialog . destroy ( )
2005-07-25 09:47:05 +02:00
self . ok_handler ( response )
2005-07-25 16:21:01 +02:00
def on_cancelbutton_clicked ( self , widget ) :
self . dialog . destroy ( )
2005-07-25 09:47:05 +02:00
def get_response ( self ) :
if self . is_modal :
response = self . dialog . run ( )
self . dialog . destroy ( )
2005-06-19 01:44:33 +02:00
return response
2005-05-14 03:29:53 +02:00
2005-06-10 23:14:16 +02:00
class ErrorDialog ( HigDialog ) :
2005-06-12 19:36:27 +02:00
def __init__ ( self , pritext , sectext = ' ' ) :
""" HIG compliant error dialog. """
HigDialog . __init__ (
self , None , pritext , sectext , gtk . STOCK_DIALOG_ERROR ,
[ [ gtk . STOCK_OK , gtk . RESPONSE_OK ] ]
)
2005-03-01 20:02:51 +01:00
2005-06-10 00:29:06 +02:00
2005-06-13 12:48:07 +02:00
class SubscriptionRequestWindow :
2005-04-04 18:46:35 +02:00
def __init__ ( self , plugin , jid , text , account ) :
xml = gtk . glade . XML ( GTKGUI_GLADE , ' subscription_request_window ' , APP )
2005-04-12 17:30:09 +02:00
self . window = xml . get_widget ( ' subscription_request_window ' )
2005-04-04 18:46:35 +02:00
self . plugin = plugin
self . jid = jid
self . account = account
2005-06-13 15:26:04 +02:00
if len ( gajim . connections ) > = 2 :
prompt_text = _ ( ' Subscription request for account %s from %s ' ) \
% ( account , self . jid )
else :
prompt_text = _ ( ' Subscription request from %s ' ) % self . jid
xml . get_widget ( ' from_label ' ) . set_text ( prompt_text )
2005-04-04 18:46:35 +02:00
xml . get_widget ( ' message_textview ' ) . get_buffer ( ) . set_text ( text )
xml . signal_autoconnect ( self )
self . window . show_all ( )
2005-03-01 15:02:32 +01:00
def on_close_button_clicked ( self , widget ) :
2005-04-12 17:30:09 +02:00
self . window . destroy ( )
2004-05-15 18:50:38 +02:00
2005-03-01 15:02:32 +01:00
def on_authorize_button_clicked ( self , widget ) :
2005-05-16 15:56:46 +02:00
''' accept the request '''
2005-04-14 11:38:08 +02:00
gajim . connections [ self . account ] . send_authorization ( self . jid )
2005-04-12 17:30:09 +02:00
self . window . destroy ( )
2005-07-18 23:08:31 +02:00
if not gajim . contacts [ self . account ] . has_key ( self . jid ) :
2005-06-10 23:14:16 +02:00
AddNewContactWindow ( self . plugin , self . account , self . jid )
2005-05-18 10:47:38 +02:00
def on_contact_info_button_clicked ( self , widget ) :
''' ask vcard '''
if self . plugin . windows [ self . account ] [ ' infos ' ] . has_key ( self . jid ) :
self . plugin . windows [ self . account ] [ ' infos ' ] [ self . jid ] . window . present ( )
else :
self . plugin . windows [ self . account ] [ ' infos ' ] [ self . jid ] = \
2005-06-11 00:45:50 +02:00
VcardWindow ( self . jid , self . plugin , self . account , True )
2005-05-18 10:47:38 +02:00
#remove the publish / retrieve buttons
vcard_xml = self . plugin . windows [ self . account ] [ ' infos ' ] [ self . jid ] . xml
hbuttonbox = vcard_xml . get_widget ( ' information_hbuttonbox ' )
children = hbuttonbox . get_children ( )
hbuttonbox . remove ( children [ 0 ] )
hbuttonbox . remove ( children [ 1 ] )
vcard_xml . get_widget ( ' nickname_label ' ) . set_text ( self . jid )
gajim . connections [ self . account ] . request_vcard ( self . jid )
2004-05-15 18:50:38 +02:00
2005-03-01 15:02:32 +01:00
def on_deny_button_clicked ( self , widget ) :
2005-04-18 14:17:43 +02:00
''' refuse the request '''
2005-04-14 11:38:08 +02:00
gajim . connections [ self . account ] . refuse_authorization ( self . jid )
2005-04-12 17:30:09 +02:00
self . window . destroy ( )
2005-04-04 18:46:35 +02:00
2005-06-10 23:14:16 +02:00
class JoinGroupchatWindow :
2005-04-22 01:20:18 +02:00
def __init__ ( self , plugin , account , server = ' ' , room = ' ' ) :
2005-04-21 20:53:16 +02:00
self . plugin = plugin
self . account = account
2005-04-14 09:20:14 +02:00
if gajim . connections [ account ] . connected < 2 :
2005-06-10 23:14:16 +02:00
ErrorDialog ( _ ( ' You are not connected to the server ' ) ,
2005-06-07 03:10:24 +02:00
_ ( ' You can not join a group chat unless you are connected. ' ) ) . get_response ( )
2005-05-12 02:00:40 +02:00
raise RuntimeError , ' You must be connected to join a groupchat '
2005-04-04 18:46:35 +02:00
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' join_groupchat_window ' , APP )
self . window = self . xml . get_widget ( ' join_groupchat_window ' )
self . xml . get_widget ( ' server_entry ' ) . set_text ( server )
self . xml . get_widget ( ' room_entry ' ) . set_text ( room )
2005-07-18 23:08:31 +02:00
self . xml . get_widget ( ' nickname_entry ' ) . set_text ( gajim . nicks [ self . account ] )
2005-04-04 18:46:35 +02:00
self . xml . signal_autoconnect ( self )
2005-04-07 13:25:59 +02:00
self . plugin . windows [ account ] [ ' join_gc ' ] = self #now add us to open windows
2005-04-21 20:53:16 +02:00
our_jid = gajim . config . get_per ( ' accounts ' , self . account , ' name ' ) + ' @ ' + \
gajim . config . get_per ( ' accounts ' , self . account , ' hostname ' )
if len ( gajim . connections ) > 1 :
2005-08-02 00:48:58 +02:00
title = _ ( ' Join Group Chat as %s ' ) % our_jid
2005-04-21 20:53:16 +02:00
else :
2005-08-02 00:48:58 +02:00
title = _ ( ' Join Group Chat ' )
2005-04-21 20:53:16 +02:00
self . window . set_title ( title )
2005-04-07 00:52:48 +02:00
self . recently_combobox = self . xml . get_widget ( ' recently_combobox ' )
liststore = gtk . ListStore ( str )
self . recently_combobox . set_model ( liststore )
cell = gtk . CellRendererText ( )
self . recently_combobox . pack_start ( cell , True )
self . recently_combobox . add_attribute ( cell , ' text ' , 0 )
2005-04-12 23:09:06 +02:00
self . recently_groupchat = gajim . config . get ( ' recently_groupchat ' ) . split ( )
2005-04-07 00:52:48 +02:00
for g in self . recently_groupchat :
self . recently_combobox . append_text ( g )
2005-06-30 18:45:14 +02:00
if len ( self . recently_groupchat ) and server == ' ' and room == ' ' :
2005-06-10 14:31:06 +02:00
self . recently_combobox . set_active ( 0 )
self . xml . get_widget ( ' room_entry ' ) . select_region ( 0 , - 1 )
2005-04-07 00:52:48 +02:00
2005-04-04 17:51:29 +02:00
self . window . show_all ( )
2005-03-02 00:48:05 +01:00
2005-03-02 13:32:44 +01:00
def on_join_groupchat_window_destroy ( self , widget ) :
2005-04-18 14:17:43 +02:00
''' close window '''
2005-04-07 13:25:59 +02:00
del self . plugin . windows [ self . account ] [ ' join_gc ' ] # remove us from open windows
2005-03-02 00:48:05 +01:00
2005-04-07 11:53:54 +02:00
def on_join_groupchat_window_key_press_event ( self , widget , event ) :
if event . keyval == gtk . keysyms . Escape : # ESCAPE
widget . destroy ( )
2005-04-07 00:52:48 +02:00
def on_recently_combobox_changed ( self , widget ) :
model = widget . get_model ( )
iter = widget . get_active_iter ( )
2005-07-25 16:38:41 +02:00
gid = model [ iter ] [ 0 ]
2005-04-07 00:52:48 +02:00
self . xml . get_widget ( ' room_entry ' ) . set_text ( gid . split ( ' @ ' ) [ 0 ] )
self . xml . get_widget ( ' server_entry ' ) . set_text ( gid . split ( ' @ ' ) [ 1 ] )
2005-03-04 14:41:48 +01:00
def on_cancel_button_clicked ( self , widget ) :
2005-04-18 14:17:43 +02:00
''' When Cancel button is clicked '''
2005-04-12 17:30:09 +02:00
self . window . destroy ( )
2005-03-02 00:48:05 +01:00
2005-03-02 13:32:44 +01:00
def on_join_button_clicked ( self , widget ) :
2005-04-18 14:17:43 +02:00
''' When Join button is clicked '''
2005-03-02 13:32:44 +01:00
nickname = self . xml . get_widget ( ' nickname_entry ' ) . get_text ( )
room = self . xml . get_widget ( ' room_entry ' ) . get_text ( )
server = self . xml . get_widget ( ' server_entry ' ) . get_text ( )
2005-03-04 14:41:48 +01:00
password = self . xml . get_widget ( ' password_entry ' ) . get_text ( )
2005-03-02 00:48:05 +01:00
jid = ' %s @ %s ' % ( room , server )
2005-04-07 00:52:48 +02:00
if jid in self . recently_groupchat :
self . recently_groupchat . remove ( jid )
self . recently_groupchat . insert ( 0 , jid )
if len ( self . recently_groupchat ) > 10 :
self . recently_groupchat = self . recently_groupchat [ 0 : 10 ]
2005-04-12 23:09:06 +02:00
gajim . config . set ( ' recently_groupchat ' , ' ' . join ( self . recently_groupchat ) )
2005-06-13 12:49:48 +02:00
self . plugin . roster . join_gc_room ( self . account , jid , nickname , password )
2005-04-12 17:30:09 +02:00
self . window . destroy ( )
2005-03-02 00:48:05 +01:00
2005-06-10 23:14:16 +02:00
class NewMessageDialog :
2005-04-04 18:46:35 +02:00
def __init__ ( self , plugin , account ) :
2005-03-02 00:48:05 +01:00
self . plugin = plugin
self . account = account
2005-06-20 01:09:15 +02:00
2005-04-14 09:05:10 +02:00
our_jid = gajim . config . get_per ( ' accounts ' , self . account , ' name ' ) + ' @ ' + \
gajim . config . get_per ( ' accounts ' , self . account , ' hostname ' )
2005-04-17 21:53:39 +02:00
if len ( gajim . connections ) > 1 :
2005-07-01 17:15:35 +02:00
title = _ ( ' New Message as %s ' ) % our_jid
2005-04-04 18:46:35 +02:00
else :
2005-05-21 16:12:35 +02:00
title = _ ( ' New Message ' )
2005-07-01 17:15:35 +02:00
prompt_text = _ ( ' Fill in the contact ID of the contact you would like \n to send a chat message to: ' )
2005-03-02 00:48:05 +01:00
2005-07-25 09:47:05 +02:00
instance = InputDialog ( title , prompt_text , is_modal = False , ok_handler = self . new_message_response )
def new_message_response ( self , jid ) :
''' called when ok button is clicked '''
if jid . find ( ' @ ' ) == - 1 : # if no @ was given
ErrorDialog ( _ ( ' Invalid contact ID ' ) ,
_ ( ' Contact ID must be of the form " username@servername " . ' ) ) . get_response ( )
return
2005-06-20 01:09:15 +02:00
2005-07-25 09:47:05 +02:00
self . plugin . roster . new_chat_from_jid ( self . account , jid )
2005-03-02 00:48:05 +01:00
2005-06-10 23:14:16 +02:00
class ChangePasswordDialog :
2005-03-02 19:38:27 +01:00
def __init__ ( self , plugin , account ) :
2005-07-18 13:03:53 +02:00
# 'account' can be None if we are about to create our first one
if not account or gajim . connections [ account ] . connected < 2 :
2005-06-10 23:14:16 +02:00
ErrorDialog ( _ ( ' You are not connected to the server ' ) ,
2005-06-07 03:10:24 +02:00
_ ( ' Without a connection, you can not change your password. ' ) ) . get_response ( )
2005-07-18 13:03:53 +02:00
raise RuntimeError , ' You are not connected to the server '
2005-03-02 00:48:05 +01:00
self . plugin = plugin
self . account = account
2005-04-04 18:46:35 +02:00
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' change_password_dialog ' , APP )
self . dialog = self . xml . get_widget ( ' change_password_dialog ' )
self . password1_entry = self . xml . get_widget ( ' password1_entry ' )
self . password2_entry = self . xml . get_widget ( ' password2_entry ' )
2005-03-28 03:39:12 +02:00
2005-06-05 12:48:34 +02:00
self . dialog . show_all ( )
2005-03-04 14:10:00 +01:00
def run ( self ) :
2005-04-18 14:17:43 +02:00
''' Wait for OK button to be pressed and return new password '''
2005-03-04 14:10:00 +01:00
end = False
while not end :
rep = self . dialog . run ( )
if rep == gtk . RESPONSE_OK :
password1 = self . password1_entry . get_text ( )
if not password1 :
2005-08-02 01:17:53 +02:00
ErrorDialog ( _ ( ' Invalid password ' ) ,
2005-06-07 03:10:24 +02:00
_ ( ' You must enter a password. ' ) ) . get_response ( )
2005-03-04 14:10:00 +01:00
continue
password2 = self . password2_entry . get_text ( )
if password1 != password2 :
2005-08-02 00:48:58 +02:00
ErrorDialog ( _ ( ' Passwords do not match ' ) ,
2005-06-07 03:10:24 +02:00
_ ( ' The passwords typed in both fields must be identical. ' ) ) . get_response ( )
2005-03-04 14:10:00 +01:00
continue
message = password1
else :
message = - 1
end = True
self . dialog . destroy ( )
return message
2005-06-10 00:29:06 +02:00
2005-06-10 20:40:19 +02:00
class PopupNotificationWindow :
2005-07-30 12:20:46 +02:00
def __init__ ( self , plugin , event_type , jid , account , msg_type = ' ' , file_props = None ) :
2005-03-04 14:10:00 +01:00
self . plugin = plugin
2005-04-12 17:30:09 +02:00
self . account = account
self . jid = jid
2005-07-07 17:41:03 +02:00
self . msg_type = msg_type
2005-07-30 12:20:46 +02:00
self . file_props = file_props
2005-04-04 21:27:06 +02:00
2005-04-21 23:23:41 +02:00
xml = gtk . glade . XML ( GTKGUI_GLADE , ' popup_notification_window ' , APP )
self . window = xml . get_widget ( ' popup_notification_window ' )
2005-04-04 21:27:06 +02:00
close_button = xml . get_widget ( ' close_button ' )
2005-04-06 20:51:54 +02:00
event_type_label = xml . get_widget ( ' event_type_label ' )
event_description_label = xml . get_widget ( ' event_description_label ' )
eventbox = xml . get_widget ( ' eventbox ' )
2005-04-05 17:06:11 +02:00
2005-04-22 01:20:18 +02:00
event_type_label . set_markup ( ' <b> ' + event_type + ' </b> ' )
2005-04-12 17:30:09 +02:00
2005-07-18 23:08:31 +02:00
if self . jid in gajim . contacts [ account ] :
txt = gajim . contacts [ account ] [ self . jid ] [ 0 ] . name
2005-04-12 17:30:09 +02:00
else :
txt = self . jid
event_description_label . set_text ( txt )
2005-04-04 18:46:35 +02:00
2005-04-06 20:51:54 +02:00
# set colors [ http://www.w3schools.com/html/html_colornames.asp ]
self . window . modify_bg ( gtk . STATE_NORMAL , gtk . gdk . color_parse ( ' black ' ) )
2005-08-04 13:17:16 +02:00
2005-06-03 20:40:43 +02:00
if event_type == _ ( ' Contact Signed In ' ) :
2005-07-16 11:33:43 +02:00
limegreen = gtk . gdk . color_parse ( ' limegreen ' )
close_button . modify_bg ( gtk . STATE_NORMAL , limegreen )
eventbox . modify_bg ( gtk . STATE_NORMAL , limegreen )
2005-06-03 20:40:43 +02:00
elif event_type == _ ( ' Contact Signed Out ' ) :
2005-07-16 11:33:43 +02:00
red = gtk . gdk . color_parse ( ' red ' )
close_button . modify_bg ( gtk . STATE_NORMAL , red )
eventbox . modify_bg ( gtk . STATE_NORMAL , red )
elif event_type == _ ( ' New Message ' ) or \
event_type == _ ( ' New Single Message ' ) :
dodgerblue = gtk . gdk . color_parse ( ' dodgerblue ' )
close_button . modify_bg ( gtk . STATE_NORMAL , dodgerblue )
eventbox . modify_bg ( gtk . STATE_NORMAL , dodgerblue )
2005-06-03 20:40:43 +02:00
txt = _ ( ' From %s ' ) % txt
2005-08-03 18:53:04 +02:00
elif event_type == _ ( ' File Transfer Request ' ) :
2005-07-30 12:20:46 +02:00
bg_color = gtk . gdk . color_parse ( ' coral ' )
close_button . modify_bg ( gtk . STATE_NORMAL , bg_color )
eventbox . modify_bg ( gtk . STATE_NORMAL , bg_color )
txt = _ ( ' From %s ' ) % txt
2005-08-04 13:17:16 +02:00
2005-08-02 00:48:58 +02:00
elif event_type in [ _ ( ' File Transfer Completed ' ) , _ ( ' File Transfer Stopped ' ) ] :
2005-07-30 16:14:10 +02:00
bg_color = gtk . gdk . color_parse ( ' coral ' )
close_button . modify_bg ( gtk . STATE_NORMAL , bg_color )
eventbox . modify_bg ( gtk . STATE_NORMAL , bg_color )
2005-04-04 18:46:35 +02:00
# position the window to bottom-right of screen
2005-04-12 17:30:09 +02:00
window_width , self . window_height = self . window . get_size ( )
2005-04-21 23:30:56 +02:00
self . plugin . roster . popups_notification_height + = self . window_height
2005-05-19 19:47:40 +02:00
self . window . move ( gtk . gdk . screen_width ( ) - window_width ,
2005-06-10 20:40:19 +02:00
gtk . gdk . screen_height ( ) - self . plugin . roster . popups_notification_height )
2005-04-04 18:46:35 +02:00
2005-04-04 21:27:06 +02:00
xml . signal_autoconnect ( self )
2005-04-04 17:51:29 +02:00
self . window . show_all ( )
2005-04-12 17:30:09 +02:00
gobject . timeout_add ( 5000 , self . on_timeout )
2005-04-04 18:46:35 +02:00
2005-04-12 17:30:09 +02:00
def on_close_button_clicked ( self , widget ) :
2005-04-21 23:23:41 +02:00
self . adjust_height_and_move_popup_notification_windows ( )
2005-04-04 21:27:06 +02:00
2005-04-12 17:30:09 +02:00
def on_timeout ( self ) :
2005-04-21 23:23:41 +02:00
self . adjust_height_and_move_popup_notification_windows ( )
2005-04-05 17:06:11 +02:00
2005-04-21 23:23:41 +02:00
def adjust_height_and_move_popup_notification_windows ( self ) :
2005-04-05 17:06:11 +02:00
#remove
2005-04-21 23:30:56 +02:00
self . plugin . roster . popups_notification_height - = self . window_height
2005-04-04 21:27:06 +02:00
self . window . destroy ( )
2005-04-05 17:06:11 +02:00
2005-04-21 23:23:41 +02:00
if len ( self . plugin . roster . popup_notification_windows ) > 0 :
2005-04-05 17:06:11 +02:00
# we want to remove the first window added in the list
2005-04-21 23:23:41 +02:00
self . plugin . roster . popup_notification_windows . pop ( 0 ) # remove 1st item
2005-04-05 17:06:11 +02:00
# move the rest of popup windows
2005-04-21 23:30:56 +02:00
self . plugin . roster . popups_notification_height = 0
2005-04-21 23:23:41 +02:00
for window_instance in self . plugin . roster . popup_notification_windows :
2005-04-05 17:06:11 +02:00
window_width , window_height = window_instance . window . get_size ( )
2005-04-21 23:30:56 +02:00
self . plugin . roster . popups_notification_height + = window_height
2005-05-19 19:47:40 +02:00
window_instance . window . move ( gtk . gdk . screen_width ( ) - window_width ,
2005-07-07 17:41:03 +02:00
gtk . gdk . screen_height ( ) - self . plugin . roster . popups_notification_height )
2005-04-06 20:51:54 +02:00
2005-04-21 23:23:41 +02:00
def on_popup_notification_window_button_press_event ( self , widget , event ) :
2005-06-24 16:28:00 +02:00
# use Contact class, new_chat expects it that way
2005-04-12 17:30:09 +02:00
# is it in the roster?
2005-07-18 23:08:31 +02:00
if gajim . contacts [ self . account ] . has_key ( self . jid ) :
2005-08-06 12:20:04 +02:00
contact = gajim . get_contact_instance_with_highest_priority (
self . account , self . jid )
2005-04-12 17:30:09 +02:00
else :
2005-05-29 23:34:01 +02:00
keyID = ' '
attached_keys = gajim . config . get_per ( ' accounts ' , self . account ,
' attached_gpg_keys ' ) . split ( )
2005-08-03 23:11:46 +02:00
if self . jid in attached_keys :
2005-05-29 23:34:01 +02:00
keyID = attached_keys [ attached_keys . index ( jid ) + 1 ]
2005-08-04 09:23:31 +02:00
if self . msg_type . find ( ' file ' ) != 0 :
contact = Contact ( jid = self . jid , name = self . jid . split ( ' @ ' ) [ 0 ] ,
groups = [ _ ( ' not in the roster ' ) ] , show = ' not in the roster ' ,
status = _ ( ' not in the roster ' ) , sub = ' none ' , keyID = keyID )
gajim . contacts [ self . account ] [ self . jid ] = [ contact ]
self . plugin . roster . add_contact_to_roster ( contact . jid ,
self . account )
2005-04-12 17:30:09 +02:00
2005-07-08 01:37:04 +02:00
if self . msg_type == ' normal ' : # it's single message
2005-07-16 11:33:43 +02:00
return # FIXME: I think I should not print here but in new_chat?
contact = self . contacts [ account ] [ jid ] [ 0 ]
2005-08-06 14:33:20 +02:00
SingleMessageWindow ( self . plugin , self . account , contact . jid ,
2005-07-16 11:33:43 +02:00
action = ' receive ' , from_whom = jid , subject = subject , message = msg )
2005-07-30 12:20:46 +02:00
elif self . msg_type == ' file ' : # it's file request
2005-08-01 17:02:17 +02:00
self . plugin . windows [ ' file_transfers ' ] . show_file_request (
self . account , contact , self . file_props )
2005-07-30 12:20:46 +02:00
2005-08-02 00:48:58 +02:00
elif self . msg_type == ' file-completed ' : # it's file request # FIXME: comment
2005-08-06 18:16:40 +02:00
self . plugin . windows [ ' file_transfers ' ] . show_completed ( self . jid , \
self . file_props )
2005-08-04 13:17:16 +02:00
2005-08-02 00:48:58 +02:00
elif self . msg_type == ' file-stopped ' : # it's file request # FIXME: comment
2005-08-06 18:16:40 +02:00
self . plugin . windows [ ' file_transfers ' ] . show_stopped ( self . jid , \
self . file_props )
2005-07-30 16:14:10 +02:00
2005-07-07 17:41:03 +02:00
else : # 'chat'
2005-07-16 11:33:43 +02:00
self . plugin . roster . new_chat ( contact , self . account )
2005-07-07 17:41:03 +02:00
chats_window = self . plugin . windows [ self . account ] [ ' chats ' ] [ self . jid ]
chats_window . set_active_tab ( self . jid )
chats_window . window . present ( )
2005-04-21 23:23:41 +02:00
self . adjust_height_and_move_popup_notification_windows ( )
2005-07-01 17:15:35 +02:00
2005-07-05 23:35:37 +02:00
class SingleMessageWindow :
''' SingleMessageWindow can send or show a received
singled message depending on action argument '''
2005-08-06 14:33:20 +02:00
def __init__ ( self , plugin , account , to = ' ' , action = ' ' , from_whom = ' ' ,
2005-07-05 23:35:37 +02:00
subject = ' ' , message = ' ' ) :
2005-07-01 17:15:35 +02:00
self . plugin = plugin
self . account = account
2005-08-06 18:16:40 +02:00
self . contact = contact
2005-07-05 23:35:37 +02:00
self . action = action
self . subject = subject
self . message = message
2005-07-01 17:15:35 +02:00
2005-07-05 23:35:37 +02:00
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' single_message_window ' , APP )
self . window = self . xml . get_widget ( ' single_message_window ' )
2005-07-02 17:49:25 +02:00
self . count_chars_label = self . xml . get_widget ( ' count_chars_label ' )
2005-07-05 23:35:37 +02:00
self . from_label = self . xml . get_widget ( ' from_label ' )
self . from_entry = self . xml . get_widget ( ' from_entry ' )
self . to_label = self . xml . get_widget ( ' to_label ' )
2005-07-02 17:49:25 +02:00
self . to_entry = self . xml . get_widget ( ' to_entry ' )
self . subject_entry = self . xml . get_widget ( ' subject_entry ' )
2005-07-05 23:35:37 +02:00
self . message_textview = self . xml . get_widget ( ' message_textview ' )
self . message_tv_buffer = self . message_textview . get_buffer ( )
self . send_button = self . xml . get_widget ( ' send_button ' )
self . reply_button = self . xml . get_widget ( ' reply_button ' )
2005-07-06 01:55:33 +02:00
self . send_and_close_button = self . xml . get_widget ( ' send_and_close_button ' )
2005-07-02 17:49:25 +02:00
self . message_tv_buffer . connect ( ' changed ' , self . update_char_counter )
2005-08-06 14:33:20 +02:00
self . to_entry . set_text ( to )
2005-07-01 17:15:35 +02:00
2005-07-05 23:35:37 +02:00
self . send_button . set_no_show_all ( True )
self . reply_button . set_no_show_all ( True )
2005-07-06 01:55:33 +02:00
self . send_and_close_button . set_no_show_all ( True )
2005-07-05 23:35:37 +02:00
self . to_label . set_no_show_all ( True )
self . to_entry . set_no_show_all ( True )
self . from_label . set_no_show_all ( True )
self . from_entry . set_no_show_all ( True )
self . prepare_widgets_for ( self . action )
if self . action == ' send ' :
if self . message : # we come from a reply?
self . message_textview . grab_focus ( )
else : # we write a new message
self . subject_entry . grab_focus ( )
elif self . action == ' receive ' :
self . from_whom = from_whom
self . from_entry . set_text ( self . from_whom )
self . from_entry . set_property ( ' editable ' , False )
self . subject_entry . set_property ( ' editable ' , False )
self . message_textview . set_editable ( False )
self . reply_button . grab_focus ( )
2005-07-26 17:23:11 +02:00
# set_text(None) raises TypeError exception
if self . subject is None :
self . subject = ' '
2005-07-05 23:35:37 +02:00
self . subject_entry . set_text ( self . subject )
self . message_tv_buffer . set_text ( self . message )
begin_iter = self . message_tv_buffer . get_start_iter ( )
self . message_tv_buffer . place_cursor ( begin_iter )
self . xml . signal_autoconnect ( self )
self . window . show_all ( )
def prepare_widgets_for ( self , action ) :
2005-07-01 17:15:35 +02:00
our_jid = gajim . config . get_per ( ' accounts ' , self . account , ' name ' ) + ' @ ' + \
gajim . config . get_per ( ' accounts ' , self . account , ' hostname ' )
if len ( gajim . connections ) > 1 :
2005-07-05 23:35:37 +02:00
title = _ ( ' Single Message as %s ' ) % our_jid
2005-07-01 17:15:35 +02:00
else :
2005-07-05 23:35:37 +02:00
title = _ ( ' Single Message ' )
if action == ' send ' :
title = _ ( ' Send %s ' ) % title
self . send_button . show ( )
2005-07-06 01:55:33 +02:00
self . send_and_close_button . show ( )
2005-07-05 23:35:37 +02:00
self . to_label . show ( )
self . to_entry . show ( )
self . reply_button . hide ( )
self . from_label . hide ( )
self . from_entry . hide ( )
elif action == ' receive ' :
2005-07-06 01:55:33 +02:00
title = _ ( ' Received %s ' ) % title
2005-07-05 23:35:37 +02:00
self . reply_button . show ( )
self . from_label . show ( )
self . from_entry . show ( )
self . send_button . hide ( )
2005-07-06 01:55:33 +02:00
self . send_and_close_button . hide ( )
2005-07-05 23:35:37 +02:00
self . to_label . hide ( )
self . to_entry . hide ( )
2005-07-02 17:49:25 +02:00
2005-07-05 23:35:37 +02:00
self . window . set_title ( title )
2005-07-01 17:15:35 +02:00
2005-07-02 17:49:25 +02:00
def on_cancel_button_clicked ( self , widget ) :
self . window . destroy ( )
2005-07-01 17:15:35 +02:00
2005-07-02 17:49:25 +02:00
def update_char_counter ( self , widget ) :
characters_no = self . message_tv_buffer . get_char_count ( )
self . count_chars_label . set_text ( str ( characters_no ) )
2005-07-01 17:15:35 +02:00
2005-07-06 01:55:33 +02:00
def send_single_message ( self ) :
2005-07-02 17:49:25 +02:00
to_whom_jid = self . to_entry . get_text ( )
2005-08-06 14:33:20 +02:00
subject = self . subject_entry . get_text ( )
begin , end = self . message_tv_buffer . get_bounds ( )
message = self . message_tv_buffer . get_text ( begin , end )
if to_whom_jid . find ( ' /announce/motd ' ) > - 1 :
gajim . connections [ self . account ] . send_motd ( to_whom_jid , subject ,
message )
return
2005-07-02 17:49:25 +02:00
if to_whom_jid . find ( ' @ ' ) == - 1 : # if no @ was given
ErrorDialog ( _ ( ' Invalid contact ID ' ) ,
_ ( ' Contact ID must be of the form " username@servername " . ' ) ) . get_response ( )
return
# FIXME: allow GPG message some day
gajim . connections [ self . account ] . send_message ( to_whom_jid , message ,
keyID = None , type = ' normal ' , subject = subject )
2005-07-05 23:57:19 +02:00
self . subject_entry . set_text ( ' ' ) # we sent ok, clear the subject
2005-07-02 17:49:25 +02:00
self . message_tv_buffer . set_text ( ' ' ) # we sent ok, clear the textview
2005-07-04 23:29:22 +02:00
2005-07-06 01:55:33 +02:00
def on_send_button_clicked ( self , widget ) :
self . send_single_message ( )
2005-07-05 23:35:37 +02:00
def on_reply_button_clicked ( self , widget ) :
# we create a new blank window to send and we preset RE: and to jid
self . subject = _ ( ' RE: %s ' ) % self . subject
2005-07-06 01:55:33 +02:00
self . message = _ ( ' \n \n \n == Original Message == \n %s ' ) % self . message
2005-07-05 23:57:19 +02:00
self . window . destroy ( )
2005-08-06 14:33:20 +02:00
SingleMessageWindow ( self . plugin , self . account , to = to ,
2005-07-05 23:35:37 +02:00
action = ' send ' , from_whom = self . from_whom , subject = self . subject ,
message = self . message )
2005-07-06 01:55:33 +02:00
def on_send_and_close_button_clicked ( self , widget ) :
self . send_single_message ( )
self . window . destroy ( )
def on_single_message_window_key_press_event ( self , widget , event ) :
if event . keyval == gtk . keysyms . Escape : # ESCAPE
self . window . destroy ( )
2005-07-04 23:29:22 +02:00
class XMLConsoleWindow :
def __init__ ( self , plugin , account ) :
self . plugin = plugin
self . account = account
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' xml_console_window ' , APP )
self . window = self . xml . get_widget ( ' xml_console_window ' )
self . input_textview = self . xml . get_widget ( ' input_textview ' )
self . stanzas_log_textview = self . xml . get_widget ( ' stanzas_log_textview ' )
2005-08-06 02:38:24 +02:00
self . input_tv_buffer = self . input_textview . get_buffer ( )
2005-08-06 01:43:28 +02:00
buffer = self . stanzas_log_textview . get_buffer ( )
2005-08-06 02:38:24 +02:00
end_iter = buffer . get_end_iter ( )
buffer . create_mark ( ' end ' , end_iter , False )
2005-08-06 01:43:28 +02:00
self . tagIn = buffer . create_tag ( ' incoming ' )
color = gajim . config . get ( ' inmsgcolor ' )
self . tagIn . set_property ( ' foreground ' , color )
self . tagOut = buffer . create_tag ( ' outgoing ' )
color = gajim . config . get ( ' outmsgcolor ' )
self . tagOut . set_property ( ' foreground ' , color )
2005-08-06 02:38:24 +02:00
self . enable = False
2005-08-06 01:43:28 +02:00
2005-08-06 02:38:24 +02:00
self . input_textview . modify_text (
2005-08-06 01:43:28 +02:00
gtk . STATE_NORMAL , gtk . gdk . color_parse ( color ) )
2005-07-04 23:29:22 +02:00
if len ( gajim . connections ) > 1 :
2005-07-05 01:18:05 +02:00
title = _ ( ' XML Console for %s ' ) % self . account
2005-07-04 23:29:22 +02:00
else :
title = _ ( ' XML Console ' )
self . window . set_title ( title )
self . xml . signal_autoconnect ( self )
2005-08-06 02:38:24 +02:00
def on_xml_console_window_delete_event ( self , widget , event ) :
self . window . hide ( )
return True # do NOT destroy the window
def on_clear_button_clicked ( self , widget ) :
2005-08-04 22:32:38 +02:00
buffer = self . stanzas_log_textview . get_buffer ( )
2005-08-06 02:38:24 +02:00
buffer . set_text ( ' ' )
def on_enable_checkbutton_toggled ( self , widget ) :
self . enable = widget . get_active ( )
def scroll_to_end ( self , ) :
parent = self . stanzas_log_textview . get_parent ( )
buffer = self . stanzas_log_textview . get_buffer ( )
self . stanzas_log_textview . scroll_to_mark ( buffer . get_mark ( ' end ' ) , 0 , True ,
0 , 1 )
adjustment = parent . get_hadjustment ( )
adjustment . set_value ( 0 )
return False
def print_stanza ( self , stanza , kind ) :
# kind must be 'incoming' or 'outgoing'
if not self . enable :
return
buffer = self . stanzas_log_textview . get_buffer ( )
at_the_end = False
end_iter = buffer . get_end_iter ( )
end_rect = self . stanzas_log_textview . get_iter_location ( end_iter )
visible_rect = self . stanzas_log_textview . get_visible_rect ( )
if end_rect . y < = ( visible_rect . y + visible_rect . height ) :
at_the_end = True
2005-08-04 22:32:38 +02:00
end_iter = buffer . get_end_iter ( )
2005-08-06 02:38:24 +02:00
buffer . insert_with_tags_by_name ( end_iter , stanza + ' \n \n ' , kind )
if at_the_end :
gobject . idle_add ( self . scroll_to_end )
2005-08-04 22:32:38 +02:00
2005-07-04 23:29:22 +02:00
def on_send_button_clicked ( self , widget ) :
begin_iter , end_iter = self . input_tv_buffer . get_bounds ( )
stanza = self . input_tv_buffer . get_text ( begin_iter , end_iter )
if stanza :
gajim . connections [ self . account ] . send_stanza ( stanza )
self . input_tv_buffer . set_text ( ' ' ) # we sent ok, clear the textview
def on_presence_button_clicked ( self , widget ) :
self . input_tv_buffer . set_text (
' <presence><show></show><status></status><priority></priority></presence> '
)
def on_iq_button_clicked ( self , widget ) :
self . input_tv_buffer . set_text (
' <iq to= " " type= " " ><query xmlns= " " ></query></iq> '
)
def on_message_button_clicked ( self , widget ) :
self . input_tv_buffer . set_text (
' <message to= " " type= " " ><body></body></message> '
)
2005-07-05 01:18:05 +02:00
def on_expander_activate ( self , widget ) :
if not widget . get_expanded ( ) : # it's the opposite!
# it's expanded!!
self . input_textview . grab_focus ( )
2005-07-04 23:29:22 +02:00
def on_xml_console_window_destroy ( self , widget ) :
# remove us from open windows
del self . plugin . windows [ self . account ] [ ' xml_console ' ]
widget . destroy ( )
2005-08-01 17:02:17 +02:00
class FileTransfersWindow :
def __init__ ( self , plugin ) :
2005-08-03 16:11:51 +02:00
self . files_props = { ' r ' : { } , ' s ' : { } }
2005-08-01 17:02:17 +02:00
self . plugin = plugin
self . last_save_dir = None
self . xml = gtk . glade . XML ( GTKGUI_GLADE , ' file_transfers_window ' , APP )
self . window = self . xml . get_widget ( ' file_transfers_window ' )
self . tree = self . xml . get_widget ( ' transfers_list ' )
self . stop_button = self . xml . get_widget ( ' stop_button ' )
self . pause_button = self . xml . get_widget ( ' pause_restore_button ' )
2005-08-03 23:11:46 +02:00
self . remove_button = self . xml . get_widget ( ' remove_button ' )
2005-08-01 17:02:17 +02:00
self . notify_ft_checkbox = \
self . xml . get_widget ( ' notify_ft_complete_checkbox ' )
notify = gajim . config . get ( ' notify_on_file_complete ' )
if notify :
self . notify_ft_checkbox . set_active ( 1 )
else :
self . notify_ft_checkbox . set_active ( 0 )
self . model = gtk . ListStore ( gtk . gdk . Pixbuf , str , str , str , str , str )
self . tree . set_model ( self . model )
col = gtk . TreeViewColumn ( )
render_pixbuf = gtk . CellRendererPixbuf ( )
col . pack_start ( render_pixbuf , expand = True )
render_pixbuf . set_property ( ' xpad ' , 3 )
render_pixbuf . set_property ( ' ypad ' , 3 )
render_pixbuf . set_property ( ' yalign ' , .0 )
col . add_attribute ( render_pixbuf , " pixbuf " , 0 )
self . tree . append_column ( col )
col = gtk . TreeViewColumn ( _ ( ' File ' ) )
renderer = gtk . CellRendererText ( )
col . pack_start ( renderer , expand = False )
col . add_attribute ( renderer , ' markup ' , 1 )
renderer . set_property ( ' yalign ' , 0. )
renderer = gtk . CellRendererText ( )
col . pack_start ( renderer , expand = True )
col . add_attribute ( renderer , ' markup ' , 2 )
renderer . set_property ( ' xalign ' , 0. )
renderer . set_property ( ' yalign ' , 0. )
col . set_expand ( True )
self . tree . append_column ( col )
col = gtk . TreeViewColumn ( _ ( ' Progress ' ) )
renderer = gtk . CellRendererText ( )
renderer . set_property ( ' yalign ' , 0. )
renderer . set_property ( ' xalign ' , 0. )
col . pack_start ( renderer , expand = True )
col . set_expand ( False )
col . add_attribute ( renderer , ' text ' , 3 )
self . tree . append_column ( col )
self . set_images ( )
self . tree . get_selection ( ) . set_select_function ( self . select_func )
self . xml . signal_autoconnect ( self )
2005-08-04 13:17:16 +02:00
def show_completed ( self , jid , file_props ) :
self . window . present ( )
self . window . window . focus ( )
sectext = ' \t ' + _ ( ' Filename: %s ' ) % \
gtkgui_helpers . escape_for_pango_markup ( file_props [ ' name ' ] )
sectext + = ' \n \t ' + _ ( ' Size: %s ' ) % \
gtkgui_helpers . convert_bytes ( file_props [ ' size ' ] )
sectext + = ' \n \t ' + _ ( ' Sender: %s ' ) % \
gtkgui_helpers . escape_for_pango_markup ( jid )
InformationDialog ( _ ( ' File transfer completed ' ) , sectext ) . get_response ( )
self . tree . get_selection ( ) . unselect_all ( )
2005-08-06 18:16:40 +02:00
def show_request_error ( self , file_props ) :
self . window . present ( )
self . window . window . focus ( )
InformationDialog ( _ ( ' File transfer canceled ' ) , ' Remote host cannot connect to you. This may be due to nat network or missing file support on the remote host. ' ) . get_response ( )
self . tree . get_selection ( ) . unselect_all ( )
def show_send_error ( self , jid , file_props ) :
self . window . present ( )
self . window . window . focus ( )
InformationDialog ( _ ( ' File transfer canceled ' ) , ' You are unable to connect to remote host. This may be due to nat network. ' ) . get_response ( )
self . tree . get_selection ( ) . unselect_all ( )
def show_stopped ( self , file_props ) :
2005-08-04 13:17:16 +02:00
self . window . present ( )
self . window . window . focus ( )
sectext = ' \t ' + _ ( ' Filename: %s ' ) % \
gtkgui_helpers . escape_for_pango_markup ( file_props [ ' name ' ] )
sectext + = ' \n \t ' + _ ( ' Sender: %s ' ) % \
gtkgui_helpers . escape_for_pango_markup ( jid )
ErrorDialog ( _ ( ' File transfer stopped by the contact of the other side ' ) , \
sectext ) . get_response ( )
self . tree . get_selection ( ) . unselect_all ( )
2005-08-03 16:11:51 +02:00
def show_file_send_request ( self , account , contact ) :
dialog = gtk . FileChooserDialog ( title = _ ( ' Open File... ' ) ,
action = gtk . FILE_CHOOSER_ACTION_OPEN ,
buttons = ( gtk . STOCK_CANCEL , gtk . RESPONSE_CANCEL ,
gtk . STOCK_OPEN , gtk . RESPONSE_OK ) )
dialog . set_default_response ( gtk . RESPONSE_OK )
if self . last_save_dir and os . path . exists ( self . last_save_dir ) \
and os . path . isdir ( self . last_save_dir ) :
dialog . set_current_folder ( self . last_save_dir )
file_props = { }
response = dialog . run ( )
if response == gtk . RESPONSE_OK :
file_path = dialog . get_filename ( )
( file_dir , file_name ) = os . path . split ( file_path )
if file_dir :
self . last_save_dir = file_dir
file_props = self . get_send_file_props ( account , contact , file_path , file_name )
dialog . destroy ( )
self . add_transfer ( account , contact , file_props )
gajim . connections [ account ] . send_file_request ( file_props )
else :
dialog . destroy ( )
2005-08-01 17:02:17 +02:00
def show_file_request ( self , account , contact , file_props ) :
if file_props is None or not file_props . has_key ( ' name ' ) :
return
2005-08-04 13:17:16 +02:00
sec_text = ' \t ' + _ ( ' File: %s ' ) % \
gtkgui_helpers . escape_for_pango_markup ( file_props [ ' name ' ] )
2005-08-01 17:02:17 +02:00
if file_props . has_key ( ' size ' ) :
sec_text + = ' \n \t ' + _ ( ' Size: %s ' ) % \
gtkgui_helpers . convert_bytes ( file_props [ ' size ' ] )
if file_props . has_key ( ' mime-type ' ) :
2005-08-04 13:17:16 +02:00
sec_text + = ' \n \t ' + _ ( ' Type: %s ' ) % \
gtkgui_helpers . escape_for_pango_markup ( file_props [ ' mime-type ' ] )
2005-08-01 17:02:17 +02:00
if file_props . has_key ( ' desc ' ) :
2005-08-04 13:17:16 +02:00
sec_text + = ' \n \t ' + _ ( ' Description: %s ' ) % \
gtkgui_helpers . escape_for_pango_markup ( file_props [ ' desc ' ] )
2005-08-02 00:48:58 +02:00
prim_text = _ ( ' %s wants to send you a file: ' ) % contact . jid
2005-08-01 17:02:17 +02:00
dialog = ConfirmationDialog ( prim_text , sec_text )
if dialog . get_response ( ) == gtk . RESPONSE_OK :
2005-08-02 00:48:58 +02:00
dialog = gtk . FileChooserDialog ( title = _ ( ' Save File as... ' ) ,
2005-08-01 17:02:17 +02:00
action = gtk . FILE_CHOOSER_ACTION_SAVE ,
buttons = ( gtk . STOCK_CANCEL , gtk . RESPONSE_CANCEL ,
gtk . STOCK_SAVE , gtk . RESPONSE_OK ) )
dialog . set_current_name ( file_props [ ' name ' ] )
dialog . set_default_response ( gtk . RESPONSE_OK )
if self . last_save_dir and os . path . exists ( self . last_save_dir ) \
and os . path . isdir ( self . last_save_dir ) :
dialog . set_current_folder ( self . last_save_dir )
2005-08-04 13:17:16 +02:00
while True :
response = dialog . run ( )
if response == gtk . RESPONSE_OK :
file_path = dialog . get_filename ( )
if os . path . exists ( file_path ) :
primtext = _ ( ' This file already exists ' )
sectext = _ ( ' Would you like to overwrite it? ' )
dialog2 = ConfirmationDialog ( primtext , sectext )
if dialog2 . get_response ( ) != gtk . RESPONSE_OK :
continue
( file_dir , file_name ) = os . path . split ( file_path )
if file_dir :
self . last_save_dir = file_dir
file_props [ ' file-name ' ] = file_path
self . add_transfer ( account , contact , file_props )
gajim . connections [ account ] . send_file_approval ( file_props )
else :
gajim . connections [ account ] . send_file_rejection ( file_props )
dialog . destroy ( )
break
2005-08-01 17:02:17 +02:00
else :
gajim . connections [ account ] . send_file_rejection ( file_props )
def set_images ( self ) :
self . images = { }
self . images [ ' upload ' ] = self . window . render_icon ( gtk . STOCK_GO_UP ,
gtk . ICON_SIZE_MENU )
self . images [ ' download ' ] = self . window . render_icon ( gtk . STOCK_GO_DOWN ,
gtk . ICON_SIZE_MENU )
self . images [ ' stop ' ] = self . window . render_icon ( gtk . STOCK_STOP ,
gtk . ICON_SIZE_MENU )
2005-08-04 09:23:31 +02:00
self . images [ ' waiting ' ] = self . window . render_icon ( gtk . STOCK_REFRESH ,
2005-08-01 17:02:17 +02:00
gtk . ICON_SIZE_MENU )
self . images [ ' pause ' ] = self . window . render_icon ( gtk . STOCK_MEDIA_PAUSE ,
gtk . ICON_SIZE_MENU )
self . images [ ' ok ' ] = self . window . render_icon ( gtk . STOCK_APPLY ,
gtk . ICON_SIZE_MENU )
def set_status ( self , typ , sid , status ) :
iter = self . get_iter_by_sid ( typ , sid )
if iter is not None :
self . model . set ( iter , 0 , self . images [ status ] )
def set_progress ( self , typ , sid , transfered_size , iter = None ) :
if not self . files_props [ typ ] . has_key ( sid ) :
return
file_props = self . files_props [ typ ] [ sid ]
full_size = int ( file_props [ ' size ' ] )
if full_size == 0 :
percent = 0
else :
percent = round ( float ( transfered_size ) / full_size * 100 )
if iter is None :
iter = self . get_iter_by_sid ( typ , sid )
if iter is not None :
text = str ( percent ) + ' % \n '
if transfered_size == 0 :
text + = ' 0 '
else :
text + = gtkgui_helpers . convert_bytes ( transfered_size )
text + = ' / ' + gtkgui_helpers . convert_bytes ( full_size )
self . model . set ( iter , 3 , text )
2005-08-03 16:11:51 +02:00
if file_props [ ' type ' ] == ' r ' :
status = ' download '
else :
status = ' upload '
if file_props . has_key ( ' paused ' ) and file_props [ ' paused ' ] == True :
status = ' pause '
2005-08-04 09:23:31 +02:00
elif file_props . has_key ( ' stalled ' ) and file_props [ ' stalled ' ] == True :
status = ' waiting '
2005-08-03 16:11:51 +02:00
if file_props . has_key ( ' connected ' ) and file_props [ ' connected ' ] == False :
status = ' stop '
self . model . set ( iter , 0 , self . images [ status ] )
2005-08-01 17:02:17 +02:00
if percent == 100 :
self . set_status ( typ , sid , ' ok ' )
def get_iter_by_sid ( self , typ , sid ) :
2005-08-03 02:39:00 +02:00
''' returns iter to the row, which holds file transfer, identified by the
session id '''
2005-08-01 17:02:17 +02:00
iter = self . model . get_iter_root ( )
while iter :
2005-08-03 02:39:00 +02:00
if typ + sid == self . model [ iter ] [ 4 ] :
2005-08-01 17:02:17 +02:00
return iter
iter = self . model . iter_next ( iter )
2005-08-03 16:11:51 +02:00
def get_sid ( self ) :
rng = range ( 65 , 90 )
rng . extend ( range ( 48 , 57 ) )
char_sequence = map ( lambda e : chr ( e ) , rng )
from random import sample
return reduce ( lambda e1 , e2 : e1 + e2 ,
sample ( char_sequence , 16 ) )
def get_send_file_props ( self , account , contact , file_path , file_name ) :
file_props = { ' file-name ' : file_path , ' name ' : file_name ,
' type ' : ' s ' }
if os . path . exists ( file_path ) and os . path . isfile ( file_path ) :
stat = os . stat ( file_path )
os . stat ( file_path )
file_props [ ' size ' ] = str ( stat [ 6 ] )
file_props [ ' sid ' ] = self . get_sid ( )
file_props [ ' completed ' ] = False
file_props [ ' started ' ] = False
file_props [ ' sender ' ] = account
file_props [ ' receiver ' ] = contact
return file_props
2005-08-01 17:02:17 +02:00
def add_transfer ( self , account , contact , file_props ) :
if file_props is None :
return
self . files_props [ file_props [ ' type ' ] ] [ file_props [ ' sid ' ] ] = file_props
iter = self . model . append ( )
text_labels = ' <b> ' + _ ( ' Name: ' ) + ' </b> \n '
2005-08-03 17:51:37 +02:00
if file_props [ ' type ' ] == ' r ' :
text_labels + = ' <b> ' + _ ( ' Sender: ' ) + ' </b> '
else :
text_labels + = ' <b> ' + _ ( ' Recipient: ' ) + ' </b> '
2005-08-04 13:17:16 +02:00
text_props = gtkgui_helpers . escape_for_pango_markup ( file_props [ ' name ' ] ) + ' \n '
text_props + = gtkgui_helpers . escape_for_pango_markup ( contact . name )
2005-08-01 17:02:17 +02:00
self . model . set ( iter , 1 , text_labels , 2 , text_props , 4 , \
file_props [ ' type ' ] + file_props [ ' sid ' ] )
self . set_progress ( file_props [ ' type ' ] , file_props [ ' sid ' ] , 0 , iter )
2005-08-03 16:11:51 +02:00
if file_props . has_key ( ' started ' ) and file_props [ ' started ' ] is False :
status = ' waiting '
elif file_props [ ' type ' ] == ' r ' :
status = ' download '
else :
status = ' upload '
self . set_status ( file_props [ ' type ' ] , file_props [ ' sid ' ] , status )
2005-08-01 17:02:17 +02:00
self . window . show_all ( )
def on_transfers_list_enter_notify_event ( self , widget , event ) :
pass
def on_transfers_list_leave_notify_event ( self , widget , event ) :
pass
def on_transfers_list_row_activated ( self , widget , path , col ) :
# try to open the file
pass
def is_transfer_paused ( self , file_props ) :
if file_props . has_key ( ' error ' ) and file_props [ ' error ' ] != 0 :
return False
if file_props [ ' completed ' ] or file_props [ ' disconnect_cb ' ] is None :
return False
return file_props [ ' paused ' ]
def is_transfer_active ( self , file_props ) :
if file_props . has_key ( ' error ' ) and file_props [ ' error ' ] != 0 :
return False
if file_props [ ' completed ' ] or file_props [ ' disconnect_cb ' ] is None :
return False
return not file_props [ ' paused ' ]
def is_transfer_stoped ( self , file_props ) :
if file_props . has_key ( ' error ' ) and file_props [ ' error ' ] != 0 :
return True
2005-08-03 16:11:51 +02:00
if file_props . has_key ( ' completed ' ) and file_props [ ' completed ' ] :
2005-08-01 17:02:17 +02:00
return True
if file_props . has_key ( ' disconnect_cb ' ) and \
file_props [ ' disconnect_cb ' ] is not None :
return False
return True
def select_func ( self , path ) :
is_selected = False
current_iter = self . model . get_iter ( path )
selected = self . tree . get_selection ( ) . get_selected ( )
if selected [ 1 ] != None :
selected_path = self . model . get_path ( selected [ 1 ] )
if selected_path == path :
is_selected = True
sid = self . model [ current_iter ] [ 4 ]
file_props = self . files_props [ sid [ 0 ] ] [ sid [ 1 : ] ]
2005-08-04 09:23:31 +02:00
self . remove_button . set_property ( ' sensitive ' , not is_selected )
2005-08-01 17:02:17 +02:00
if self . is_transfer_stoped ( file_props ) :
is_selected = True
self . stop_button . set_property ( ' sensitive ' , not is_selected )
if is_selected :
self . pause_button . set_property ( ' sensitive ' , False )
else :
if self . is_transfer_active ( file_props ) :
self . pause_button . set_property ( ' sensitive ' , True )
self . pause_button . set_label ( _ ( ' _Pause ' ) )
elif self . is_transfer_paused ( file_props ) :
self . pause_button . set_property ( ' sensitive ' , True )
self . pause_button . set_label ( _ ( ' _Continue ' ) )
else :
self . pause_button . set_property ( ' sensitive ' , False )
return True
2005-08-03 02:39:00 +02:00
def on_remove_button_clicked ( self , widget ) :
2005-08-01 17:02:17 +02:00
selected = self . tree . get_selection ( ) . get_selected ( )
if selected is None or selected [ 1 ] is None :
return
s_iter = selected [ 1 ]
sid = self . model [ s_iter ] [ 4 ]
file_props = self . files_props [ sid [ 0 ] ] [ sid [ 1 : ] ]
if not self . is_transfer_stoped ( file_props ) :
file_props [ ' disconnect_cb ' ] ( )
self . model . remove ( s_iter )
2005-08-04 09:23:31 +02:00
self . remove_button . set_property ( ' sensitive ' , False )
2005-08-01 17:02:17 +02:00
def on_pause_restore_button_clicked ( self , widget ) :
selected = self . tree . get_selection ( ) . get_selected ( )
if selected is None or selected [ 1 ] is None :
return
s_iter = selected [ 1 ]
sid = self . model [ s_iter ] [ 4 ]
file_props = self . files_props [ sid [ 0 ] ] [ sid [ 1 : ] ]
if self . is_transfer_paused ( file_props ) :
file_props [ ' paused ' ] = False
2005-08-01 18:14:35 +02:00
types = { ' r ' : ' download ' , ' s ' : ' upload ' }
2005-08-01 17:02:17 +02:00
self . set_status ( file_props [ ' type ' ] , file_props [ ' sid ' ] , types [ sid [ 0 ] ] )
widget . set_label ( _ ( ' Pause ' ) )
elif self . is_transfer_active ( file_props ) :
file_props [ ' paused ' ] = True
self . set_status ( file_props [ ' type ' ] , file_props [ ' sid ' ] , ' pause ' )
widget . set_label ( _ ( ' _Continue ' ) )
def on_stop_button_clicked ( self , widget ) :
selected = self . tree . get_selection ( ) . get_selected ( )
if selected is None or selected [ 1 ] is None :
return
s_iter = selected [ 1 ]
sid = self . model [ s_iter ] [ 4 ]
2005-08-03 17:51:37 +02:00
2005-08-01 17:02:17 +02:00
file_props = self . files_props [ sid [ 0 ] ] [ sid [ 1 : ] ]
if not self . is_transfer_stoped ( file_props ) :
file_props [ ' disconnect_cb ' ] ( )
self . set_status ( file_props [ ' type ' ] , file_props [ ' sid ' ] , ' stop ' )
def on_notify_ft_complete_checkbox_toggled ( self , widget ) :
gajim . config . set ( ' notify_on_file_complete ' ,
widget . get_active ( ) )
def on_file_transfers_dialog_delete_event ( self , widget , event ) :
self . window . hide ( )
2005-08-03 02:39:00 +02:00
return True # do NOT destory window
2005-08-01 17:02:17 +02:00
2005-08-03 17:59:44 +02:00
def on_close_button_clicked ( self , widget ) :
self . window . hide ( )