merged trunk

This commit is contained in:
Brendan Taylor 2008-02-14 02:20:07 +00:00
parent 867955155f
commit c8cae71099
13 changed files with 686 additions and 662 deletions

File diff suppressed because it is too large Load Diff

View File

@ -281,7 +281,7 @@ class ChatControlBase(MessageControl):
self.conv_textview.tv.show() self.conv_textview.tv.show()
self._paint_banner() self._paint_banner()
# For JEP-0172 # For XEP-0172
self.user_nick = None self.user_nick = None
self.smooth = True self.smooth = True

View File

@ -296,6 +296,7 @@ class Config:
'keep_alives_enabled': [ opt_bool, True], 'keep_alives_enabled': [ opt_bool, True],
# send keepalive every N seconds of inactivity # send keepalive every N seconds of inactivity
'keep_alive_every_foo_secs': [ opt_int, 55 ], 'keep_alive_every_foo_secs': [ opt_int, 55 ],
'time_for_keep_alive_answer': [ opt_int, 20, _('How many seconds to wait for the answer of keepalive packet before we try to reconnect.') ],
# try for 2 minutes before giving up (aka. timeout after those seconds) # try for 2 minutes before giving up (aka. timeout after those seconds)
'try_connecting_for_foo_secs': [ opt_int, 60 ], 'try_connecting_for_foo_secs': [ opt_int, 60 ],
'http_auth': [opt_str, 'ask'], # yes, no, ask 'http_auth': [opt_str, 'ask'], # yes, no, ask

View File

@ -705,11 +705,21 @@ class Connection(ConnectionHandlers):
return return
common.xmpp.features_nb.getPrivacyLists(self.connection) common.xmpp.features_nb.getPrivacyLists(self.connection)
def sendPing(self, pingTo): def sendPing(self, pingTo=None):
'''Send XMPP Ping (XEP-0199) request. If pingTo is not set, ping is sent
to server to detect connection failure at application level.'''
if not self.connection: if not self.connection:
return return
iq = common.xmpp.Iq('get', to = pingTo.get_full_jid()) id = self.connection.getAnID()
if pingTo:
to = pingTo.get_full_jid()
self.dispatch('PING_SENT', (pingTo))
else:
to = gajim.config.get_per('accounts', self.name, 'hostname')
self.awaiting_xmpp_ping_id = id
iq = common.xmpp.Iq('get', to=to)
iq.addChild(name = 'ping', namespace = common.xmpp.NS_PING) iq.addChild(name = 'ping', namespace = common.xmpp.NS_PING)
iq.setID(id)
def _on_response(resp): def _on_response(resp):
timePong = time_time() timePong = time_time()
if not common.xmpp.isResultNode(resp): if not common.xmpp.isResultNode(resp):
@ -717,9 +727,13 @@ class Connection(ConnectionHandlers):
return return
timeDiff = round(timePong - timePing,2) timeDiff = round(timePong - timePing,2)
self.dispatch('PING_REPLY', (pingTo, timeDiff)) self.dispatch('PING_REPLY', (pingTo, timeDiff))
self.dispatch('PING_SENT', (pingTo)) if pingTo:
timePing = time_time() timePing = time_time()
self.connection.SendAndCallForResponse(iq, _on_response) self.connection.SendAndCallForResponse(iq, _on_response)
else:
self.connection.send(iq)
gajim.idlequeue.set_alarm(self.check_keepalive, gajim.config.get_per(
'accounts', self.name, 'time_for_keep_alive_answer'))
def get_active_default_lists(self): def get_active_default_lists(self):
if not self.connection: if not self.connection:
@ -877,7 +891,7 @@ class Connection(ConnectionHandlers):
self.connection = con self.connection = con
if not self.connection: if not self.connection:
return return
self.connection.set_send_timeout(self.keepalives, self.send_keepalive) self.connection.set_send_timeout(self.keepalives, self.sendPing)
self.connection.onreceive(None) self.connection.onreceive(None)
iq = common.xmpp.Iq('get', common.xmpp.NS_PRIVACY, xmlns = '') iq = common.xmpp.Iq('get', common.xmpp.NS_PRIVACY, xmlns = '')
id = self.connection.getAnID() id = self.connection.getAnID()
@ -922,7 +936,7 @@ class Connection(ConnectionHandlers):
if not auto and not show == 'offline': if not auto and not show == 'offline':
sign_msg = True sign_msg = True
self.status = msg self.status = msg
if show != 'offline' and not self.connected: if show != 'offline' and self.connected < 1:
# set old_show to requested 'show' in case we need to # set old_show to requested 'show' in case we need to
# recconect before we auth to server # recconect before we auth to server
self.old_show = show self.old_show = show
@ -955,7 +969,7 @@ class Connection(ConnectionHandlers):
self.time_to_reconnect = None self.time_to_reconnect = None
self._on_disconnected() self._on_disconnected()
elif show != 'offline' and self.connected: elif show != 'offline' and self.connected > 0:
# dont'try to connect, when we are in state 'connecting' # dont'try to connect, when we are in state 'connecting'
if self.connected == 1: if self.connected == 1:
return return
@ -1257,6 +1271,7 @@ class Connection(ConnectionHandlers):
iq.setID(id) iq.setID(id)
if groupchat_jid: if groupchat_jid:
self.groupchat_jids[id] = groupchat_jid self.groupchat_jids[id] = groupchat_jid
self.last_ids.append(id)
self.connection.send(iq) self.connection.send(iq)
def request_os_info(self, jid, resource, groupchat_jid=None): def request_os_info(self, jid, resource, groupchat_jid=None):
@ -1277,6 +1292,7 @@ class Connection(ConnectionHandlers):
iq.setID(id) iq.setID(id)
if groupchat_jid: if groupchat_jid:
self.groupchat_jids[id] = groupchat_jid self.groupchat_jids[id] = groupchat_jid
self.version_ids.append(id)
self.connection.send(iq) self.connection.send(iq)
def get_settings(self): def get_settings(self):
@ -1599,10 +1615,10 @@ class Connection(ConnectionHandlers):
c.setTagData('reason', reason) c.setTagData('reason', reason)
self.connection.send(message) self.connection.send(message)
def send_keepalive(self): def check_keepalive(self):
# nothing received for the last foo seconds (60 secs by default) if self.awaiting_xmpp_ping_id:
if self.connection: # We haven't got the pong in time, disco and reconnect
self.connection.send(' ') self._disconnectedReconnCB()
def _reconnect_alarm(self): def _reconnect_alarm(self):
if self.time_to_reconnect: if self.time_to_reconnect:

