follow chat in tabs more easily. Don't open as many chattabs as there are lowe priority chats. Fixes #5227

This commit is contained in:
Yann Leboulanger 2011-08-21 09:51:57 +02:00
parent 9d12023ec5
commit 31bfc4969a
8 changed files with 58 additions and 70 deletions

View File

@ -868,7 +868,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
keyID=keyID, type_=type_, chatstate=chatstate, msg_id=msg_id,
composing_xep=composing_xep, resource=resource,
user_nick=self.user_nick, xhtml=xhtml, label=label,
callback=callback, callback_args= callback_args))
callback=callback, callback_args=callback_args, control=self))
# Record the history of sent messages
self.save_message(message, 'sent')
@ -2631,13 +2631,15 @@ class ChatControl(ChatControlBase):
if contact.our_chatstate == 'inactive' and state == 'composing':
# go active before
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
account=self.account, jid=self.contact.jid, chatstate='active'))
account=self.account, jid=self.contact.jid, chatstate='active',
control=self))
contact.our_chatstate = 'active'
self.reset_kbd_mouse_timeout_vars()
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
account=self.account, jid=self.contact.jid, chatstate=state,
msg_id=contact.msg_id, composing_xep=contact.composing_xep))
msg_id=contact.msg_id, composing_xep=contact.composing_xep,
control=self))
contact.our_chatstate = state
if contact.our_chatstate == 'active':

View File

@ -926,23 +926,6 @@ class ConnectionHandlersBase:
continue
if sess.control:
sess.control.no_autonegotiation = False
if sess.enable_encryption:
sess.terminate_e2e()
self.delete_session(jid, sess.thread_id)
if obj.ptype == 'unavailable':
for jid in (obj.jid, obj.fjid):
if jid not in self.sessions:
continue
# automatically terminate sessions that they haven't sent a
# thread ID in, only if other part support thread ID
for sess in self.sessions[jid].values():
if not sess.received_thread_id:
contact = gajim.contacts.get_contact(self.name, jid)
if contact and (contact.supports(xmpp.NS_SSN) or \
contact.supports(xmpp.NS_ESESSION)):
sess.terminate()
del self.sessions[jid][sess.thread_id]
if gajim.config.get('log_contact_status_changes') and \
gajim.config.should_log(self.name, obj.jid):

View File

@ -2187,6 +2187,7 @@ class MessageOutgoingEvent(nec.NetworkIncomingEvent):
self.callback_args = []
self.now = False
self.is_loggable = True
self.control = None
def generate(self):
return True

View File

@ -58,7 +58,7 @@ class StanzaSession(object):
self.conn = conn
self.jid = jid
self.type = type_
self.resource = None
self.resource = jid.getResource()
if thread_id:
self.received_thread_id = True

View File

@ -358,15 +358,9 @@ class Interface:
highest = gajim.contacts.get_contact_with_highest_priority(account, jid)
is_highest = (highest and highest.resource == resource)
# disconnect the session from the ctrl if the highest resource has
# changed
if (obj.was_highest and not is_highest) or \
(not obj.was_highest and is_highest):
ctrl = self.msg_win_mgr.get_control(jid, account)
if ctrl:
ctrl.no_autonegotiation = False
ctrl.set_session(None)
ctrl.contact = highest
ctrl = self.msg_win_mgr.get_control(jid, account)
if ctrl and ctrl.session and ctrl.session.resource == resource:
ctrl.remove_session(ctrl.session)
def handle_event_msgerror(self, obj):
#'MSGERROR' (account, (jid, error_code, error_msg, msg, time[session]))

View File

