massive everything-breaking overhaul for per-session windows
This commit is contained in:
parent
d696f79c55
commit
17c5bf5e52
13 changed files with 319 additions and 188 deletions
|
@ -577,7 +577,7 @@ class ChatControlBase(MessageControl):
|
||||||
type_ = 'printed_' + self.type_id
|
type_ = 'printed_' + self.type_id
|
||||||
event = 'message_received'
|
event = 'message_received'
|
||||||
show_in_roster = notify.get_show_in_roster(event,
|
show_in_roster = notify.get_show_in_roster(event,
|
||||||
self.account, self.contact)
|
self.account, self.contact, self.session)
|
||||||
show_in_systray = notify.get_show_in_systray(event,
|
show_in_systray = notify.get_show_in_systray(event,
|
||||||
self.account, self.contact)
|
self.account, self.contact)
|
||||||
if gc_message:
|
if gc_message:
|
||||||
|
@ -606,7 +606,7 @@ class ChatControlBase(MessageControl):
|
||||||
not self.parent_win.is_active() or not end) and \
|
not self.parent_win.is_active() or not end) and \
|
||||||
kind in ('incoming', 'incoming_queue'):
|
kind in ('incoming', 'incoming_queue'):
|
||||||
self.parent_win.redraw_tab(self)
|
self.parent_win.redraw_tab(self)
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(full_jid, self.account)
|
ctrl = gajim.interface.msg_win_mgr.get_control(full_jid, self.account, self.session.thread_id)
|
||||||
if not self.parent_win.is_active():
|
if not self.parent_win.is_active():
|
||||||
self.parent_win.show_title(True, ctrl) # Enabled Urgent hint
|
self.parent_win.show_title(True, ctrl) # Enabled Urgent hint
|
||||||
else:
|
else:
|
||||||
|
@ -905,10 +905,10 @@ class ChatControl(ChatControlBase):
|
||||||
old_msg_kind = None # last kind of the printed message
|
old_msg_kind = None # last kind of the printed message
|
||||||
CHAT_CMDS = ['clear', 'compact', 'help', 'ping']
|
CHAT_CMDS = ['clear', 'compact', 'help', 'ping']
|
||||||
|
|
||||||
def __init__(self, parent_win, contact, acct, resource = None):
|
def __init__(self, parent_win, contact, acct, session, resource = None):
|
||||||
ChatControlBase.__init__(self, self.TYPE_ID, parent_win,
|
ChatControlBase.__init__(self, self.TYPE_ID, parent_win,
|
||||||
'chat_child_vbox', contact, acct, resource)
|
'chat_child_vbox', contact, acct, resource)
|
||||||
|
|
||||||
# for muc use:
|
# for muc use:
|
||||||
# widget = self.xml.get_widget('muc_window_actions_button')
|
# widget = self.xml.get_widget('muc_window_actions_button')
|
||||||
widget = self.xml.get_widget('message_window_actions_button')
|
widget = self.xml.get_widget('message_window_actions_button')
|
||||||
|
@ -935,7 +935,7 @@ class ChatControl(ChatControlBase):
|
||||||
# it is on enter-notify and leave-notify so no need to be per jid
|
# it is on enter-notify and leave-notify so no need to be per jid
|
||||||
self.show_bigger_avatar_timeout_id = None
|
self.show_bigger_avatar_timeout_id = None
|
||||||
self.bigger_avatar_window = None
|
self.bigger_avatar_window = None
|
||||||
self.show_avatar(self.contact.resource)
|
self.show_avatar(self.contact.resource)
|
||||||
|
|
||||||
# chatstate timers and state
|
# chatstate timers and state
|
||||||
self.reset_kbd_mouse_timeout_vars()
|
self.reset_kbd_mouse_timeout_vars()
|
||||||
|
@ -949,7 +949,7 @@ class ChatControl(ChatControlBase):
|
||||||
id = message_tv_buffer.connect('changed',
|
id = message_tv_buffer.connect('changed',
|
||||||
self._on_message_tv_buffer_changed)
|
self._on_message_tv_buffer_changed)
|
||||||
self.handlers[id] = message_tv_buffer
|
self.handlers[id] = message_tv_buffer
|
||||||
|
|
||||||
widget = self.xml.get_widget('avatar_eventbox')
|
widget = self.xml.get_widget('avatar_eventbox')
|
||||||
id = widget.connect('enter-notify-event',
|
id = widget.connect('enter-notify-event',
|
||||||
self.on_avatar_eventbox_enter_notify_event)
|
self.on_avatar_eventbox_enter_notify_event)
|
||||||
|
@ -969,7 +969,9 @@ class ChatControl(ChatControlBase):
|
||||||
|
|
||||||
if self.contact.jid in gajim.encrypted_chats[self.account]:
|
if self.contact.jid in gajim.encrypted_chats[self.account]:
|
||||||
self.xml.get_widget('gpg_togglebutton').set_active(True)
|
self.xml.get_widget('gpg_togglebutton').set_active(True)
|
||||||
|
|
||||||
|
self.session = session
|
||||||
|
|
||||||
self.status_tooltip = gtk.Tooltips()
|
self.status_tooltip = gtk.Tooltips()
|
||||||
self.update_ui()
|
self.update_ui()
|
||||||
# restore previous conversation
|
# restore previous conversation
|
||||||
|
@ -1797,7 +1799,7 @@ class ChatControl(ChatControlBase):
|
||||||
# Is it a pm ?
|
# Is it a pm ?
|
||||||
is_pm = False
|
is_pm = False
|
||||||
room_jid, nick = gajim.get_room_and_nick_from_fjid(jid)
|
room_jid, nick = gajim.get_room_and_nick_from_fjid(jid)
|
||||||
control = gajim.interface.msg_win_mgr.get_control(room_jid, self.account)
|
control = gajim.interface.msg_win_mgr.get_control(room_jid, self.account, self.session.thread_id)
|
||||||
if control and control.type_id == message_control.TYPE_GC:
|
if control and control.type_id == message_control.TYPE_GC:
|
||||||
is_pm = True
|
is_pm = True
|
||||||
# list of message ids which should be marked as read
|
# list of message ids which should be marked as read
|
||||||
|
@ -1815,9 +1817,6 @@ class ChatControl(ChatControlBase):
|
||||||
encrypted = data[4], subject = data[1], xhtml = data[7])
|
encrypted = data[4], subject = data[1], xhtml = data[7])
|
||||||
if len(data) > 6 and isinstance(data[6], int):
|
if len(data) > 6 and isinstance(data[6], int):
|
||||||
message_ids.append(data[6])
|
message_ids.append(data[6])
|
||||||
|
|
||||||
if len(data) > 8:
|
|
||||||
self.set_thread_id(data[8])
|
|
||||||
if message_ids:
|
if message_ids:
|
||||||
gajim.logger.set_read_messages(message_ids)
|
gajim.logger.set_read_messages(message_ids)
|
||||||
gajim.events.remove_events(self.account, jid_with_resource,
|
gajim.events.remove_events(self.account, jid_with_resource,
|
||||||
|
|
|
@ -48,6 +48,8 @@ log = logging.getLogger('gajim.c.connection')
|
||||||
|
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
class Connection(ConnectionHandlers):
|
class Connection(ConnectionHandlers):
|
||||||
'''Connection class'''
|
'''Connection class'''
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
|
@ -839,7 +841,7 @@ class Connection(ConnectionHandlers):
|
||||||
|
|
||||||
def send_message(self, jid, msg, keyID, type = 'chat', subject='',
|
def send_message(self, jid, msg, keyID, type = 'chat', subject='',
|
||||||
chatstate = None, msg_id = None, composing_jep = None, resource = None,
|
chatstate = None, msg_id = None, composing_jep = None, resource = None,
|
||||||
user_nick = None, xhtml = None, thread = None):
|
user_nick = None, xhtml = None, session = None):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return 1
|
return 1
|
||||||
if msg and not xhtml and gajim.config.get('rst_formatting_outgoing_messages'):
|
if msg and not xhtml and gajim.config.get('rst_formatting_outgoing_messages'):
|
||||||
|
@ -884,8 +886,10 @@ class Connection(ConnectionHandlers):
|
||||||
msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
|
msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
|
||||||
|
|
||||||
# XEP-0201
|
# XEP-0201
|
||||||
if thread:
|
if session:
|
||||||
msg_iq.setTag("thread").setData(thread)
|
session.last_send = time.time()
|
||||||
|
if session.thread_id:
|
||||||
|
msg_iq.setThread(session.thread_id)
|
||||||
|
|
||||||
# JEP-0172: user_nickname
|
# JEP-0172: user_nickname
|
||||||
if user_nick:
|
if user_nick:
|
||||||
|
|
|
@ -37,6 +37,8 @@ from common import atom
|
||||||
from common.commands import ConnectionCommands
|
from common.commands import ConnectionCommands
|
||||||
from common.pubsub import ConnectionPubSub
|
from common.pubsub import ConnectionPubSub
|
||||||
|
|
||||||
|
from common.stanza_session import StanzaSession
|
||||||
|
|
||||||
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
||||||
'invisible', 'error']
|
'invisible', 'error']
|
||||||
# kind of events we can wait for an answer
|
# kind of events we can wait for an answer
|
||||||
|
@ -1171,6 +1173,10 @@ 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 = {}
|
||||||
|
|
||||||
|
# keep track of sessions this connection has with other JIDs
|
||||||
|
self.sessions = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
idle.init()
|
idle.init()
|
||||||
except:
|
except:
|
||||||
|
@ -1197,13 +1203,13 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
self.dispatch('HTTP_AUTH', (method, url, id, iq_obj, msg));
|
self.dispatch('HTTP_AUTH', (method, url, id, iq_obj, msg));
|
||||||
raise common.xmpp.NodeProcessed
|
raise common.xmpp.NodeProcessed
|
||||||
|
|
||||||
def _FeatureNegCB(self, con, stanza):
|
def _FeatureNegCB(self, con, stanza, session):
|
||||||
gajim.log.debug('FeatureNegCB')
|
gajim.log.debug('FeatureNegCB')
|
||||||
feature = stanza.getTag('feature')
|
feature = stanza.getTag('feature')
|
||||||
form = common.xmpp.DataForm(node=feature.getTag('x'))
|
form = common.xmpp.DataForm(node=feature.getTag('x'))
|
||||||
|
|
||||||
if form['FORM_TYPE'] == 'urn:xmpp:ssn':
|
if form['FORM_TYPE'] == 'urn:xmpp:ssn':
|
||||||
self.dispatch('SESSION_NEG', (stanza.getFrom(), stanza.getThread(), form))
|
self.dispatch('SESSION_NEG', (stanza.getFrom(), session, form))
|
||||||
else:
|
else:
|
||||||
reply = stanza.buildReply()
|
reply = stanza.buildReply()
|
||||||
reply.setType('error')
|
reply.setType('error')
|
||||||
|
@ -1410,6 +1416,17 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
|
|
||||||
def _messageCB(self, con, msg):
|
def _messageCB(self, con, msg):
|
||||||
'''Called when we receive a message'''
|
'''Called when we receive a message'''
|
||||||
|
frm = helpers.get_full_jid_from_iq(msg)
|
||||||
|
mtype = msg.getType()
|
||||||
|
thread_id = msg.getThread()
|
||||||
|
if not mtype:
|
||||||
|
mtype = 'normal'
|
||||||
|
|
||||||
|
session = self.get_session(frm, thread_id, mtype)
|
||||||
|
|
||||||
|
if thread_id and not session.received_thread_id:
|
||||||
|
session.received_thread_id = True
|
||||||
|
|
||||||
# check if the message is pubsub#event
|
# check if the message is pubsub#event
|
||||||
if msg.getTag('event') is not None:
|
if msg.getTag('event') is not None:
|
||||||
self._pubsubEventCB(con, msg)
|
self._pubsubEventCB(con, msg)
|
||||||
|
@ -1421,18 +1438,15 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
return
|
return
|
||||||
if msg.getTag('feature') and msg.getTag('feature').namespace == \
|
if msg.getTag('feature') and msg.getTag('feature').namespace == \
|
||||||
common.xmpp.NS_FEATURE:
|
common.xmpp.NS_FEATURE:
|
||||||
self._FeatureNegCB(con, msg)
|
self._FeatureNegCB(con, msg, session)
|
||||||
return
|
return
|
||||||
|
|
||||||
msgtxt = msg.getBody()
|
msgtxt = msg.getBody()
|
||||||
msghtml = msg.getXHTML()
|
msghtml = msg.getXHTML()
|
||||||
mtype = msg.getType()
|
|
||||||
subject = msg.getSubject() # if not there, it's None
|
subject = msg.getSubject() # if not there, it's None
|
||||||
thread = msg.getThread()
|
|
||||||
tim = msg.getTimestamp()
|
tim = msg.getTimestamp()
|
||||||
tim = time.strptime(tim, '%Y%m%dT%H:%M:%S')
|
tim = time.strptime(tim, '%Y%m%dT%H:%M:%S')
|
||||||
tim = time.localtime(timegm(tim))
|
tim = time.localtime(timegm(tim))
|
||||||
frm = helpers.get_full_jid_from_iq(msg)
|
|
||||||
jid = helpers.get_jid_from_iq(msg)
|
jid = helpers.get_jid_from_iq(msg)
|
||||||
no_log_for = gajim.config.get_per('accounts', self.name,
|
no_log_for = gajim.config.get_per('accounts', self.name,
|
||||||
'no_log_for')
|
'no_log_for')
|
||||||
|
@ -1541,13 +1555,42 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
gajim.logger.write('single_msg_recv', frm, msgtxt, tim = tim,
|
gajim.logger.write('single_msg_recv', frm, msgtxt, tim = tim,
|
||||||
subject = subject)
|
subject = subject)
|
||||||
mtype = 'normal'
|
mtype = 'normal'
|
||||||
|
|
||||||
treat_as = gajim.config.get('treat_incoming_messages')
|
treat_as = gajim.config.get('treat_incoming_messages')
|
||||||
if treat_as:
|
if treat_as:
|
||||||
mtype = treat_as
|
mtype = treat_as
|
||||||
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype,
|
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype,
|
||||||
subject, chatstate, msg_id, composing_jep, user_nick, msghtml, thread))
|
subject, chatstate, msg_id, composing_jep, user_nick, msghtml, session))
|
||||||
# END messageCB
|
# END messageCB
|
||||||
|
|
||||||
|
def get_session(self, jid, thread_id, type):
|
||||||
|
'''returns an existing session between this connection and 'jid' or starts a new one.'''
|
||||||
|
try:
|
||||||
|
if type == 'chat' and not thread_id:
|
||||||
|
return self.find_null_session(jid)
|
||||||
|
else:
|
||||||
|
return self.sessions[jid][thread_id]
|
||||||
|
except KeyError:
|
||||||
|
return self.make_new_session(jid, thread_id, type)
|
||||||
|
|
||||||
|
def find_null_session(self, jid):
|
||||||
|
'''returns the session between this connecting and 'jid' that we last sent a message in.'''
|
||||||
|
all = self.sessions[jid].values()
|
||||||
|
null_sessions = filter(lambda s: not s.received_thread_id, all)
|
||||||
|
null_sessions.sort(key=lambda s: s.last_send)
|
||||||
|
|
||||||
|
return null_sessions[-1]
|
||||||
|
|
||||||
|
def make_new_session(self, jid, thread_id = None, type = 'chat'):
|
||||||
|
sess = StanzaSession(self, jid, thread_id, type)
|
||||||
|
|
||||||
|
if not jid in self.sessions:
|
||||||
|
self.sessions[jid] = {}
|
||||||
|
|
||||||
|
self.sessions[jid][sess.thread_id] = sess
|
||||||
|
|
||||||
|
return sess
|
||||||
|
|
||||||
def _pubsubEventCB(self, con, msg):
|
def _pubsubEventCB(self, con, msg):
|
||||||
''' Called when we receive <message/> with pubsub event. '''
|
''' Called when we receive <message/> with pubsub event. '''
|
||||||
# TODO: Logging? (actually services where logging would be useful, should
|
# TODO: Logging? (actually services where logging would be useful, should
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
import common.gajim
|
import common.gajim
|
||||||
|
|
||||||
import random, string
|
#import random, string
|
||||||
|
|
||||||
class Contact:
|
class Contact:
|
||||||
'''Information concerning each contact'''
|
'''Information concerning each contact'''
|
||||||
|
@ -53,18 +53,18 @@ class Contact:
|
||||||
self.last_status_time = last_status_time
|
self.last_status_time = last_status_time
|
||||||
|
|
||||||
# XEP-0201
|
# XEP-0201
|
||||||
self.sessions = {}
|
# self.sessions = {}
|
||||||
|
|
||||||
def new_session(self):
|
# def new_session(self):
|
||||||
thread_id = "".join([random.choice(string.letters) for x in xrange(0,32)])
|
# thread_id = "".join([random.choice(string.letters) for x in xrange(0,32)])
|
||||||
self.sessions[self.get_full_jid()] = thread_id
|
# self.sessions[self.get_full_jid()] = thread_id
|
||||||
return thread_id
|
# return thread_id
|
||||||
|
|
||||||
def get_session(self):
|
# def get_session(self):
|
||||||
try:
|
# try:
|
||||||
return self.sessions[self.get_full_jid()]
|
# return self.sessions[self.get_full_jid()]
|
||||||
except KeyError:
|
# except KeyError:
|
||||||
return None
|
# return None
|
||||||
|
|
||||||
def get_full_jid(self):
|
def get_full_jid(self):
|
||||||
if self.resource:
|
if self.resource:
|
||||||
|
@ -169,7 +169,7 @@ class Contacts:
|
||||||
return Contact(jid, name, groups, show, status, sub, ask, resource,
|
return Contact(jid, name, groups, show, status, sub, ask, resource,
|
||||||
priority, keyID, our_chatstate, chatstate, last_status_time,
|
priority, keyID, our_chatstate, chatstate, last_status_time,
|
||||||
composing_jep)
|
composing_jep)
|
||||||
|
|
||||||
def copy_contact(self, contact):
|
def copy_contact(self, contact):
|
||||||
return self.create_contact(jid = contact.jid, name = contact.name,
|
return self.create_contact(jid = contact.jid, name = contact.name,
|
||||||
groups = contact.groups, show = contact.show, status = contact.status,
|
groups = contact.groups, show = contact.show, status = contact.status,
|
||||||
|
|
|
@ -820,7 +820,7 @@ def allow_sound_notification(sound_event, advanced_notif_num = None):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_chat_control(account, contact):
|
def get_chat_control(account, contact, session):
|
||||||
full_jid_with_resource = contact.jid
|
full_jid_with_resource = contact.jid
|
||||||
if contact.resource:
|
if contact.resource:
|
||||||
full_jid_with_resource += '/' + contact.resource
|
full_jid_with_resource += '/' + contact.resource
|
||||||
|
@ -829,16 +829,16 @@ def get_chat_control(account, contact):
|
||||||
# Look for a chat control that has the given resource, or default to
|
# Look for a chat control that has the given resource, or default to
|
||||||
# one without resource
|
# one without resource
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(full_jid_with_resource,
|
ctrl = gajim.interface.msg_win_mgr.get_control(full_jid_with_resource,
|
||||||
account)
|
account, session.thread_id)
|
||||||
if ctrl:
|
if ctrl:
|
||||||
return ctrl
|
return ctrl
|
||||||
elif not highest_contact or not highest_contact.resource:
|
elif not highest_contact or not highest_contact.resource:
|
||||||
# unknow contact or offline message
|
# unknow contact or offline message
|
||||||
return gajim.interface.msg_win_mgr.get_control(contact.jid, account)
|
return gajim.interface.msg_win_mgr.get_control(contact.jid, account, session.thread_id)
|
||||||
elif highest_contact and contact.resource != \
|
elif highest_contact and contact.resource != \
|
||||||
highest_contact.resource:
|
highest_contact.resource:
|
||||||
return None
|
return None
|
||||||
return gajim.interface.msg_win_mgr.get_control(contact.jid, account)
|
return gajim.interface.msg_win_mgr.get_control(contact.jid, account, session.thread_id)
|
||||||
|
|
||||||
def reduce_chars_newlines(text, max_chars = 0, max_lines = 0):
|
def reduce_chars_newlines(text, max_chars = 0, max_lines = 0):
|
||||||
'''Cut the chars after 'max_chars' on each line
|
'''Cut the chars after 'max_chars' on each line
|
||||||
|
|
51
src/common/stanza_session.py
Normal file
51
src/common/stanza_session.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import gajim
|
||||||
|
|
||||||
|
from common import xmpp
|
||||||
|
from common import helpers
|
||||||
|
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
|
class StanzaSession:
|
||||||
|
def __init__(self, conn, jid, thread_id, type):
|
||||||
|
self.conn = conn
|
||||||
|
|
||||||
|
if isinstance(jid, str) or isinstance(jid, unicode):
|
||||||
|
self.jid = xmpp.JID(jid)
|
||||||
|
else:
|
||||||
|
self.jid = jid
|
||||||
|
|
||||||
|
self.type = type
|
||||||
|
|
||||||
|
if thread_id:
|
||||||
|
self.received_thread_id = True
|
||||||
|
self.thread_id = thread_id
|
||||||
|
else:
|
||||||
|
self.received_thread_id = False
|
||||||
|
if type == 'normal':
|
||||||
|
self.thread_id = None
|
||||||
|
else:
|
||||||
|
self.thread_id = self.generate_thread_id()
|
||||||
|
|
||||||
|
self.last_send = 0
|
||||||
|
|
||||||
|
def generate_thread_id(self):
|
||||||
|
return "".join([random.choice(string.letters) for x in xrange(0,32)])
|
||||||
|
|
||||||
|
def get_control(self, advanced_notif_num = None):
|
||||||
|
account = self.conn.name
|
||||||
|
highest_contact = gajim.contacts.get_contact_with_highest_priority(account, str(self.jid))
|
||||||
|
contact = gajim.contacts.get_contact(account, self.jid.getStripped(), self.jid.getResource())
|
||||||
|
if isinstance(contact, list):
|
||||||
|
# there was no resource (maybe we're reading unread messages after shutdown). just take the first one for now :/
|
||||||
|
contact = contact[0]
|
||||||
|
|
||||||
|
ctrl = gajim.interface.msg_win_mgr.get_control(str(self.jid), account, self.thread_id)
|
||||||
|
# if not ctrl:
|
||||||
|
# if highest_contact and contact.resource == highest_contact.resource and not str(self.jid) == gajim.get_jid_from_account(account):
|
||||||
|
# ctrl = gajim.interface.msg_win_mgr.get_control(self.jid.getStripped(), account, self.thread_id)
|
||||||
|
|
||||||
|
if not ctrl and helpers.allow_popup_window(account, advanced_notif_num):
|
||||||
|
gajim.new_chat(contact, account, resource = resource_for_chat, session = self)
|
||||||
|
|
||||||
|
return ctrl
|
|
@ -1404,7 +1404,7 @@ class SynchroniseSelectAccountDialog:
|
||||||
if not iter:
|
if not iter:
|
||||||
return
|
return
|
||||||
remote_account = model.get_value(iter, 0).decode('utf-8')
|
remote_account = model.get_value(iter, 0).decode('utf-8')
|
||||||
|
|
||||||
if gajim.connections[remote_account].connected < 2:
|
if gajim.connections[remote_account].connected < 2:
|
||||||
ErrorDialog(_('This account is not connected to the server'),
|
ErrorDialog(_('This account is not connected to the server'),
|
||||||
_('You cannot synchronize with an account unless it is connected.'))
|
_('You cannot synchronize with an account unless it is connected.'))
|
||||||
|
@ -1686,7 +1686,7 @@ class SingleMessageWindow:
|
||||||
or 'receive'.
|
or 'receive'.
|
||||||
'''
|
'''
|
||||||
def __init__(self, account, to = '', action = '', from_whom = '',
|
def __init__(self, account, to = '', action = '', from_whom = '',
|
||||||
subject = '', message = '', resource = '', thread = None):
|
subject = '', message = '', resource = '', session = None):
|
||||||
self.account = account
|
self.account = account
|
||||||
self.action = action
|
self.action = action
|
||||||
|
|
||||||
|
@ -1695,7 +1695,7 @@ class SingleMessageWindow:
|
||||||
self.to = to
|
self.to = to
|
||||||
self.from_whom = from_whom
|
self.from_whom = from_whom
|
||||||
self.resource = resource
|
self.resource = resource
|
||||||
self.thread = thread
|
self.session = session
|
||||||
|
|
||||||
self.xml = gtkgui_helpers.get_glade('single_message_window.glade')
|
self.xml = gtkgui_helpers.get_glade('single_message_window.glade')
|
||||||
self.window = self.xml.get_widget('single_message_window')
|
self.window = self.xml.get_widget('single_message_window')
|
||||||
|
@ -1897,7 +1897,7 @@ class SingleMessageWindow:
|
||||||
|
|
||||||
# FIXME: allow GPG message some day
|
# FIXME: allow GPG message some day
|
||||||
gajim.connections[self.account].send_message(to_whom_jid, message,
|
gajim.connections[self.account].send_message(to_whom_jid, message,
|
||||||
keyID = None, type = 'normal', subject=subject, thread = self.thread)
|
keyID = None, type = 'normal', subject=subject, session = self.session)
|
||||||
|
|
||||||
self.subject_entry.set_text('') # we sent ok, clear the subject
|
self.subject_entry.set_text('') # we sent ok, clear the subject
|
||||||
self.message_tv_buffer.set_text('') # we sent ok, clear the textview
|
self.message_tv_buffer.set_text('') # we sent ok, clear the textview
|
||||||
|
@ -1914,7 +1914,7 @@ class SingleMessageWindow:
|
||||||
self.window.destroy()
|
self.window.destroy()
|
||||||
SingleMessageWindow(self.account, to = self.from_whom,
|
SingleMessageWindow(self.account, to = self.from_whom,
|
||||||
action = 'send', from_whom = self.from_whom, subject = self.subject,
|
action = 'send', from_whom = self.from_whom, subject = self.subject,
|
||||||
message = self.message, thread = self.thread)
|
message = self.message, session = self.session)
|
||||||
|
|
||||||
def on_send_and_close_button_clicked(self, widget):
|
def on_send_and_close_button_clicked(self, widget):
|
||||||
self.send_single_message()
|
self.send_single_message()
|
||||||
|
@ -2099,7 +2099,7 @@ class PrivacyListWindow:
|
||||||
jid_entry_completion.set_text_column(0)
|
jid_entry_completion.set_text_column(0)
|
||||||
jid_entry_completion.set_model(jids_list_store)
|
jid_entry_completion.set_model(jids_list_store)
|
||||||
jid_entry_completion.set_popup_completion(True)
|
jid_entry_completion.set_popup_completion(True)
|
||||||
self.edit_type_jabberid_entry.set_completion(jid_entry_completion)
|
self.edit_type_jabberid_entry.set_completion(jid_entry_completion)
|
||||||
|
|
||||||
if action == 'EDIT':
|
if action == 'EDIT':
|
||||||
self.refresh_rules()
|
self.refresh_rules()
|
||||||
|
|
98
src/gajim.py
98
src/gajim.py
|
@ -443,9 +443,9 @@ class Interface:
|
||||||
(jid_from, file_props))
|
(jid_from, file_props))
|
||||||
conn.disconnect_transfer(file_props)
|
conn.disconnect_transfer(file_props)
|
||||||
return
|
return
|
||||||
ctrl = self.msg_win_mgr.get_control(jid_from, account)
|
for ctrl in self.msg_win_mgr.get_controls(jid=jid_from, acct=account):
|
||||||
if ctrl and ctrl.type_id == message_control.TYPE_GC:
|
if ctrl and ctrl.type_id == message_control.TYPE_GC:
|
||||||
ctrl.print_conversation('Error %s: %s' % (array[2], array[1]))
|
ctrl.print_conversation('Error %s: %s' % (array[2], array[1]))
|
||||||
|
|
||||||
def handle_event_con_type(self, account, con_type):
|
def handle_event_con_type(self, account, con_type):
|
||||||
# ('CON_TYPE', account, con_type) which can be 'ssl', 'tls', 'tcp'
|
# ('CON_TYPE', account, con_type) which can be 'ssl', 'tls', 'tcp'
|
||||||
|
@ -667,7 +667,7 @@ class Interface:
|
||||||
|
|
||||||
def handle_event_msg(self, account, array):
|
def handle_event_msg(self, account, array):
|
||||||
# 'MSG' (account, (jid, msg, time, encrypted, msg_type, subject,
|
# 'MSG' (account, (jid, msg, time, encrypted, msg_type, subject,
|
||||||
# chatstate, msg_id, composing_jep, user_nick, xhtml, thread))
|
# chatstate, msg_id, composing_jep, user_nick, xhtml, session))
|
||||||
# user_nick is JEP-0172
|
# user_nick is JEP-0172
|
||||||
|
|
||||||
full_jid_with_resource = array[0]
|
full_jid_with_resource = array[0]
|
||||||
|
@ -682,13 +682,13 @@ class Interface:
|
||||||
msg_id = array[7]
|
msg_id = array[7]
|
||||||
composing_jep = array[8]
|
composing_jep = array[8]
|
||||||
xhtml = array[10]
|
xhtml = array[10]
|
||||||
thread = array[11]
|
session = array[11]
|
||||||
if gajim.config.get('ignore_incoming_xhtml'):
|
if gajim.config.get('ignore_incoming_xhtml'):
|
||||||
xhtml = None
|
xhtml = None
|
||||||
if gajim.jid_is_transport(jid):
|
if gajim.jid_is_transport(jid):
|
||||||
jid = jid.replace('@', '')
|
jid = jid.replace('@', '')
|
||||||
|
|
||||||
groupchat_control = self.msg_win_mgr.get_control(jid, account)
|
groupchat_control = self.msg_win_mgr.get_control(jid, account, session.thread_id)
|
||||||
if not groupchat_control and \
|
if not groupchat_control and \
|
||||||
gajim.interface.minimized_controls.has_key(account) and \
|
gajim.interface.minimized_controls.has_key(account) and \
|
||||||
jid in gajim.interface.minimized_controls[account]:
|
jid in gajim.interface.minimized_controls[account]:
|
||||||
|
@ -700,28 +700,29 @@ class Interface:
|
||||||
pm = True
|
pm = True
|
||||||
msg_type = 'pm'
|
msg_type = 'pm'
|
||||||
|
|
||||||
chat_control = None
|
# chat_control = None
|
||||||
jid_of_control = full_jid_with_resource
|
# jid_of_control = full_jid_with_resource
|
||||||
highest_contact = gajim.contacts.get_contact_with_highest_priority(
|
highest_contact = gajim.contacts.get_contact_with_highest_priority(
|
||||||
account, jid)
|
account, jid)
|
||||||
# Look for a chat control that has the given resource, or default to one
|
# Look for a chat control that has the given resource, or default to one
|
||||||
# without resource
|
# without resource
|
||||||
ctrl = self.msg_win_mgr.get_control(full_jid_with_resource, account)
|
chat_control = session.get_control()
|
||||||
if ctrl:
|
# ctrl = self.msg_win_mgr.get_control(full_jid_with_resource, account, session.thread_id)
|
||||||
chat_control = ctrl
|
# if ctrl:
|
||||||
elif not pm and (not highest_contact or not highest_contact.resource):
|
# chat_control = ctrl
|
||||||
|
# elif not pm and (not highest_contact or not highest_contact.resource):
|
||||||
# unknow contact or offline message
|
# unknow contact or offline message
|
||||||
jid_of_control = jid
|
# jid_of_control = jid
|
||||||
chat_control = self.msg_win_mgr.get_control(jid, account)
|
# chat_control = self.msg_win_mgr.get_control(jid, account, session.thread_id)
|
||||||
elif highest_contact and resource != highest_contact.resource and \
|
# elif highest_contact and resource != highest_contact.resource and \
|
||||||
highest_contact.show != 'offline':
|
# highest_contact.show != 'offline':
|
||||||
jid_of_control = full_jid_with_resource
|
# jid_of_control = full_jid_with_resource
|
||||||
chat_control = None
|
# chat_control = None
|
||||||
elif not pm:
|
# elif not pm:
|
||||||
jid_of_control = jid
|
# jid_of_control = jid
|
||||||
chat_control = self.msg_win_mgr.get_control(jid, account)
|
# chat_control = self.msg_win_mgr.get_control(jid, account, session.thread_id)
|
||||||
|
|
||||||
# Handle chat states
|
# Handle chat states
|
||||||
contact = gajim.contacts.get_contact(account, jid, resource)
|
contact = gajim.contacts.get_contact(account, jid, resource)
|
||||||
if contact and isinstance(contact, list):
|
if contact and isinstance(contact, list):
|
||||||
contact = contact[0]
|
contact = contact[0]
|
||||||
|
@ -739,7 +740,7 @@ class Interface:
|
||||||
# got no valid jep85 answer, peer does not support it
|
# got no valid jep85 answer, peer does not support it
|
||||||
contact.chatstate = False
|
contact.chatstate = False
|
||||||
elif chatstate == 'active':
|
elif chatstate == 'active':
|
||||||
# Brand new message, incoming.
|
# Brand new message, incoming.
|
||||||
contact.our_chatstate = chatstate
|
contact.our_chatstate = chatstate
|
||||||
contact.chatstate = chatstate
|
contact.chatstate = chatstate
|
||||||
if msg_id: # Do not overwrite an existing msg_id with None
|
if msg_id: # Do not overwrite an existing msg_id with None
|
||||||
|
@ -753,10 +754,12 @@ class Interface:
|
||||||
if gajim.config.get('ignore_unknown_contacts') and \
|
if gajim.config.get('ignore_unknown_contacts') and \
|
||||||
not gajim.contacts.get_contact(account, jid) and not pm:
|
not gajim.contacts.get_contact(account, jid) and not pm:
|
||||||
return
|
return
|
||||||
|
|
||||||
if not contact:
|
if not contact:
|
||||||
# contact is not in the roster, create a fake one to display
|
# contact is not in the roster, create a fake one to display
|
||||||
# notification
|
# notification
|
||||||
contact = common.contacts.Contact(jid = jid, resource = resource)
|
contact = common.contacts.Contact(jid = jid, resource = resource)
|
||||||
|
|
||||||
advanced_notif_num = notify.get_advanced_notification('message_received',
|
advanced_notif_num = notify.get_advanced_notification('message_received',
|
||||||
account, contact)
|
account, contact)
|
||||||
|
|
||||||
|
@ -765,8 +768,8 @@ class Interface:
|
||||||
if msg_type == 'normal':
|
if msg_type == 'normal':
|
||||||
if not gajim.events.get_events(account, jid, ['normal']):
|
if not gajim.events.get_events(account, jid, ['normal']):
|
||||||
first = True
|
first = True
|
||||||
elif not chat_control and not gajim.events.get_events(account,
|
elif not chat_control and not gajim.events.get_events(account,
|
||||||
jid_of_control, [msg_type]): # msg_type can be chat or pm
|
full_jid_with_resource, [msg_type]): # msg_type can be chat or pm
|
||||||
first = True
|
first = True
|
||||||
|
|
||||||
if pm:
|
if pm:
|
||||||
|
@ -778,18 +781,19 @@ class Interface:
|
||||||
if encrypted:
|
if encrypted:
|
||||||
self.roster.on_message(jid, message, array[2], account, array[3],
|
self.roster.on_message(jid, message, array[2], account, array[3],
|
||||||
msg_type, subject, resource, msg_id, array[9],
|
msg_type, subject, resource, msg_id, array[9],
|
||||||
advanced_notif_num, thread = thread)
|
advanced_notif_num, session = session)
|
||||||
else:
|
else:
|
||||||
# xhtml in last element
|
# xhtml in last element
|
||||||
self.roster.on_message(jid, message, array[2], account, array[3],
|
self.roster.on_message(jid, message, array[2], account, array[3],
|
||||||
msg_type, subject, resource, msg_id, array[9],
|
msg_type, subject, resource, msg_id, array[9],
|
||||||
advanced_notif_num, xhtml = xhtml, thread = thread)
|
advanced_notif_num, xhtml = xhtml, session = session)
|
||||||
nickname = gajim.get_name_from_jid(account, jid)
|
nickname = gajim.get_name_from_jid(account, jid)
|
||||||
# Check and do wanted notifications
|
|
||||||
|
# Check and do wanted notifications
|
||||||
msg = message
|
msg = message
|
||||||
if subject:
|
if subject:
|
||||||
msg = _('Subject: %s') % subject + '\n' + msg
|
msg = _('Subject: %s') % subject + '\n' + msg
|
||||||
notify.notify('new_message', jid_of_control, account, [msg_type,
|
notify.notify('new_message', full_jid_with_resource, account, [msg_type,
|
||||||
first, nickname, msg], advanced_notif_num)
|
first, nickname, msg], advanced_notif_num)
|
||||||
|
|
||||||
if self.remote_ctrl:
|
if self.remote_ctrl:
|
||||||
|
@ -986,7 +990,7 @@ class Interface:
|
||||||
resource = ''
|
resource = ''
|
||||||
if vcard.has_key('resource'):
|
if vcard.has_key('resource'):
|
||||||
resource = vcard['resource']
|
resource = vcard['resource']
|
||||||
|
|
||||||
# vcard window
|
# vcard window
|
||||||
win = None
|
win = None
|
||||||
if self.instances[account]['infos'].has_key(jid):
|
if self.instances[account]['infos'].has_key(jid):
|
||||||
|
@ -1008,11 +1012,14 @@ class Interface:
|
||||||
elif self.msg_win_mgr.has_window(jid, account):
|
elif self.msg_win_mgr.has_window(jid, account):
|
||||||
win = self.msg_win_mgr.get_window(jid, account)
|
win = self.msg_win_mgr.get_window(jid, account)
|
||||||
ctrl = win.get_control(jid, account)
|
ctrl = win.get_control(jid, account)
|
||||||
if win and ctrl.type_id != message_control.TYPE_GC:
|
|
||||||
ctrl.show_avatar()
|
for ctrl in self.msg_win_mgr.get_controls(jid=jid, acct=account):
|
||||||
|
if ctrl.type_id != message_control.TYPE_GC:
|
||||||
|
ctrl.show_avatar()
|
||||||
|
|
||||||
# Show avatar in roster or gc_roster
|
# Show avatar in roster or gc_roster
|
||||||
gc_ctrl = self.msg_win_mgr.get_control(jid, account)
|
gc_ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||||
|
# XXX get_gc_control?
|
||||||
if gc_ctrl and gc_ctrl.type_id == message_control.TYPE_GC:
|
if gc_ctrl and gc_ctrl.type_id == message_control.TYPE_GC:
|
||||||
gc_ctrl.draw_avatar(resource)
|
gc_ctrl.draw_avatar(resource)
|
||||||
else:
|
else:
|
||||||
|
@ -1656,25 +1663,24 @@ class Interface:
|
||||||
AtomWindow.newAtomEntry(atom_entry)
|
AtomWindow.newAtomEntry(atom_entry)
|
||||||
|
|
||||||
def handle_session_negotiation(self, account, data):
|
def handle_session_negotiation(self, account, data):
|
||||||
jid, thread_id, form = data
|
jid, session, form = data
|
||||||
# XXX check negotiation state, etc.
|
# XXX check negotiation state, etc.
|
||||||
# XXX check if we can autoaccept
|
# XXX check if we can autoaccept
|
||||||
|
|
||||||
if form.getType() == 'form':
|
if form.getType() == 'form':
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(str(jid), account)
|
ctrl = session.get_control()
|
||||||
if not ctrl:
|
# ctrl = gajim.interface.msg_win_mgr.get_control(str(jid), account)
|
||||||
resource = jid.getResource()
|
# if not ctrl:
|
||||||
contact = gajim.contacts.get_contact(account, str(jid), resource)
|
# resource = jid.getResource()
|
||||||
if not contact:
|
# contact = gajim.contacts.get_contact(account, str(jid), resource)
|
||||||
connection = gajim.connections[account]
|
# if not contact:
|
||||||
contact = gajim.contacts.create_contact(jid = jid.getStripped(), resource = resource, show = connection.get_status())
|
# connection = gajim.connections[account]
|
||||||
self.roster.new_chat(contact, account, resource = resource)
|
# contact = gajim.contacts.create_contact(jid = jid.getStripped(), resource = resource, show = connection.get_status())
|
||||||
|
# self.roster.new_chat(contact, account, resource = resource)
|
||||||
|
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(str(jid), account)
|
# ctrl = gajim.interface.msg_win_mgr.get_control(str(jid), account)
|
||||||
|
|
||||||
ctrl.set_thread_id(thread_id)
|
negotiation.FeatureNegotiationWindow(account, jid, session, form)
|
||||||
|
|
||||||
negotiation.FeatureNegotiationWindow(account, jid, thread_id, form)
|
|
||||||
|
|
||||||
def handle_event_privacy_lists_received(self, account, data):
|
def handle_event_privacy_lists_received(self, account, data):
|
||||||
# ('PRIVACY_LISTS_RECEIVED', account, list)
|
# ('PRIVACY_LISTS_RECEIVED', account, list)
|
||||||
|
|
|
@ -37,8 +37,6 @@ class MessageControl:
|
||||||
self.hide_chat_buttons_current = False
|
self.hide_chat_buttons_current = False
|
||||||
self.resource = resource
|
self.resource = resource
|
||||||
|
|
||||||
self.thread_id = self.contact.get_session()
|
|
||||||
|
|
||||||
gajim.last_message_time[self.account][self.get_full_jid()] = 0
|
gajim.last_message_time[self.account][self.get_full_jid()] = 0
|
||||||
|
|
||||||
self.xml = gtkgui_helpers.get_glade('message_window.glade', widget_name)
|
self.xml = gtkgui_helpers.get_glade('message_window.glade', widget_name)
|
||||||
|
@ -112,14 +110,6 @@ class MessageControl:
|
||||||
def get_specific_unread(self):
|
def get_specific_unread(self):
|
||||||
return len(gajim.events.get_events(self.account, self.contact.jid))
|
return len(gajim.events.get_events(self.account, self.contact.jid))
|
||||||
|
|
||||||
def set_thread_id(self, thread_id):
|
|
||||||
if thread_id == self.thread_id:
|
|
||||||
return
|
|
||||||
if self.thread_id:
|
|
||||||
print "starting a new session, forgetting about the old one!"
|
|
||||||
self.thread_id = thread_id
|
|
||||||
self.contact.sessions[self.contact.get_full_jid()] = thread_id
|
|
||||||
|
|
||||||
def send_message(self, message, keyID = '', type = 'chat',
|
def send_message(self, message, keyID = '', type = 'chat',
|
||||||
chatstate = None, msg_id = None, composing_jep = None, resource = None,
|
chatstate = None, msg_id = None, composing_jep = None, resource = None,
|
||||||
user_nick = None):
|
user_nick = None):
|
||||||
|
@ -127,11 +117,8 @@ class MessageControl:
|
||||||
'''
|
'''
|
||||||
jid = self.contact.jid
|
jid = self.contact.jid
|
||||||
|
|
||||||
if not self.thread_id:
|
|
||||||
self.thread_id = self.contact.new_session()
|
|
||||||
|
|
||||||
# Send and update history
|
# Send and update history
|
||||||
return gajim.connections[self.account].send_message(jid, message, keyID,
|
return gajim.connections[self.account].send_message(jid, message, keyID,
|
||||||
type = type, chatstate = chatstate, msg_id = msg_id,
|
type = type, chatstate = chatstate, msg_id = msg_id,
|
||||||
composing_jep = composing_jep, resource = self.resource,
|
composing_jep = composing_jep, resource = self.resource,
|
||||||
user_nick = user_nick, thread = self.thread_id)
|
user_nick = user_nick, session = self.session)
|
||||||
|
|
|
@ -123,8 +123,9 @@ class MessageWindow:
|
||||||
|
|
||||||
def get_num_controls(self):
|
def get_num_controls(self):
|
||||||
n = 0
|
n = 0
|
||||||
for dict in self._controls.values():
|
for sess_dict in self._controls.values():
|
||||||
n += len(dict)
|
for dict in sess_dict.values():
|
||||||
|
n += len(dict)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def _on_window_focus(self, widget, event):
|
def _on_window_focus(self, widget, event):
|
||||||
|
@ -165,7 +166,9 @@ class MessageWindow:
|
||||||
if not self._controls.has_key(control.account):
|
if not self._controls.has_key(control.account):
|
||||||
self._controls[control.account] = {}
|
self._controls[control.account] = {}
|
||||||
fjid = control.get_full_jid()
|
fjid = control.get_full_jid()
|
||||||
self._controls[control.account][fjid] = control
|
if not self._controls.has_key(fjid):
|
||||||
|
self._controls[control.account][fjid] = {}
|
||||||
|
self._controls[control.account][fjid][control.session.thread_id] = control
|
||||||
|
|
||||||
if self.get_num_controls() == 2:
|
if self.get_num_controls() == 2:
|
||||||
# is first conversation_textview scrolled down ?
|
# is first conversation_textview scrolled down ?
|
||||||
|
@ -292,11 +295,11 @@ class MessageWindow:
|
||||||
else:
|
else:
|
||||||
gtkgui_helpers.set_unset_urgency_hint(self.window, False)
|
gtkgui_helpers.set_unset_urgency_hint(self.window, False)
|
||||||
|
|
||||||
def set_active_tab(self, jid, acct):
|
def set_active_tab(self, jid, acct, thread_id):
|
||||||
ctrl = self._controls[acct][jid]
|
ctrl = self._controls[acct][jid][thread_id]
|
||||||
ctrl_page = self.notebook.page_num(ctrl.widget)
|
ctrl_page = self.notebook.page_num(ctrl.widget)
|
||||||
self.notebook.set_current_page(ctrl_page)
|
self.notebook.set_current_page(ctrl_page)
|
||||||
|
|
||||||
def remove_tab(self, ctrl, method, reason = None, force = False):
|
def remove_tab(self, ctrl, method, reason = None, force = False):
|
||||||
'''reason is only for gc (offline status message)
|
'''reason is only for gc (offline status message)
|
||||||
if force is True, do not ask any confirmation'''
|
if force is True, do not ask any confirmation'''
|
||||||
|
@ -317,7 +320,9 @@ class MessageWindow:
|
||||||
self.notebook.remove_page(self.notebook.page_num(ctrl.widget))
|
self.notebook.remove_page(self.notebook.page_num(ctrl.widget))
|
||||||
|
|
||||||
fjid = ctrl.get_full_jid()
|
fjid = ctrl.get_full_jid()
|
||||||
del self._controls[ctrl.account][fjid]
|
del self._controls[ctrl.account][fjid][ctrl.session.thread_id]
|
||||||
|
if len(self._controls[ctrl.account][fjid]) == 0:
|
||||||
|
del self._controls[ctrl.account][fjid]
|
||||||
if len(self._controls[ctrl.account]) == 0:
|
if len(self._controls[ctrl.account]) == 0:
|
||||||
del self._controls[ctrl.account]
|
del self._controls[ctrl.account]
|
||||||
|
|
||||||
|
@ -415,7 +420,19 @@ class MessageWindow:
|
||||||
for ctrl in self.controls():
|
for ctrl in self.controls():
|
||||||
ctrl.update_tags()
|
ctrl.update_tags()
|
||||||
|
|
||||||
def get_control(self, key, acct):
|
def has_control(self, jid, acct, thread_id = None):
|
||||||
|
try:
|
||||||
|
if thread_id:
|
||||||
|
return (thread_id in self._controls[acct][jid])
|
||||||
|
else:
|
||||||
|
return (jid in self._controls[acct])
|
||||||
|
except KeyError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_controls(self, jid, acct):
|
||||||
|
return self._controls[acct][jid].values()
|
||||||
|
|
||||||
|
def get_control(self, key, acct, thread_id):
|
||||||
'''Return the MessageControl for jid or n, where n is a notebook page index.
|
'''Return the MessageControl for jid or n, where n is a notebook page index.
|
||||||
When key is an int index acct may be None'''
|
When key is an int index acct may be None'''
|
||||||
if isinstance(key, str):
|
if isinstance(key, str):
|
||||||
|
@ -424,7 +441,7 @@ class MessageWindow:
|
||||||
if isinstance(key, unicode):
|
if isinstance(key, unicode):
|
||||||
jid = key
|
jid = key
|
||||||
try:
|
try:
|
||||||
return self._controls[acct][jid]
|
return self._controls[acct][jid][thread_id]
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
@ -436,9 +453,10 @@ class MessageWindow:
|
||||||
return self._widget_to_control(nth_child)
|
return self._widget_to_control(nth_child)
|
||||||
|
|
||||||
def controls(self):
|
def controls(self):
|
||||||
for ctrl_dict in self._controls.values():
|
for jid_dict in self._controls.values():
|
||||||
for ctrl in ctrl_dict.values():
|
for sess_dict in jid_dict.values():
|
||||||
yield ctrl
|
for ctrl in sess_dict.values():
|
||||||
|
yield ctrl
|
||||||
|
|
||||||
def move_to_next_unread_tab(self, forward):
|
def move_to_next_unread_tab(self, forward):
|
||||||
ind = self.notebook.get_current_page()
|
ind = self.notebook.get_current_page()
|
||||||
|
@ -495,7 +513,7 @@ class MessageWindow:
|
||||||
if old_no >= 0:
|
if old_no >= 0:
|
||||||
old_ctrl = self._widget_to_control(notebook.get_nth_page(old_no))
|
old_ctrl = self._widget_to_control(notebook.get_nth_page(old_no))
|
||||||
old_ctrl.set_control_active(False)
|
old_ctrl.set_control_active(False)
|
||||||
|
|
||||||
new_ctrl = self._widget_to_control(notebook.get_nth_page(page_num))
|
new_ctrl = self._widget_to_control(notebook.get_nth_page(page_num))
|
||||||
new_ctrl.set_control_active(True)
|
new_ctrl.set_control_active(True)
|
||||||
self.show_title(control = new_ctrl)
|
self.show_title(control = new_ctrl)
|
||||||
|
@ -569,11 +587,11 @@ class MessageWindow:
|
||||||
source_child = self.notebook.get_nth_page(source_page_num)
|
source_child = self.notebook.get_nth_page(source_page_num)
|
||||||
if dest_page_num != source_page_num:
|
if dest_page_num != source_page_num:
|
||||||
self.notebook.reorder_child(source_child, dest_page_num)
|
self.notebook.reorder_child(source_child, dest_page_num)
|
||||||
|
|
||||||
def get_tab_at_xy(self, x, y):
|
def get_tab_at_xy(self, x, y):
|
||||||
'''Thanks to Gaim
|
'''Thanks to Gaim
|
||||||
Return the tab under xy and
|
Return the tab under xy and
|
||||||
if its nearer from left or right side of the tab
|
if its nearer from left or right side of the tab
|
||||||
'''
|
'''
|
||||||
page_num = -1
|
page_num = -1
|
||||||
to_right = False
|
to_right = False
|
||||||
|
@ -594,7 +612,7 @@ class MessageWindow:
|
||||||
if (y >= tab_alloc.y) and \
|
if (y >= tab_alloc.y) and \
|
||||||
(y <= (tab_alloc.y + tab_alloc.height)):
|
(y <= (tab_alloc.y + tab_alloc.height)):
|
||||||
page_num = i
|
page_num = i
|
||||||
|
|
||||||
if y > tab_alloc.y + (tab_alloc.height / 2.0):
|
if y > tab_alloc.y + (tab_alloc.height / 2.0):
|
||||||
to_right = True
|
to_right = True
|
||||||
break
|
break
|
||||||
|
@ -659,14 +677,22 @@ class MessageWindowMgr:
|
||||||
return w
|
return w
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_window(self, jid, acct):
|
def get_window(self, jid, acct, thread_id):
|
||||||
for win in self.windows():
|
for win in self.windows():
|
||||||
if win.get_control(jid, acct):
|
if win.has_control(jid, acct, thread_id):
|
||||||
return win
|
return win
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def has_window(self, jid, acct):
|
def get_windows(self, jid, acct):
|
||||||
return self.get_window(jid, acct) != None
|
for win in self.windows():
|
||||||
|
if win.has_control(jid, acct):
|
||||||
|
yield win
|
||||||
|
|
||||||
|
def has_window(self, jid, acct, thread_id = None):
|
||||||
|
for win in self.windows():
|
||||||
|
if win.has_control(jid, acct, thread_id):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def one_window_opened(self, contact, acct, type):
|
def one_window_opened(self, contact, acct, type):
|
||||||
try:
|
try:
|
||||||
|
@ -678,7 +704,7 @@ class MessageWindowMgr:
|
||||||
'''Resizes window according to config settings'''
|
'''Resizes window according to config settings'''
|
||||||
if not gajim.config.get('saveposition'):
|
if not gajim.config.get('saveposition'):
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
if self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
||||||
size = (gajim.config.get('msgwin-width'),
|
size = (gajim.config.get('msgwin-width'),
|
||||||
gajim.config.get('msgwin-height'))
|
gajim.config.get('msgwin-height'))
|
||||||
|
@ -695,7 +721,7 @@ class MessageWindowMgr:
|
||||||
return
|
return
|
||||||
|
|
||||||
gtkgui_helpers.resize_window(win.window, size[0], size[1])
|
gtkgui_helpers.resize_window(win.window, size[0], size[1])
|
||||||
|
|
||||||
def _position_window(self, win, acct, type):
|
def _position_window(self, win, acct, type):
|
||||||
'''Moves window according to config settings'''
|
'''Moves window according to config settings'''
|
||||||
if not gajim.config.get('saveposition') or\
|
if not gajim.config.get('saveposition') or\
|
||||||
|
@ -773,18 +799,20 @@ class MessageWindowMgr:
|
||||||
del self._windows[k]
|
del self._windows[k]
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_control(self, jid, acct):
|
def get_control(self, jid, acct, thread_id):
|
||||||
'''Amongst all windows, return the MessageControl for jid'''
|
'''Amongst all windows, return the MessageControl for jid'''
|
||||||
win = self.get_window(jid, acct)
|
win = self.get_window(jid, acct, thread_id)
|
||||||
if win:
|
if win:
|
||||||
return win.get_control(jid, acct)
|
return win.get_control(jid, acct, thread_id)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_controls(self, type = None, acct = None):
|
def get_controls(self, type = None, acct = None, jid = None):
|
||||||
ctrls = []
|
ctrls = []
|
||||||
for c in self.controls():
|
for c in self.controls():
|
||||||
if acct and c.account != acct:
|
if acct and c.account != acct:
|
||||||
continue
|
continue
|
||||||
|
if jid and c.get_full_jid() != jid:
|
||||||
|
continue
|
||||||
if not type or c.type_id == type:
|
if not type or c.type_id == type:
|
||||||
ctrls.append(c)
|
ctrls.append(c)
|
||||||
return ctrls
|
return ctrls
|
||||||
|
@ -808,7 +836,7 @@ class MessageWindowMgr:
|
||||||
def save_state(self, msg_win):
|
def save_state(self, msg_win):
|
||||||
if not gajim.config.get('saveposition'):
|
if not gajim.config.get('saveposition'):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Save window size and position
|
# Save window size and position
|
||||||
pos_x_key = 'msgwin-x-position'
|
pos_x_key = 'msgwin-x-position'
|
||||||
pos_y_key = 'msgwin-y-position'
|
pos_y_key = 'msgwin-y-position'
|
||||||
|
@ -843,11 +871,11 @@ class MessageWindowMgr:
|
||||||
if self.mode != self.ONE_MSG_WINDOW_NEVER:
|
if self.mode != self.ONE_MSG_WINDOW_NEVER:
|
||||||
gajim.config.set_per('accounts', acct, pos_x_key, x)
|
gajim.config.set_per('accounts', acct, pos_x_key, x)
|
||||||
gajim.config.set_per('accounts', acct, pos_y_key, y)
|
gajim.config.set_per('accounts', acct, pos_y_key, y)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
gajim.config.set(size_width_key, width)
|
gajim.config.set(size_width_key, width)
|
||||||
gajim.config.set(size_height_key, height)
|
gajim.config.set(size_height_key, height)
|
||||||
|
|
||||||
if self.mode != self.ONE_MSG_WINDOW_NEVER:
|
if self.mode != self.ONE_MSG_WINDOW_NEVER:
|
||||||
gajim.config.set(pos_x_key, x)
|
gajim.config.set(pos_x_key, x)
|
||||||
gajim.config.set(pos_y_key, y)
|
gajim.config.set(pos_y_key, y)
|
||||||
|
|
|
@ -7,11 +7,11 @@ from common import xmpp
|
||||||
|
|
||||||
class FeatureNegotiationWindow:
|
class FeatureNegotiationWindow:
|
||||||
'''FeatureNegotiotionWindow class'''
|
'''FeatureNegotiotionWindow class'''
|
||||||
def __init__(self, account, jid, thread_id, form):
|
def __init__(self, account, jid, session, form):
|
||||||
self.account = account
|
self.account = account
|
||||||
self.jid = jid
|
self.jid = jid
|
||||||
self.form = form
|
self.form = form
|
||||||
self.thread_id = thread_id
|
self.session = session
|
||||||
|
|
||||||
self.xml = gtkgui_helpers.get_glade('data_form_window.glade', 'data_form_window')
|
self.xml = gtkgui_helpers.get_glade('data_form_window.glade', 'data_form_window')
|
||||||
self.window = self.xml.get_widget('data_form_window')
|
self.window = self.xml.get_widget('data_form_window')
|
||||||
|
@ -27,7 +27,7 @@ class FeatureNegotiationWindow:
|
||||||
|
|
||||||
def on_ok_button_clicked(self, widget):
|
def on_ok_button_clicked(self, widget):
|
||||||
acceptance = xmpp.Message(self.jid)
|
acceptance = xmpp.Message(self.jid)
|
||||||
acceptance.setThread(self.thread_id)
|
acceptance.setThread(self.session.thread_id)
|
||||||
feature = acceptance.NT.feature
|
feature = acceptance.NT.feature
|
||||||
feature.setNamespace(xmpp.NS_FEATURE)
|
feature.setNamespace(xmpp.NS_FEATURE)
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ class FeatureNegotiationWindow:
|
||||||
# XXX determine whether to reveal presence
|
# XXX determine whether to reveal presence
|
||||||
|
|
||||||
rejection = xmpp.Message(self.jid)
|
rejection = xmpp.Message(self.jid)
|
||||||
rejection.setThread(self.thread_id)
|
rejection.setThread(self.session.thread_id)
|
||||||
feature = rejection.NT.feature
|
feature = rejection.NT.feature
|
||||||
feature.setNamespace(xmpp.NS_FEATURE)
|
feature.setNamespace(xmpp.NS_FEATURE)
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
USER_HAS_PYNOTIFY = False
|
USER_HAS_PYNOTIFY = False
|
||||||
|
|
||||||
def get_show_in_roster(event, account, contact):
|
def get_show_in_roster(event, account, contact, session):
|
||||||
'''Return True if this event must be shown in roster, else False'''
|
'''Return True if this event must be shown in roster, else False'''
|
||||||
if event == 'gc_message_received':
|
if event == 'gc_message_received':
|
||||||
return True
|
return True
|
||||||
|
@ -51,7 +51,7 @@ def get_show_in_roster(event, account, contact):
|
||||||
if gajim.config.get_per('notifications', str(num), 'roster') == 'no':
|
if gajim.config.get_per('notifications', str(num), 'roster') == 'no':
|
||||||
return False
|
return False
|
||||||
if event == 'message_received':
|
if event == 'message_received':
|
||||||
chat_control = helpers.get_chat_control(account, contact)
|
chat_control = helpers.get_chat_control(account, contact, session)
|
||||||
if chat_control:
|
if chat_control:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -1190,10 +1190,14 @@ class RosterWindow:
|
||||||
'''reads from db the unread messages, and fire them up'''
|
'''reads from db the unread messages, and fire them up'''
|
||||||
for jid in gajim.contacts.get_jid_list(account):
|
for jid in gajim.contacts.get_jid_list(account):
|
||||||
results = gajim.logger.get_unread_msgs_for_jid(jid)
|
results = gajim.logger.get_unread_msgs_for_jid(jid)
|
||||||
|
|
||||||
|
# XXX results should contain sessions anyways
|
||||||
|
session = gajim.connections[account].make_new_session(jid)
|
||||||
|
|
||||||
for result in results:
|
for result in results:
|
||||||
tim = time.localtime(float(result[2]))
|
tim = time.localtime(float(result[2]))
|
||||||
self.on_message(jid, result[1], tim, account, msg_type = 'chat',
|
self.on_message(jid, result[1], tim, account, msg_type = 'chat',
|
||||||
msg_id = result[0])
|
msg_id = result[0], session = session)
|
||||||
|
|
||||||
def fill_contacts_and_groups_dicts(self, array, account):
|
def fill_contacts_and_groups_dicts(self, array, account):
|
||||||
'''fill gajim.contacts and gajim.groups'''
|
'''fill gajim.contacts and gajim.groups'''
|
||||||
|
@ -1255,8 +1259,8 @@ class RosterWindow:
|
||||||
gajim.transport_avatar[account][host].append(contact1.jid)
|
gajim.transport_avatar[account][host].append(contact1.jid)
|
||||||
# If we already have a chat window opened, update it with new contact
|
# If we already have a chat window opened, update it with new contact
|
||||||
# instance
|
# instance
|
||||||
chat_control = gajim.interface.msg_win_mgr.get_control(ji, account)
|
chat_controls = gajim.interface.msg_win_mgr.get_controls(jid=ji, acct=account)
|
||||||
if chat_control:
|
for chat_control in chat_controls:
|
||||||
chat_control.contact = contact1
|
chat_control.contact = contact1
|
||||||
|
|
||||||
def chg_contact_status(self, contact, show, status, account):
|
def chg_contact_status(self, contact, show, status, account):
|
||||||
|
@ -1283,14 +1287,14 @@ class RosterWindow:
|
||||||
jid_list = [contact.jid]
|
jid_list = [contact.jid]
|
||||||
for jid in jid_list:
|
for jid in jid_list:
|
||||||
if gajim.interface.msg_win_mgr.has_window(jid, account):
|
if gajim.interface.msg_win_mgr.has_window(jid, account):
|
||||||
win = gajim.interface.msg_win_mgr.get_window(jid, account)
|
for win in gajim.interface.msg_win_mgr.get_windows(jid, account):
|
||||||
ctrl = win.get_control(jid, account)
|
for ctrl in win.get_controls(jid=jid, acct=account):
|
||||||
ctrl.contact = gajim.contacts.get_contact_with_highest_priority(
|
ctrl.contact = gajim.contacts.get_contact_with_highest_priority(
|
||||||
account, contact.jid)
|
account, contact.jid)
|
||||||
ctrl.update_ui()
|
ctrl.update_ui()
|
||||||
win.redraw_tab(ctrl)
|
win.redraw_tab(ctrl)
|
||||||
|
|
||||||
name = contact.get_shown_name()
|
name = contact.get_shown_name()
|
||||||
|
|
||||||
# if multiple resources (or second one disconnecting)
|
# if multiple resources (or second one disconnecting)
|
||||||
if (len(contact_instances) > 1 or (len(contact_instances) == 1 and \
|
if (len(contact_instances) > 1 or (len(contact_instances) == 1 and \
|
||||||
|
@ -3477,18 +3481,22 @@ class RosterWindow:
|
||||||
# We call this here to avoid race conditions with widget validation
|
# We call this here to avoid race conditions with widget validation
|
||||||
chat_control.read_queue()
|
chat_control.read_queue()
|
||||||
|
|
||||||
def new_chat(self, contact, account, resource = None):
|
def new_chat(self, contact, account, resource = None, session = None):
|
||||||
# Get target window, create a control, and associate it with the window
|
# Get target window, create a control, and associate it with the window
|
||||||
type_ = message_control.TYPE_CHAT
|
type_ = message_control.TYPE_CHAT
|
||||||
|
|
||||||
fjid = contact.jid
|
fjid = contact.jid
|
||||||
if resource:
|
if resource:
|
||||||
fjid += '/' + resource
|
fjid += '/' + resource
|
||||||
mw = gajim.interface.msg_win_mgr.get_window(fjid, account)
|
|
||||||
|
if not session:
|
||||||
|
session = gajim.connections[account].make_new_session(fjid)
|
||||||
|
|
||||||
|
mw = gajim.interface.msg_win_mgr.get_window(fjid, account, session.thread_id)
|
||||||
if not mw:
|
if not mw:
|
||||||
mw = gajim.interface.msg_win_mgr.create_window(contact, account, type_)
|
mw = gajim.interface.msg_win_mgr.create_window(contact, account, type_)
|
||||||
|
|
||||||
chat_control = ChatControl(mw, contact, account, resource)
|
chat_control = ChatControl(mw, contact, account, session, resource)
|
||||||
|
|
||||||
mw.new_tab(chat_control)
|
mw.new_tab(chat_control)
|
||||||
|
|
||||||
|
@ -3496,6 +3504,8 @@ class RosterWindow:
|
||||||
# We call this here to avoid race conditions with widget validation
|
# We call this here to avoid race conditions with widget validation
|
||||||
chat_control.read_queue()
|
chat_control.read_queue()
|
||||||
|
|
||||||
|
return session
|
||||||
|
|
||||||
def new_chat_from_jid(self, account, fjid):
|
def new_chat_from_jid(self, account, fjid):
|
||||||
jid, resource = gajim.get_room_and_nick_from_fjid(fjid)
|
jid, resource = gajim.get_room_and_nick_from_fjid(fjid)
|
||||||
if resource:
|
if resource:
|
||||||
|
@ -3531,7 +3541,7 @@ class RosterWindow:
|
||||||
|
|
||||||
def on_message(self, jid, msg, tim, account, encrypted = False,
|
def on_message(self, jid, msg, tim, account, encrypted = False,
|
||||||
msg_type = '', subject = None, resource = '', msg_id = None,
|
msg_type = '', subject = None, resource = '', msg_id = None,
|
||||||
user_nick = '', advanced_notif_num = None, xhtml = None, thread = None):
|
user_nick = '', advanced_notif_num = None, xhtml = None, session = None):
|
||||||
'''when we receive a message'''
|
'''when we receive a message'''
|
||||||
contact = None
|
contact = None
|
||||||
# if chat window will be for specific resource
|
# if chat window will be for specific resource
|
||||||
|
@ -3569,16 +3579,18 @@ class RosterWindow:
|
||||||
|
|
||||||
path = self.get_path(jid, account) # Try to get line of contact in roster
|
path = self.get_path(jid, account) # Try to get line of contact in roster
|
||||||
|
|
||||||
|
ctrl = session.get_control(advanced_notif_num)
|
||||||
|
|
||||||
# Look for a chat control that has the given resource
|
# Look for a chat control that has the given resource
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(fjid, account)
|
# ctrl = gajim.interface.msg_win_mgr.get_control(fjid, account)
|
||||||
if not ctrl:
|
# if not ctrl:
|
||||||
# if not, if message comes from highest prio, get control or open one
|
# if not, if message comes from highest prio, get control or open one
|
||||||
# without resource
|
# without resource
|
||||||
if highest_contact and contact.resource == highest_contact.resource \
|
# if highest_contact and contact.resource == highest_contact.resource \
|
||||||
and not jid == gajim.get_jid_from_account(account):
|
# and not jid == gajim.get_jid_from_account(account):
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(jid, account)
|
# ctrl = gajim.interface.msg_win_mgr.get_control(jid, account)
|
||||||
fjid = jid
|
# fjid = jid
|
||||||
resource_for_chat = None
|
# resource_for_chat = None
|
||||||
|
|
||||||
# Do we have a queue?
|
# Do we have a queue?
|
||||||
no_queue = len(gajim.events.get_events(account, fjid)) == 0
|
no_queue = len(gajim.events.get_events(account, fjid)) == 0
|
||||||
|
@ -3588,7 +3600,7 @@ class RosterWindow:
|
||||||
if msg_type == 'normal' and popup: # it's single message to be autopopuped
|
if msg_type == 'normal' and popup: # it's single message to be autopopuped
|
||||||
dialogs.SingleMessageWindow(account, contact.jid,
|
dialogs.SingleMessageWindow(account, contact.jid,
|
||||||
action = 'receive', from_whom = jid, subject = subject,
|
action = 'receive', from_whom = jid, subject = subject,
|
||||||
message = msg, resource = resource, thread = thread)
|
message = msg, resource = resource, session = session)
|
||||||
return
|
return
|
||||||
|
|
||||||
# We print if window is opened and it's not a single message
|
# We print if window is opened and it's not a single message
|
||||||
|
@ -3596,8 +3608,6 @@ class RosterWindow:
|
||||||
typ = ''
|
typ = ''
|
||||||
if msg_type == 'error':
|
if msg_type == 'error':
|
||||||
typ = 'status'
|
typ = 'status'
|
||||||
if thread:
|
|
||||||
ctrl.set_thread_id(thread)
|
|
||||||
ctrl.print_conversation(msg, typ, tim = tim, encrypted = encrypted,
|
ctrl.print_conversation(msg, typ, tim = tim, encrypted = encrypted,
|
||||||
subject = subject, xhtml = xhtml)
|
subject = subject, xhtml = xhtml)
|
||||||
if msg_id:
|
if msg_id:
|
||||||
|
@ -3610,26 +3620,26 @@ class RosterWindow:
|
||||||
if msg_type == 'normal':
|
if msg_type == 'normal':
|
||||||
type_ = 'normal'
|
type_ = 'normal'
|
||||||
event_type = 'single_message_received'
|
event_type = 'single_message_received'
|
||||||
show_in_roster = notify.get_show_in_roster(event_type, account, contact)
|
show_in_roster = notify.get_show_in_roster(event_type, account, contact, session)
|
||||||
show_in_systray = notify.get_show_in_systray(event_type, account, contact)
|
show_in_systray = notify.get_show_in_systray(event_type, account, contact)
|
||||||
event = gajim.events.create_event(type_, (msg, subject, msg_type, tim,
|
event = gajim.events.create_event(type_, (msg, subject, msg_type, tim,
|
||||||
encrypted, resource, msg_id, xhtml, thread), show_in_roster = show_in_roster,
|
encrypted, resource, msg_id, xhtml, session), show_in_roster = show_in_roster,
|
||||||
show_in_systray = show_in_systray)
|
show_in_systray = show_in_systray)
|
||||||
gajim.events.add_event(account, fjid, event)
|
gajim.events.add_event(account, fjid, event)
|
||||||
if popup:
|
# if popup:
|
||||||
if not ctrl:
|
# if not ctrl:
|
||||||
self.new_chat(contact, account, resource = resource_for_chat)
|
# self.new_chat(contact, account, resource = resource_for_chat)
|
||||||
if path and not self.dragging and gajim.config.get(
|
# if path and not self.dragging and gajim.config.get(
|
||||||
'scroll_roster_to_last_message'):
|
# 'scroll_roster_to_last_message'):
|
||||||
# we curently see contact in our roster OR he
|
# # we curently see contact in our roster OR he
|
||||||
# is not in the roster at all.
|
# # is not in the roster at all.
|
||||||
# show and select his line in roster
|
# show and select his line in roster
|
||||||
# do not change selection while DND'ing
|
# do not change selection while DND'ing
|
||||||
self.tree.expand_row(path[0:1], False)
|
# self.tree.expand_row(path[0:1], False)
|
||||||
self.tree.expand_row(path[0:2], False)
|
# self.tree.expand_row(path[0:2], False)
|
||||||
self.tree.scroll_to_cell(path)
|
# self.tree.scroll_to_cell(path)
|
||||||
self.tree.set_cursor(path)
|
# self.tree.set_cursor(path)
|
||||||
else:
|
if not popup:
|
||||||
if no_queue: # We didn't have a queue: we change icons
|
if no_queue: # We didn't have a queue: we change icons
|
||||||
self.draw_contact(jid, account)
|
self.draw_contact(jid, account)
|
||||||
self.show_title() # we show the * or [n]
|
self.show_title() # we show the * or [n]
|
||||||
|
@ -3875,7 +3885,7 @@ class RosterWindow:
|
||||||
if event.type_ == 'normal':
|
if event.type_ == 'normal':
|
||||||
dialogs.SingleMessageWindow(account, jid,
|
dialogs.SingleMessageWindow(account, jid,
|
||||||
action = 'receive', from_whom = jid, subject = data[1],
|
action = 'receive', from_whom = jid, subject = data[1],
|
||||||
message = data[0], resource = data[5], thread = data[8])
|
message = data[0], resource = data[5], session = data[8])
|
||||||
gajim.interface.remove_first_event(account, jid, event.type_)
|
gajim.interface.remove_first_event(account, jid, event.type_)
|
||||||
return True
|
return True
|
||||||
elif event.type_ == 'file-request':
|
elif event.type_ == 'file-request':
|
||||||
|
@ -3912,22 +3922,22 @@ class RosterWindow:
|
||||||
jid = jid + u'/' + resource
|
jid = jid + u'/' + resource
|
||||||
adhoc_commands.CommandWindow(account, jid)
|
adhoc_commands.CommandWindow(account, jid)
|
||||||
|
|
||||||
def on_open_chat_window(self, widget, contact, account, resource = None):
|
def on_open_chat_window(self, widget, contact, account, resource = None, session = None):
|
||||||
# Get the window containing the chat
|
# Get the window containing the chat
|
||||||
fjid = contact.jid
|
fjid = contact.jid
|
||||||
if resource:
|
if resource:
|
||||||
fjid += '/' + resource
|
fjid += '/' + resource
|
||||||
win = gajim.interface.msg_win_mgr.get_window(fjid, account)
|
|
||||||
if not win:
|
session = self.new_chat(contact, account, resource=resource, session=session)
|
||||||
self.new_chat(contact, account, resource = resource)
|
win = gajim.interface.msg_win_mgr.get_window(fjid, account, session.thread_id)
|
||||||
win = gajim.interface.msg_win_mgr.get_window(fjid, account)
|
ctrl = win.get_control(fjid, account, session.thread_id)
|
||||||
ctrl = win.get_control(fjid, account)
|
# last message is long time ago
|
||||||
# last message is long time ago
|
gajim.last_message_time[account][ctrl.get_full_jid()] = 0
|
||||||
gajim.last_message_time[account][ctrl.get_full_jid()] = 0
|
|
||||||
win.set_active_tab(fjid, account)
|
win.set_active_tab(fjid, account, session.thread_id)
|
||||||
if gajim.connections[account].is_zeroconf and \
|
if gajim.connections[account].is_zeroconf and \
|
||||||
gajim.connections[account].status in ('offline', 'invisible'):
|
gajim.connections[account].status in ('offline', 'invisible'):
|
||||||
win.get_control(fjid, account).got_disconnected()
|
win.get_control(fjid, account, session.thread_id).got_disconnected()
|
||||||
|
|
||||||
win.window.present()
|
win.window.present()
|
||||||
|
|
||||||
|
@ -3967,7 +3977,10 @@ class RosterWindow:
|
||||||
jid = child_jid
|
jid = child_jid
|
||||||
else:
|
else:
|
||||||
child_iter = model.iter_next(child_iter)
|
child_iter = model.iter_next(child_iter)
|
||||||
|
|
||||||
|
session = None
|
||||||
if first_ev:
|
if first_ev:
|
||||||
|
session = first_ev.parameters[8]
|
||||||
fjid = jid
|
fjid = jid
|
||||||
if resource:
|
if resource:
|
||||||
fjid += '/' + resource
|
fjid += '/' + resource
|
||||||
|
@ -3978,7 +3991,7 @@ class RosterWindow:
|
||||||
c = gajim.contacts.get_contact_with_highest_priority(account, jid)
|
c = gajim.contacts.get_contact_with_highest_priority(account, jid)
|
||||||
if jid == gajim.get_jid_from_account(account):
|
if jid == gajim.get_jid_from_account(account):
|
||||||
resource = c.resource
|
resource = c.resource
|
||||||
self.on_open_chat_window(widget, c, account, resource = resource)
|
self.on_open_chat_window(widget, c, account, resource = resource, session=session)
|
||||||
|
|
||||||
def on_roster_treeview_row_activated(self, widget, path, col = 0):
|
def on_roster_treeview_row_activated(self, widget, path, col = 0):
|
||||||
'''When an iter is double clicked: open the first event window'''
|
'''When an iter is double clicked: open the first event window'''
|
||||||
|
|
Loading…
Add table
Reference in a new issue