View File

@ -426,6 +426,9 @@ class ConnectionBytestream:
# if we want to respect xep-0065 we have to check for proxy # if we want to respect xep-0065 we have to check for proxy
# activation result in any result iq # activation result in any result iq
real_id = unicode(iq_obj.getAttr('id')) real_id = unicode(iq_obj.getAttr('id'))
if real_id == self.awaiting_xmpp_ping_id:
self.awaiting_xmpp_ping_id = None
return
if real_id[:3] != 'au_': if real_id[:3] != 'au_':
return return
frm = helpers.get_full_jid_from_iq(iq_obj) frm = helpers.get_full_jid_from_iq(iq_obj)
@ -667,8 +670,8 @@ class ConnectionDisco:
query = iq.setTag('query') query = iq.setTag('query')
query.setAttr('node','http://gajim.org/caps#' + gajim.version.split('-', query.setAttr('node','http://gajim.org/caps#' + gajim.version.split('-',
1)[0]) 1)[0])
for f in (common.xmpp.NS_BYTESTREAM, common.xmpp.NS_SI, \ for f in (common.xmpp.NS_BYTESTREAM, common.xmpp.NS_SI,
common.xmpp.NS_FILE, common.xmpp.NS_COMMANDS): common.xmpp.NS_FILE, common.xmpp.NS_COMMANDS):
feature = common.xmpp.Node('feature') feature = common.xmpp.Node('feature')
feature.setAttr('var', f) feature.setAttr('var', f)
query.addChild(node=feature) query.addChild(node=feature)
@ -1240,6 +1243,12 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
# keep the latest subscribed event for each jid to prevent loop when we # keep the latest subscribed event for each jid to prevent loop when we
# acknoledge presences # acknoledge presences
self.subscribed_events = {} self.subscribed_events = {}
# IDs of jabber:iq:last requests
self.last_ids = []
# IDs of jabber:iq:version requests
self.version_ids = []
# ID of urn:xmpp:ping requests
self.awaiting_xmpp_ping_id = None
# keep track of sessions this connection has with other JIDs # keep track of sessions this connection has with other JIDs
self.sessions = {} self.sessions = {}
@ -1298,15 +1307,21 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
def _ErrorCB(self, con, iq_obj): def _ErrorCB(self, con, iq_obj):
gajim.log.debug('ErrorCB') gajim.log.debug('ErrorCB')
if iq_obj.getQueryNS() == common.xmpp.NS_VERSION: jid_from = helpers.get_full_jid_from_iq(iq_obj)
who = helpers.get_full_jid_from_iq(iq_obj) jid_stripped, resource = gajim.get_room_and_nick_from_fjid(jid_from)
jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who) id = unicode(iq_obj.getID())
if id in self.version_ids:
self.dispatch('OS_INFO', (jid_stripped, resource, '', '')) self.dispatch('OS_INFO', (jid_stripped, resource, '', ''))
self.version_ids.remove(id)
return return
if id in self.last_ids:
self.dispatch('LAST_STATUS_TIME', (jid_stripped, resource, -1, ''))
self.last_ids.remove(id)
return
if id == self.awaiting_xmpp_ping_id:
self.awaiting_xmpp_ping_id = None
errmsg = iq_obj.getErrorMsg() errmsg = iq_obj.getErrorMsg()
errcode = iq_obj.getErrorCode() errcode = iq_obj.getErrorCode()
jid_from = helpers.get_full_jid_from_iq(iq_obj)
id = unicode(iq_obj.getID())
self.dispatch('ERROR_ANSWER', (id, jid_from, errmsg, errcode)) self.dispatch('ERROR_ANSWER', (id, jid_from, errmsg, errcode))
def _PrivateCB(self, con, iq_obj): def _PrivateCB(self, con, iq_obj):
@ -1393,9 +1408,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
qp.setTagData('os', helpers.get_os_info()) qp.setTagData('os', helpers.get_os_info())
self.connection.send(iq_obj) self.connection.send(iq_obj)
raise common.xmpp.NodeProcessed raise common.xmpp.NodeProcessed
def _LastCB(self, con, iq_obj): def _LastCB(self, con, iq_obj):
gajim.log.debug('IdleCB') gajim.log.debug('LastCB')
iq_obj = iq_obj.buildReply('result') iq_obj = iq_obj.buildReply('result')
qp = iq_obj.getTag('query') qp = iq_obj.getTag('query')
if not HAS_IDLE: if not HAS_IDLE:
@ -1405,7 +1420,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
self.connection.send(iq_obj) self.connection.send(iq_obj)
raise common.xmpp.NodeProcessed raise common.xmpp.NodeProcessed
def _LastResultCB(self, con, iq_obj): def _LastResultCB(self, con, iq_obj):
gajim.log.debug('LastResultCB') gajim.log.debug('LastResultCB')
qp = iq_obj.getTag('query') qp = iq_obj.getTag('query')
@ -1421,9 +1436,11 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
del self.groupchat_jids[id] del self.groupchat_jids[id]
else: else:
who = helpers.get_full_jid_from_iq(iq_obj) who = helpers.get_full_jid_from_iq(iq_obj)
if id in self.last_ids:
self.last_ids.remove(id)
jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who) jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who)
self.dispatch('LAST_STATUS_TIME', (jid_stripped, resource, seconds, status)) self.dispatch('LAST_STATUS_TIME', (jid_stripped, resource, seconds, status))
def _VersionResultCB(self, con, iq_obj): def _VersionResultCB(self, con, iq_obj):
gajim.log.debug('VersionResultCB') gajim.log.debug('VersionResultCB')
client_info = '' client_info = ''
@ -1442,6 +1459,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
else: else:
who = helpers.get_full_jid_from_iq(iq_obj) who = helpers.get_full_jid_from_iq(iq_obj)
jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who) jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who)
if id in self.version_ids:
self.version_ids.remove(id)
self.dispatch('OS_INFO', (jid_stripped, resource, client_info, os_info)) self.dispatch('OS_INFO', (jid_stripped, resource, client_info, os_info))
def _TimeCB(self, con, iq_obj): def _TimeCB(self, con, iq_obj):