@ -46,7 +46,8 @@ class MessageControl(object):
MessageWindow
"""
def __init__(self, type_id, parent_win, widget_name, contact, account, resource = None):
def __init__(self, type_id, parent_win, widget_name, contact, account,
resource=None):
# dict { cb id : widget}
# keep all registered callbacks of widgets, created by self.xml
self.handlers = {}
@ -59,6 +60,7 @@ class MessageControl(object):
self.resource = resource
self.session = None
self.other_sessions = []
gajim.last_message_time[self.account][self.get_full_jid()] = 0
@ -201,15 +203,15 @@ class MessageControl(object):
if oldsession:
oldsession.control = None
self.other_sessions.append(oldsession)
jid = self.contact.jid
if self.resource:
jid += '/' + self.resource
if self.session in self.other_sessions:
self.other_sessions.remove(self.session)
crypto_changed = bool(session and isinstance(session,
EncryptedStanzaSession) and session.enable_encryption) != \
bool(oldsession and isinstance(oldsession,
EncryptedStanzaSession) and oldsession.enable_encryption)
EncryptedStanzaSession) and session.enable_encryption) != \
bool(oldsession and isinstance(oldsession, EncryptedStanzaSession) \
and oldsession.enable_encryption)
archiving_changed = bool(session and isinstance(session,
ArchivingStanzaSession) and session.archiving) != \
@ -219,12 +221,21 @@ class MessageControl(object):
if crypto_changed or archiving_changed:
self.print_session_details()
def remove_session(self, session):
if session != self.session:
return
last_session = None
if self.other_sessions:
last_session = self.other_sessions.pop(0)
if session not in self.other_sessions:
self.other_sessions.append(session)
if last_session:
self.session = last_session
def _nec_message_outgoing(self, obj):
# Send the given message to the active tab.
# Doesn't return None if error
if obj.account != self.account:
return
if self.contact.jid != obj.jid:
if obj.control != self:
return
obj.message = helpers.remove_invalid_xml_chars(obj.message)

View File

@ -1087,6 +1087,26 @@ class MessageWindowMgr(gobject.GObject):
return win.get_control(jid, acct)
return None
def search_control(self, jid, account, resource=None):
"""
Search windows with this policy:
1. try to find already opened tab for resource
2. find the tab for this jid with ctrl.resource not set
3. there is none
"""
fjid = jid
if resource:
jid += '/' + resource
ctrl = self.get_control(fjid, account)
if ctrl:
return ctrl
win = self.get_window(jid, account)
if win:
ctrl = win.get_control(jid, account)
if not ctrl.resource:
return ctrl
return None
def get_gc_control(self, jid, acct):
"""
Same as get_control. Was briefly required, is not any more. May be useful

View File

@ -155,14 +155,9 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
obj.resource == highest_contact.resource or highest_contact.show ==\
'offline'
if not pm and is_highest:
jid_of_control = obj.jid
else:
jid_of_control = obj.fjid
if not self.control:
ctrl = gajim.interface.msg_win_mgr.get_control(jid_of_control,
self.conn.name)
ctrl = gajim.interface.msg_win_mgr.search_control(obj.jid,
obj.conn.name, obj.resource)
if ctrl:
self.control = ctrl
self.control.set_session(self)
@ -183,8 +178,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
contact = None
jid = obj.jid
resource = obj.resource
# if chat window will be for specific resource
resource_for_chat = resource
fjid = jid
@ -211,7 +204,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
else:
# Default to highest prio
fjid = jid
resource_for_chat = None
contact = highest_contact
if not contact:
@ -220,21 +212,15 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
obj.conn.name, jid, obj.user_nick)
if not self.control:
ctrl = gajim.interface.msg_win_mgr.get_control(fjid, self.conn.name)
ctrl = gajim.interface.msg_win_mgr.search_control(obj.jid,
obj.conn.name, obj.resource)
if ctrl:
self.control = ctrl
self.control.set_session(self)
else:
# if no control exists and message comes from highest prio,
# the new control shouldn't have a resource
if highest_contact and contact.resource == \
highest_contact.resource and jid != gajim.get_jid_from_account(
self.conn.name):
fjid = jid
resource_for_chat = None
fjid = jid
obj.popup = helpers.allow_popup_window(self.conn.name)
obj.resource_for_chat = resource_for_chat
type_ = 'chat'
event_type = 'message_received'
@ -268,9 +254,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
Display the message or show notification in the roster
"""
contact = None
# if chat window will be for specific resource
resource_for_chat = resource
fjid = jid
# Try to catch the contact with correct resource
@ -298,7 +281,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
else:
# Default to highest prio
fjid = jid
resource_for_chat = None
contact = highest_contact
if not contact:
@ -312,12 +294,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
self.control = ctrl
self.control.set_session(self)
else:
# if no control exists and message comes from highest prio, the new
# control shouldn't have a resource
if highest_contact and contact.resource == highest_contact.resource\
and not jid == gajim.get_jid_from_account(self.conn.name):
fjid = jid
resource_for_chat = None
fjid = jid
# Do we have a queue?
no_queue = len(gajim.events.get_events(self.conn.name, fjid)) == 0
@ -367,7 +344,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
if popup:
if not self.control:
self.control = gajim.interface.new_chat(contact,
self.conn.name, resource=resource_for_chat, session=self)
self.conn.name, session=self)
if len(gajim.events.get_events(self.conn.name, fjid)):
self.control.read_queue()