View File

@ -298,27 +298,20 @@ class PreferencesWindow:
self.auto_popup_away_checkbutton.set_active(st) self.auto_popup_away_checkbutton.set_active(st)
# sounds # sounds
if ((os.name == 'nt') or (sys.platform == 'darwin')):
# if windows, player must not become visible on show_all
soundplayer_hbox = self.xml.get_widget('soundplayer_hbox')
soundplayer_hbox.set_no_show_all(True)
if gajim.config.get('sounds_on'): if gajim.config.get('sounds_on'):
self.xml.get_widget('play_sounds_checkbutton').set_active(True) self.xml.get_widget('play_sounds_checkbutton').set_active(True)
else: else:
self.xml.get_widget('soundplayer_hbox').set_sensitive(False)
self.xml.get_widget('sounds_scrolledwindow').set_sensitive(False) self.xml.get_widget('sounds_scrolledwindow').set_sensitive(False)
self.xml.get_widget('browse_sounds_hbox').set_sensitive(False) self.xml.get_widget('browse_sounds_hbox').set_sensitive(False)
# sound player # sound player
player = gajim.config.get('soundplayer') player = gajim.config.get('soundplayer')
self.xml.get_widget('soundplayer_entry').set_text(player)
if player == '': # only on first time Gajim starts if player == '': # only on first time Gajim starts
commands = ('aplay', 'play', 'esdplay', 'artsplay') commands = ('aplay', 'play', 'esdplay', 'artsplay')
for command in commands: for command in commands:
if helpers.is_in_path(command): if helpers.is_in_path(command):
if command == 'aplay': if command == 'aplay':
command += ' -q' command += ' -q'
self.xml.get_widget('soundplayer_entry').set_text(command)
gajim.config.set('soundplayer', command) gajim.config.set('soundplayer', command)
break break
@ -775,14 +768,9 @@ class PreferencesWindow:
def on_play_sounds_checkbutton_toggled(self, widget): def on_play_sounds_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'sounds_on', self.on_checkbutton_toggled(widget, 'sounds_on',
[self.xml.get_widget('soundplayer_hbox'), [self.xml.get_widget('sounds_scrolledwindow'),
self.xml.get_widget('sounds_scrolledwindow'),
self.xml.get_widget('browse_sounds_hbox')]) self.xml.get_widget('browse_sounds_hbox')])
def on_soundplayer_entry_changed(self, widget):
gajim.config.set('soundplayer', widget.get_text().decode('utf-8'))
gajim.interface.save_config()
def on_sounds_treemodel_row_changed(self, model, path, iter): def on_sounds_treemodel_row_changed(self, model, path, iter):
sound_event = model[iter][3].decode('utf-8') sound_event = model[iter][3].decode('utf-8')
gajim.config.set_per('soundevents', sound_event, 'enabled', gajim.config.set_per('soundevents', sound_event, 'enabled',

View File

@ -936,7 +936,7 @@ class AboutDialog:
dlg.set_transient_for(gajim.interface.roster.window) dlg.set_transient_for(gajim.interface.roster.window)
dlg.set_name('Gajim') dlg.set_name('Gajim')
dlg.set_version(gajim.version) dlg.set_version(gajim.version)
s = u'Copyright © 2003-2007 Gajim Team' s = u'Copyright © 2003-2008 Gajim Team'
dlg.set_copyright(s) dlg.set_copyright(s)
copying_file_path = None copying_file_path = None
if os.path.isfile(os.path.join(gajim.defs.docdir, 'COPYING')): if os.path.isfile(os.path.join(gajim.defs.docdir, 'COPYING')):

View File

@ -142,7 +142,10 @@ class FeaturesWindow:
selection = widget.get_selection() selection = widget.get_selection()
if not selection: if not selection:
return return
path = selection.get_selected_rows()[1][0] rows = selection.get_selected_rows()[1]
if not rows:
return
path = rows[0]
available = self.model[path][1] available = self.model[path][1]
feature = self.model[path][0].decode('utf-8') feature = self.model[path][0].decode('utf-8')
text = self.features[feature][1] + '\n' text = self.features[feature][1] + '\n'

View File

@ -59,7 +59,7 @@ BASENAME = 'gajim-remote'
class GajimRemote: class GajimRemote:
def __init__(self): def __init__(self):
self.argv_len = len(sys.argv) self.argv_len = len(sys.argv)
# define commands dict. Prototype : # define commands dict. Prototype :
# { # {
# 'command': [comment, [list of arguments] ] # 'command': [comment, [list of arguments] ]
@ -73,14 +73,14 @@ class GajimRemote:
_('Shows a help on specific command'), _('Shows a help on specific command'),
[ [
#User gets help for the command, specified by this parameter #User gets help for the command, specified by this parameter
(_('command'), (_('command'),
_('show help on command'), False) _('show help on command'), False)
] ]
], ],
'toggle_roster_appearance' : [ 'toggle_roster_appearance' : [
_('Shows or hides the roster window'), _('Shows or hides the roster window'),
[] []
], ],
'show_next_pending_event': [ 'show_next_pending_event': [
_('Pops up a window with the next pending event'), _('Pops up a window with the next pending event'),
[] []
@ -93,27 +93,27 @@ class GajimRemote:
False) False)
] ]
], ],
'list_accounts': [ 'list_accounts': [
_('Prints a list of registered accounts'), _('Prints a list of registered accounts'),
[] []
], ],
'change_status': [ 'change_status': [
_('Changes the status of account or accounts'), _('Changes the status of account or accounts'),
[ [
#offline, online, chat, away, xa, dnd, invisible should not be translated #offline, online, chat, away, xa, dnd, invisible should not be translated
(_('status'), _('one of: offline, online, chat, away, xa, dnd, invisible '), True), (_('status'), _('one of: offline, online, chat, away, xa, dnd, invisible '), True),
(_('message'), _('status message'), False), (_('message'), _('status message'), False),
(_('account'), _('change status of account "account". ' (_('account'), _('change status of account "account". '
'If not specified, try to change status of all accounts that have ' 'If not specified, try to change status of all accounts that have '
'"sync with global status" option set'), False) '"sync with global status" option set'), False)
] ]
], ],
'open_chat': [ 'open_chat': [
_('Shows the chat dialog so that you can send messages to a contact'), _('Shows the chat dialog so that you can send messages to a contact'),
[ [
('jid', _('JID of the contact that you want to chat with'), ('jid', _('JID of the contact that you want to chat with'),
True), True),
(_('account'), _('if specified, contact is taken from the ' (_('account'), _('if specified, contact is taken from the '
'contact list of this account'), False) 'contact list of this account'), False)
] ]
@ -121,7 +121,7 @@ class GajimRemote:
'send_chat_message':[ 'send_chat_message':[
_('Sends new chat message to a contact in the roster. Both OpenPGP key ' _('Sends new chat message to a contact in the roster. Both OpenPGP key '
'and account are optional. If you want to set only \'account\', ' 'and account are optional. If you want to set only \'account\', '
'without \'OpenPGP key\', just set \'OpenPGP key\' to \'\'.'), 'without \'OpenPGP key\', just set \'OpenPGP key\' to \'\'.'),
[ [
('jid', _('JID of the contact that will receive the message'), True), ('jid', _('JID of the contact that will receive the message'), True),
(_('message'), _('message contents'), True), (_('message'), _('message contents'), True),
@ -134,7 +134,7 @@ class GajimRemote:
'send_single_message':[ 'send_single_message':[
_('Sends new single message to a contact in the roster. Both OpenPGP key ' _('Sends new single message to a contact in the roster. Both OpenPGP key '
'and account are optional. If you want to set only \'account\', ' 'and account are optional. If you want to set only \'account\', '
'without \'OpenPGP key\', just set \'OpenPGP key\' to \'\'.'), 'without \'OpenPGP key\', just set \'OpenPGP key\' to \'\'.'),
[ [
('jid', _('JID of the contact that will receive the message'), True), ('jid', _('JID of the contact that will receive the message'), True),
(_('subject'), _('message subject'), True), (_('subject'), _('message subject'), True),
@ -144,9 +144,9 @@ class GajimRemote:
(_('account'), _('if specified, the message will be sent ' (_('account'), _('if specified, the message will be sent '
'using this account'), False), 'using this account'), False),
] ]
], ],
'send_groupchat_message':[ 'send_groupchat_message':[
_('Sends new message to a groupchat you\'ve joined.'), _('Sends new message to a groupchat you\'ve joined.'),
[ [
('room_jid', _('JID of the room that will receive the message'), True), ('room_jid', _('JID of the room that will receive the message'), True),
(_('message'), _('message contents'), True), (_('message'), _('message contents'), True),
@ -155,13 +155,13 @@ class GajimRemote:
] ]
], ],
'contact_info': [ 'contact_info': [
_('Gets detailed info on a contact'), _('Gets detailed info on a contact'),
[ [
('jid', _('JID of the contact'), True) ('jid', _('JID of the contact'), True)
] ]
], ],
'account_info': [ 'account_info': [
_('Gets detailed info on a account'), _('Gets detailed info on a account'),
[ [
('account', _('Name of the account'), True) ('account', _('Name of the account'), True)
] ]
@ -188,8 +188,8 @@ class GajimRemote:
], ],
'prefs_del': [ 'prefs_del': [
_('Deletes a preference item'), _('Deletes a preference item'),
[ [
(_('key'), _('name of the preference to be deleted'), True) (_('key'), _('name of the preference to be deleted'), True)
] ]
], ],
'prefs_store': [ 'prefs_store': [
@ -199,7 +199,7 @@ class GajimRemote:
], ],
'remove_contact': [ 'remove_contact': [
_('Removes contact from roster'), _('Removes contact from roster'),
[ [
('jid', _('JID of the contact'), True), ('jid', _('JID of the contact'), True),
(_('account'), _('if specified, contact is taken from the ' (_('account'), _('if specified, contact is taken from the '
'contact list of this account'), False) 'contact list of this account'), False)
@ -208,7 +208,7 @@ class GajimRemote:
], ],
'add_contact': [ 'add_contact': [
_('Adds contact to roster'), _('Adds contact to roster'),
[ [
(_('jid'), _('JID of the contact'), True), (_('jid'), _('JID of the contact'), True),
(_('account'), _('Adds new contact to this account'), False) (_('account'), _('Adds new contact to this account'), False)
] ]
@ -226,7 +226,7 @@ class GajimRemote:
[ [
(_('account'), _(''), False) (_('account'), _(''), False)
] ]
], ],
'get_unread_msgs_number': [ 'get_unread_msgs_number': [
_('Returns number of unread messages'), _('Returns number of unread messages'),
@ -239,7 +239,7 @@ class GajimRemote:
] ]
], ],
'send_xml': [ 'send_xml': [
_('Sends custom XML'), _('Sends custom XML'),
[ [
('xml', _('XML to send'), True), ('xml', _('XML to send'), True),
('account', _('Account in which the xml will be sent; ' ('account', _('Account in which the xml will be sent; '
@ -263,8 +263,13 @@ class GajimRemote:
(_('account'), _(''), False) (_('account'), _(''), False)
] ]
], ],
'check_gajim_running':[
_('Check if Gajim is running'),
[]
],
} }
self.sbus = None
if self.argv_len < 2 or \ if self.argv_len < 2 or \
sys.argv[1] not in self.commands.keys(): # no args or bad args sys.argv[1] not in self.commands.keys(): # no args or bad args
send_error(self.compose_help()) send_error(self.compose_help())
@ -277,6 +282,9 @@ class GajimRemote:
sys.exit(0) sys.exit(0)
if self.command == 'handle_uri': if self.command == 'handle_uri':
self.handle_uri() self.handle_uri()
if self.command == 'check_gajim_running':
print self.check_gajim_running()
sys.exit(0)
self.init_connection() self.init_connection()
self.check_arguments() self.check_arguments()
@ -323,7 +331,7 @@ class GajimRemote:
pref_keys.sort() pref_keys.sort()
for pref_key in pref_keys: for pref_key in pref_keys:
result = '%s = %s' % (pref_key, res[pref_key]) result = '%s = %s' % (pref_key, res[pref_key])
if isinstance(result, unicode): if isinstance(result, unicode):
print result.encode(PREFERRED_ENCODING) print result.encode(PREFERRED_ENCODING)
else: else:
print result print result
@ -332,6 +340,22 @@ class GajimRemote:
elif res: elif res:
print unicode(res).encode(PREFERRED_ENCODING) print unicode(res).encode(PREFERRED_ENCODING)
def check_gajim_running(self):
if not self.sbus:
try:
self.sbus = dbus.SessionBus()
except:
raise exceptions.SessionBusNotPresent
test = False
if hasattr(self.sbus, 'name_has_owner'):
if self.sbus.name_has_owner(SERVICE):
test = True
elif dbus.dbus_bindings.bus_name_has_owner(self.sbus.get_connection(),
SERVICE):
test = True
return test
def init_connection(self): def init_connection(self):
''' create the onnection to the session dbus, ''' create the onnection to the session dbus,
or exit if it is not possible ''' or exit if it is not possible '''
@ -340,6 +364,8 @@ class GajimRemote:
except: except:
raise exceptions.SessionBusNotPresent raise exceptions.SessionBusNotPresent
if not self.check_gajim_running():
send_error(_('It seems Gajim is not running. So you can\'t use gajim-remote.'))
obj = self.sbus.get_object(SERVICE, OBJ_PATH) obj = self.sbus.get_object(SERVICE, OBJ_PATH)
interface = dbus.Interface(obj, INTERFACE) interface = dbus.Interface(obj, INTERFACE)
@ -368,7 +394,7 @@ class GajimRemote:
if command in self.commands: if command in self.commands:
command_props = self.commands[command] command_props = self.commands[command]
arguments_str = self.make_arguments_row(command_props[1]) arguments_str = self.make_arguments_row(command_props[1])
str = _('Usage: %s %s %s \n\t %s') % (BASENAME, command, str = _('Usage: %s %s %s \n\t %s') % (BASENAME, command,
arguments_str, command_props[0]) arguments_str, command_props[0])
if len(command_props[1]) > 0: if len(command_props[1]) > 0:
str += '\n\n' + _('Arguments:') + '\n' str += '\n\n' + _('Arguments:') + '\n'
@ -383,7 +409,7 @@ class GajimRemote:
commands = self.commands.keys() commands = self.commands.keys()
commands.sort() commands.sort()
for command in commands: for command in commands:
str += ' ' + command str += ' ' + command
for argument in self.commands[command][1]: for argument in self.commands[command][1]:
str += ' ' str += ' '
if argument[2]: if argument[2]:
@ -457,7 +483,7 @@ class GajimRemote:
if len(args) > argv_len: if len(args) > argv_len:
if args[argv_len][2]: if args[argv_len][2]:
send_error(_('Argument "%s" is not specified. \n' send_error(_('Argument "%s" is not specified. \n'
'Type "%s help %s" for more info') % 'Type "%s help %s" for more info') %
(args[argv_len][0], BASENAME, self.command)) (args[argv_len][0], BASENAME, self.command))
self.arguments = [] self.arguments = []
i = 0 i = 0
@ -485,7 +511,7 @@ class GajimRemote:
if action == 'join': if action == 'join':
self.command = sys.argv[1] = 'join_room' self.command = sys.argv[1] = 'join_room'
return return
sys.exit(0) sys.exit(0)
def call_remote_method(self): def call_remote_method(self):

View File

@ -720,12 +720,6 @@ class Interface:
elif new_show > 1: # Status change (not connected/disconnected or error (<1)) elif new_show > 1: # Status change (not connected/disconnected or error (<1))
notify.notify('status_change', jid, account, [new_show, notify.notify('status_change', jid, account, [new_show,
status_message]) status_message])
else:
# FIXME: Msn transport (CMSN1.2.1 and PyMSN0.10) doesn't follow the JEP
# remove in 2007
# It's maybe a GC_NOTIFY (specialy for MSN gc)
self.handle_event_gc_notify(account, (jid, array[1], status_message,
array[3], None, None, None, None, None, [], None, None))
def handle_event_msgerror(self, account, array): def handle_event_msgerror(self, account, array):
#'MSGERROR' (account, (jid, error_code, error_msg, msg, time)) #'MSGERROR' (account, (jid, error_code, error_msg, msg, time))
@ -989,6 +983,10 @@ class Interface:
def handle_event_last_status_time(self, account, array): def handle_event_last_status_time(self, account, array):
# ('LAST_STATUS_TIME', account, (jid, resource, seconds, status)) # ('LAST_STATUS_TIME', account, (jid, resource, seconds, status))
tim = array[2]
if tim < 0:
# Ann error occured
return
win = None win = None
if self.instances[account]['infos'].has_key(array[0]): if self.instances[account]['infos'].has_key(array[0]):
win = self.instances[account]['infos'][array[0]] win = self.instances[account]['infos'][array[0]]
@ -997,7 +995,7 @@ class Interface:
if win: if win:
c = gajim.contacts.get_contact(account, array[0], array[1]) c = gajim.contacts.get_contact(account, array[0], array[1])
if c: # c can be none if it's a gc contact if c: # c can be none if it's a gc contact
c.last_status_time = time.localtime(time.time() - array[2]) c.last_status_time = time.localtime(time.time() - tim)
if array[3]: if array[3]:
c.status = array[3] c.status = array[3]
win.set_last_status_time() win.set_last_status_time()

View File

@ -939,19 +939,18 @@ class GroupchatControl(ChatControlBase):
model[iter][C_TEXT] = name model[iter][C_TEXT] = name
def draw_avatar(self, nick): def draw_avatar(self, nick):
if not gajim.config.get('show_avatars_in_roster'):
return
model = self.list_treeview.get_model() model = self.list_treeview.get_model()
iter = self.get_contact_iter(nick) iter = self.get_contact_iter(nick)
if not iter: if not iter:
return return
if gajim.config.get('show_avatars_in_roster'): pixbuf = gtkgui_helpers.get_avatar_pixbuf_from_cache(self.room_jid + \
pixbuf = gtkgui_helpers.get_avatar_pixbuf_from_cache(self.room_jid + \ '/' + nick, True)
'/' + nick, True) if pixbuf in ('ask', None):
if pixbuf in ('ask', None):
scaled_pixbuf = None
else:
scaled_pixbuf = gtkgui_helpers.get_scaled_pixbuf(pixbuf, 'roster')
else:
scaled_pixbuf = None scaled_pixbuf = None
else:
scaled_pixbuf = gtkgui_helpers.get_scaled_pixbuf(pixbuf, 'roster')
model[iter][C_AVATAR] = scaled_pixbuf model[iter][C_AVATAR] = scaled_pixbuf
def chg_contact_status(self, nick, show, status, role, affiliation, jid, def chg_contact_status(self, nick, show, status, role, affiliation, jid,

View File

@ -4,12 +4,12 @@
## Vincent Hanquez <tab@snarc.org> ## Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Yann Leboulanger <asterix@lagaule.org> ## Copyright (C) 2005 Yann Leboulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org> ## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <kourem@gmail.com>
## Dimitur Kirov <dkirov@gmail.com> ## Dimitur Kirov <dkirov@gmail.com>
## Norman Rasmussen <norman@rasmussen.co.za> ## Norman Rasmussen <norman@rasmussen.co.za>
## Copyright (C) 2005-2007 Travis Shirk <travis@pobox.com> ## Copyright (C) 2005-2007 Travis Shirk <travis@pobox.com>
## Copyright (C) 2006 Geobert Quach <geobert@gmail.com> ## Copyright (C) 2006 Geobert Quach <geobert@gmail.com>
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de> ## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de>
## Copyright (C) 2005-2008 Nikos Kouremenos <kourem@gmail.com>
## ##
## This file is part of Gajim. ## This file is part of Gajim.
## ##
@ -123,7 +123,9 @@ class MessageWindow(object):
else: else:
nb_pos = gtk.POS_TOP nb_pos = gtk.POS_TOP
self.notebook.set_tab_pos(nb_pos) self.notebook.set_tab_pos(nb_pos)
if gajim.config.get('tabs_always_visible'): window_mode = gajim.interface.msg_win_mgr.mode
if gajim.config.get('tabs_always_visible') or \
window_mode == MessageWindowMgr.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER:
self.notebook.set_show_tabs(True) self.notebook.set_show_tabs(True)
self.alignment.set_property('top-padding', 2) self.alignment.set_property('top-padding', 2)
else: else:
@ -444,7 +446,9 @@ class MessageWindow(object):
self.window.destroy() self.window.destroy()
return # don't show_title, we are dead return # don't show_title, we are dead
elif self.get_num_controls() == 1: # we are going from two tabs to one elif self.get_num_controls() == 1: # we are going from two tabs to one
show_tabs_if_one_tab = gajim.config.get('tabs_always_visible') window_mode = gajim.interface.msg_win_mgr.mode
show_tabs_if_one_tab = gajim.config.get('tabs_always_visible') or \
window_mode == MessageWindowMgr.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER
self.notebook.set_show_tabs(show_tabs_if_one_tab) self.notebook.set_show_tabs(show_tabs_if_one_tab)
if not show_tabs_if_one_tab: if not show_tabs_if_one_tab:
self.alignment.set_property('top-padding', 0) self.alignment.set_property('top-padding', 0)
@ -624,11 +628,15 @@ class MessageWindow(object):
self.show_title(control = new_ctrl) self.show_title(control = new_ctrl)
def _on_notebook_key_press(self, widget, event): def _on_notebook_key_press(self, widget, event):
control = self.get_active_control()
# Ctrl+PageUP / DOWN has to be handled by notebook # Ctrl+PageUP / DOWN has to be handled by notebook
if (event.state & gtk.gdk.CONTROL_MASK and if (event.state & gtk.gdk.CONTROL_MASK and
event.keyval in (gtk.keysyms.Page_Down, gtk.keysyms.Page_Up)): event.keyval in (gtk.keysyms.Page_Down, gtk.keysyms.Page_Up)):
return False return False
# when tab itself is selected, make sure <- and -> are allowed for navigating between tabs
if event.keyval in (gtk.keysyms.Left, gtk.keysyms.Right):
return False
control = self.get_active_control()
if isinstance(control, ChatControlBase): if isinstance(control, ChatControlBase):
# we forwarded it to message textview # we forwarded it to message textview
control.msg_textview.emit('key_press_event', event) control.msg_textview.emit('key_press_event', event)

View File

@ -334,8 +334,7 @@ class RosterWindow:
model.append(i, (None, name, 'contact', jid, account, None, model.append(i, (None, name, 'contact', jid, account, None,
None)) None))
self.draw_contact(jid, account) self.draw_contact(jid, account)
if gajim.config.get('show_avatars_in_roster'): self.draw_avatar(jid, account)
self.draw_avatar(jid, account)
self.draw_account(account) self.draw_account(account)
# Redraw parent to change icon # Redraw parent to change icon
self.draw_contact(big_brother_jid, big_brother_account) self.draw_contact(big_brother_jid, big_brother_account)
@ -395,8 +394,7 @@ class RosterWindow:
if gajim.groups[account][group]['expand']: if gajim.groups[account][group]['expand']:
self.tree.expand_row(model.get_path(iterG), False) self.tree.expand_row(model.get_path(iterG), False)
self.draw_contact(jid, account) self.draw_contact(jid, account)
if gajim.config.get('show_avatars_in_roster'): self.draw_avatar(jid, account)
self.draw_avatar(jid, account)
self.draw_account(account) self.draw_account(account)
# put the children under this iter # put the children under this iter
for data in shown_family: for data in shown_family:
@ -762,6 +760,8 @@ class RosterWindow:
def draw_avatar(self, jid, account): def draw_avatar(self, jid, account):
'''draw the avatar''' '''draw the avatar'''
if not gajim.config.get('show_avatars_in_roster'):
return
model = self.tree.get_model() model = self.tree.get_model()
iters = self.get_contact_iter(jid, account) iters = self.get_contact_iter(jid, account)
if gajim.config.get('show_avatars_in_roster'): if gajim.config.get('show_avatars_in_roster'):