move message handling into ChatControlSession
This commit is contained in:
parent
0b48b05218
commit
0b574d2360
|
@ -49,7 +49,8 @@ if dbus_support.supported:
|
||||||
import dbus
|
import dbus
|
||||||
from music_track_listener import MusicTrackListener
|
from music_track_listener import MusicTrackListener
|
||||||
|
|
||||||
from common.stanza_session import EncryptedStanzaSession
|
# XXX interface leaking into the back end?
|
||||||
|
import session
|
||||||
|
|
||||||
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
||||||
'invisible', 'error']
|
'invisible', 'error']
|
||||||
|
@ -1713,9 +1714,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
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,
|
|
||||||
subject, chatstate, msg_id, composing_xep, user_nick, msghtml,
|
session.received(frm, msgtxt, tim, encrypted, mtype, subject, chatstate,
|
||||||
session, form_node))
|
msg_id, composing_xep, user_nick, msghtml, form_node)
|
||||||
# END messageCB
|
# END messageCB
|
||||||
|
|
||||||
def get_session(self, jid, thread_id, type):
|
def get_session(self, jid, thread_id, type):
|
||||||
|
@ -1786,7 +1787,7 @@ returns the session that we last sent a message to.'''
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def make_new_session(self, jid, thread_id = None, type = 'chat'):
|
def make_new_session(self, jid, thread_id = None, type = 'chat'):
|
||||||
sess = EncryptedStanzaSession(self, common.xmpp.JID(jid), thread_id, type)
|
sess = session.ChatControlSession(self, common.xmpp.JID(jid), thread_id, type)
|
||||||
|
|
||||||
if not jid in self.sessions:
|
if not jid in self.sessions:
|
||||||
self.sessions[jid] = {}
|
self.sessions[jid] = {}
|
||||||
|
|
|
@ -168,7 +168,7 @@ class Events:
|
||||||
'''returns all events from the given account of the form
|
'''returns all events from the given account of the form
|
||||||
{jid1: [], jid2: []}
|
{jid1: [], jid2: []}
|
||||||
if jid is given, returns all events from the given jid in a list: []
|
if jid is given, returns all events from the given jid in a list: []
|
||||||
optionnaly only from given type'''
|
optionally only from given type'''
|
||||||
if not self._events.has_key(account):
|
if not self._events.has_key(account):
|
||||||
return []
|
return []
|
||||||
if not jid:
|
if not jid:
|
||||||
|
|
136
src/gajim.py
136
src/gajim.py
|
@ -727,141 +727,6 @@ class Interface:
|
||||||
self.handle_event_gc_notify(account, (jid, array[1], status_message,
|
self.handle_event_gc_notify(account, (jid, array[1], status_message,
|
||||||
array[3], None, None, None, None, None, [], None, None))
|
array[3], None, None, None, None, None, [], None, None))
|
||||||
|
|
||||||
|
|
||||||
def handle_event_msg(self, account, array):
|
|
||||||
# 'MSG' (account, (jid, msg, time, encrypted, msg_type, subject,
|
|
||||||
# chatstate, msg_id, composing_xep, user_nick, xhtml, session, form_node))
|
|
||||||
# user_nick is JEP-0172
|
|
||||||
|
|
||||||
full_jid_with_resource = array[0]
|
|
||||||
jid = gajim.get_jid_without_resource(full_jid_with_resource)
|
|
||||||
resource = gajim.get_resource_from_jid(full_jid_with_resource)
|
|
||||||
|
|
||||||
message = array[1]
|
|
||||||
encrypted = array[3]
|
|
||||||
msg_type = array[4]
|
|
||||||
subject = array[5]
|
|
||||||
chatstate = array[6]
|
|
||||||
msg_id = array[7]
|
|
||||||
composing_xep = array[8]
|
|
||||||
xhtml = array[10]
|
|
||||||
session = array[11]
|
|
||||||
if gajim.config.get('ignore_incoming_xhtml'):
|
|
||||||
xhtml = None
|
|
||||||
if gajim.jid_is_transport(jid):
|
|
||||||
jid = jid.replace('@', '')
|
|
||||||
|
|
||||||
groupchat_control = self.msg_win_mgr.get_control(jid, account)
|
|
||||||
if not groupchat_control and \
|
|
||||||
jid in self.minimized_controls[account]:
|
|
||||||
groupchat_control = self.minimized_controls[account][jid]
|
|
||||||
pm = False
|
|
||||||
if groupchat_control and groupchat_control.type_id == \
|
|
||||||
message_control.TYPE_GC:
|
|
||||||
# It's a Private message
|
|
||||||
pm = True
|
|
||||||
msg_type = 'pm'
|
|
||||||
|
|
||||||
chat_control = None
|
|
||||||
jid_of_control = full_jid_with_resource
|
|
||||||
highest_contact = gajim.contacts.get_contact_with_highest_priority(
|
|
||||||
account, jid)
|
|
||||||
# Look for a chat control that has the given resource, or default to one
|
|
||||||
# without resource
|
|
||||||
ctrl = self.msg_win_mgr.get_control(full_jid_with_resource, account)
|
|
||||||
if ctrl:
|
|
||||||
chat_control = ctrl
|
|
||||||
elif not pm and (not highest_contact or not highest_contact.resource):
|
|
||||||
# unknow contact or offline message
|
|
||||||
jid_of_control = jid
|
|
||||||
chat_control = self.msg_win_mgr.get_control(jid, account)
|
|
||||||
elif highest_contact and resource != highest_contact.resource and \
|
|
||||||
highest_contact.show != 'offline':
|
|
||||||
jid_of_control = full_jid_with_resource
|
|
||||||
chat_control = None
|
|
||||||
elif not pm:
|
|
||||||
jid_of_control = jid
|
|
||||||
chat_control = self.msg_win_mgr.get_control(jid, account)
|
|
||||||
|
|
||||||
# Handle chat states
|
|
||||||
contact = gajim.contacts.get_contact(account, jid, resource)
|
|
||||||
if contact:
|
|
||||||
if contact.composing_xep != 'XEP-0085': # We cache xep85 support
|
|
||||||
contact.composing_xep = composing_xep
|
|
||||||
if chat_control and chat_control.type_id == message_control.TYPE_CHAT:
|
|
||||||
if chatstate is not None:
|
|
||||||
# other peer sent us reply, so he supports jep85 or jep22
|
|
||||||
contact.chatstate = chatstate
|
|
||||||
if contact.our_chatstate == 'ask': # we were jep85 disco?
|
|
||||||
contact.our_chatstate = 'active' # no more
|
|
||||||
chat_control.handle_incoming_chatstate()
|
|
||||||
elif contact.chatstate != 'active':
|
|
||||||
# got no valid jep85 answer, peer does not support it
|
|
||||||
contact.chatstate = False
|
|
||||||
elif chatstate == 'active':
|
|
||||||
# Brand new message, incoming.
|
|
||||||
contact.our_chatstate = chatstate
|
|
||||||
contact.chatstate = chatstate
|
|
||||||
if msg_id: # Do not overwrite an existing msg_id with None
|
|
||||||
contact.msg_id = msg_id
|
|
||||||
|
|
||||||
# THIS MUST BE AFTER chatstates handling
|
|
||||||
# AND BEFORE playsound (else we ear sounding on chatstates!)
|
|
||||||
if not message: # empty message text
|
|
||||||
return
|
|
||||||
|
|
||||||
if gajim.config.get('ignore_unknown_contacts') and \
|
|
||||||
not gajim.contacts.get_contacts(account, jid) and not pm:
|
|
||||||
return
|
|
||||||
if not contact:
|
|
||||||
# contact is not in the roster, create a fake one to display
|
|
||||||
# notification
|
|
||||||
contact = common.contacts.Contact(jid = jid, resource = resource)
|
|
||||||
advanced_notif_num = notify.get_advanced_notification('message_received',
|
|
||||||
account, contact)
|
|
||||||
|
|
||||||
# Is it a first or next message received ?
|
|
||||||
first = False
|
|
||||||
if msg_type == 'normal':
|
|
||||||
if not gajim.events.get_events(account, jid, ['normal']):
|
|
||||||
first = True
|
|
||||||
elif not chat_control and not gajim.events.get_events(account,
|
|
||||||
jid_of_control, [msg_type]): # msg_type can be chat or pm
|
|
||||||
first = True
|
|
||||||
|
|
||||||
if pm:
|
|
||||||
nickname = resource
|
|
||||||
groupchat_control.on_private_message(nickname, message, array[2],
|
|
||||||
xhtml, session, msg_id)
|
|
||||||
else:
|
|
||||||
# array: (jid, msg, time, encrypted, msg_type, subject)
|
|
||||||
if encrypted:
|
|
||||||
self.roster.on_message(jid, message, array[2], account, array[3],
|
|
||||||
msg_type, subject, resource, msg_id, array[9],
|
|
||||||
advanced_notif_num, session=session, form_node=array[12])
|
|
||||||
else:
|
|
||||||
# xhtml in last element
|
|
||||||
self.roster.on_message(jid, message, array[2], account, array[3],
|
|
||||||
msg_type, subject, resource, msg_id, array[9],
|
|
||||||
advanced_notif_num, xhtml=xhtml, session=session,
|
|
||||||
form_node=array[12])
|
|
||||||
nickname = gajim.get_name_from_jid(account, jid)
|
|
||||||
# Check and do wanted notifications
|
|
||||||
msg = message
|
|
||||||
if subject:
|
|
||||||
msg = _('Subject: %s') % subject + '\n' + msg
|
|
||||||
focused = False
|
|
||||||
if chat_control:
|
|
||||||
parent_win = chat_control.parent_win
|
|
||||||
if chat_control == parent_win.get_active_control() and \
|
|
||||||
parent_win.window.has_focus:
|
|
||||||
focused = True
|
|
||||||
notify.notify('new_message', jid_of_control, account, [msg_type,
|
|
||||||
first, nickname, msg, focused], advanced_notif_num)
|
|
||||||
|
|
||||||
if self.remote_ctrl:
|
|
||||||
self.remote_ctrl.raise_signal('NewMessage', (account, array))
|
|
||||||
|
|
||||||
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))
|
||||||
full_jid_with_resource = array[0]
|
full_jid_with_resource = array[0]
|
||||||
|
@ -2556,7 +2421,6 @@ class Interface:
|
||||||
'ERROR_ANSWER': self.handle_event_error_answer,
|
'ERROR_ANSWER': self.handle_event_error_answer,
|
||||||
'STATUS': self.handle_event_status,
|
'STATUS': self.handle_event_status,
|
||||||
'NOTIFY': self.handle_event_notify,
|
'NOTIFY': self.handle_event_notify,
|
||||||
'MSG': self.handle_event_msg,
|
|
||||||
'MSGERROR': self.handle_event_msgerror,
|
'MSGERROR': self.handle_event_msgerror,
|
||||||
'MSGSENT': self.handle_event_msgsent,
|
'MSGSENT': self.handle_event_msgsent,
|
||||||
'MSGNOTSENT': self.handle_event_msgnotsent,
|
'MSGNOTSENT': self.handle_event_msgnotsent,
|
||||||
|
|
|
@ -3929,7 +3929,7 @@ 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, session = None):
|
def new_chat(self, session, contact, account, resource = 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
|
||||||
|
|
||||||
|
@ -3945,9 +3945,7 @@ class RosterWindow:
|
||||||
|
|
||||||
mw.new_tab(chat_control)
|
mw.new_tab(chat_control)
|
||||||
|
|
||||||
if len(gajim.events.get_events(account, fjid)):
|
return chat_control
|
||||||
# We call this here to avoid race conditions with widget validation
|
|
||||||
chat_control.read_queue()
|
|
||||||
|
|
||||||
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)
|
||||||
|
@ -3963,7 +3961,12 @@ class RosterWindow:
|
||||||
resource = resource)
|
resource = resource)
|
||||||
|
|
||||||
if not gajim.interface.msg_win_mgr.has_window(fjid, account):
|
if not gajim.interface.msg_win_mgr.has_window(fjid, account):
|
||||||
self.new_chat(contact, account, resource = resource)
|
session = account.make_new_session(account, fjid)
|
||||||
|
self.control = self.new_chat(session, contact, account, resource = resource)
|
||||||
|
|
||||||
|
if len(gajim.events.get_events(account, fjid)):
|
||||||
|
chat_control.read_queue()
|
||||||
|
|
||||||
mw = gajim.interface.msg_win_mgr.get_window(fjid, account)
|
mw = gajim.interface.msg_win_mgr.get_window(fjid, account)
|
||||||
mw.set_active_tab(fjid, account)
|
mw.set_active_tab(fjid, account)
|
||||||
mw.window.present()
|
mw.window.present()
|
||||||
|
@ -3983,114 +3986,6 @@ class RosterWindow:
|
||||||
is_continued=is_continued)
|
is_continued=is_continued)
|
||||||
mw.new_tab(gc_control)
|
mw.new_tab(gc_control)
|
||||||
|
|
||||||
def on_message(self, jid, msg, tim, account, encrypted=False, msg_type='',
|
|
||||||
subject=None, resource='', msg_id=None, user_nick='',
|
|
||||||
advanced_notif_num=None, xhtml=None, session=None, form_node=None):
|
|
||||||
'''when we receive a message'''
|
|
||||||
contact = None
|
|
||||||
# if chat window will be for specific resource
|
|
||||||
resource_for_chat = resource
|
|
||||||
fjid = jid
|
|
||||||
# Try to catch the contact with correct resource
|
|
||||||
if resource:
|
|
||||||
fjid = jid + '/' + resource
|
|
||||||
contact = gajim.contacts.get_contact(account, jid, resource)
|
|
||||||
highest_contact = gajim.contacts.get_contact_with_highest_priority(
|
|
||||||
account, jid)
|
|
||||||
if not contact:
|
|
||||||
# If there is another resource, it may be a message from an invisible
|
|
||||||
# resource
|
|
||||||
lcontact = gajim.contacts.get_contacts(account, jid)
|
|
||||||
if (len(lcontact) > 1 or (lcontact and lcontact[0].resource and \
|
|
||||||
lcontact[0].show != 'offline')) and jid.find('@') > 0:
|
|
||||||
contact = gajim.contacts.copy_contact(highest_contact)
|
|
||||||
contact.resource = resource
|
|
||||||
if resource:
|
|
||||||
fjid = jid + '/' + resource
|
|
||||||
contact.priority = 0
|
|
||||||
contact.show = 'offline'
|
|
||||||
contact.status = ''
|
|
||||||
gajim.contacts.add_contact(account, contact)
|
|
||||||
|
|
||||||
else:
|
|
||||||
# Default to highest prio
|
|
||||||
fjid = jid
|
|
||||||
resource_for_chat = None
|
|
||||||
contact = highest_contact
|
|
||||||
if not contact:
|
|
||||||
# contact is not in roster
|
|
||||||
contact = self.add_to_not_in_the_roster(account, jid, user_nick)
|
|
||||||
|
|
||||||
path = self.get_path(jid, account) # Try to get line of contact in roster
|
|
||||||
|
|
||||||
# Look for a chat control that has the given resource
|
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(fjid, account)
|
|
||||||
if not ctrl:
|
|
||||||
# if not, if message comes from highest prio, get control or open one
|
|
||||||
# without resource
|
|
||||||
if highest_contact and contact.resource == highest_contact.resource \
|
|
||||||
and not jid == gajim.get_jid_from_account(account):
|
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(jid, account)
|
|
||||||
fjid = jid
|
|
||||||
resource_for_chat = None
|
|
||||||
|
|
||||||
# Do we have a queue?
|
|
||||||
no_queue = len(gajim.events.get_events(account, fjid)) == 0
|
|
||||||
|
|
||||||
popup = helpers.allow_popup_window(account, advanced_notif_num)
|
|
||||||
|
|
||||||
if msg_type == 'normal' and popup: # it's single message to be autopopuped
|
|
||||||
dialogs.SingleMessageWindow(account, contact.jid, action='receive',
|
|
||||||
from_whom=jid, subject=subject, message=msg, resource=resource,
|
|
||||||
session=session, form_node=form_node)
|
|
||||||
return
|
|
||||||
|
|
||||||
# We print if window is opened and it's not a single message
|
|
||||||
if ctrl and msg_type != 'normal':
|
|
||||||
typ = ''
|
|
||||||
if msg_type == 'error':
|
|
||||||
typ = 'status'
|
|
||||||
if session:
|
|
||||||
ctrl.set_session(session)
|
|
||||||
ctrl.print_conversation(msg, typ, tim = tim, encrypted = encrypted,
|
|
||||||
subject = subject, xhtml = xhtml)
|
|
||||||
if msg_id:
|
|
||||||
gajim.logger.set_read_messages([msg_id])
|
|
||||||
return
|
|
||||||
|
|
||||||
# We save it in a queue
|
|
||||||
type_ = 'chat'
|
|
||||||
event_type = 'message_received'
|
|
||||||
if msg_type == 'normal':
|
|
||||||
type_ = 'normal'
|
|
||||||
event_type = 'single_message_received'
|
|
||||||
show_in_roster = notify.get_show_in_roster(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,
|
|
||||||
encrypted, resource, msg_id, xhtml, session, form_node),
|
|
||||||
show_in_roster=show_in_roster, show_in_systray=show_in_systray)
|
|
||||||
gajim.events.add_event(account, fjid, event)
|
|
||||||
if popup:
|
|
||||||
if not ctrl:
|
|
||||||
self.new_chat(contact, account, resource=resource_for_chat)
|
|
||||||
if path and not self.dragging and gajim.config.get(
|
|
||||||
'scroll_roster_to_last_message'):
|
|
||||||
# we curently see contact in our roster OR he
|
|
||||||
# is not in the roster at all.
|
|
||||||
# show and select his line in roster
|
|
||||||
# do not change selection while DND'ing
|
|
||||||
self.tree.expand_row(path[0:1], False)
|
|
||||||
self.tree.expand_row(path[0:2], False)
|
|
||||||
self.tree.scroll_to_cell(path)
|
|
||||||
self.tree.set_cursor(path)
|
|
||||||
else:
|
|
||||||
if no_queue: # We didn't have a queue: we change icons
|
|
||||||
self.draw_contact(jid, account)
|
|
||||||
self.show_title() # we show the * or [n]
|
|
||||||
# Show contact in roster (if he is invisible for example) and select
|
|
||||||
# line
|
|
||||||
self.show_and_select_path(path, jid, account)
|
|
||||||
|
|
||||||
def on_preferences_menuitem_activate(self, widget):
|
def on_preferences_menuitem_activate(self, widget):
|
||||||
if gajim.interface.instances.has_key('preferences'):
|
if gajim.interface.instances.has_key('preferences'):
|
||||||
gajim.interface.instances['preferences'].window.present()
|
gajim.interface.instances['preferences'].window.present()
|
||||||
|
@ -4399,7 +4294,7 @@ class RosterWindow:
|
||||||
fjid += '/' + resource
|
fjid += '/' + resource
|
||||||
win = gajim.interface.msg_win_mgr.get_window(fjid, account)
|
win = gajim.interface.msg_win_mgr.get_window(fjid, account)
|
||||||
if not win:
|
if not win:
|
||||||
self.new_chat(contact, account, resource = resource, session = session)
|
self.new_chat(session, contact, account, resource = resource)
|
||||||
win = gajim.interface.msg_win_mgr.get_window(fjid, account)
|
win = gajim.interface.msg_win_mgr.get_window(fjid, account)
|
||||||
ctrl = win.get_control(fjid, account)
|
ctrl = win.get_control(fjid, account)
|
||||||
# last message is long time ago
|
# last message is long time ago
|
||||||
|
|
|
@ -0,0 +1,224 @@
|
||||||
|
from common import helpers
|
||||||
|
|
||||||
|
from common import gajim
|
||||||
|
from common import stanza_session
|
||||||
|
from common import contacts
|
||||||
|
|
||||||
|
import dialogs
|
||||||
|
|
||||||
|
import message_control
|
||||||
|
|
||||||
|
import notify
|
||||||
|
|
||||||
|
class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
|
def __init__(self, conn, jid, thread_id, type = 'chat'):
|
||||||
|
stanza_session.EncryptedStanzaSession.__init__(self, conn, jid, thread_id, type = 'chat')
|
||||||
|
|
||||||
|
self.control = None
|
||||||
|
|
||||||
|
def received(self, full_jid_with_resource, message, tim, encrypted, msg_type, subject, chatstate, msg_id, composing_xep, user_nick, xhtml, form_node):
|
||||||
|
|
||||||
|
jid = gajim.get_jid_without_resource(full_jid_with_resource)
|
||||||
|
resource = gajim.get_resource_from_jid(full_jid_with_resource)
|
||||||
|
|
||||||
|
if gajim.config.get('ignore_incoming_xhtml'):
|
||||||
|
xhtml = None
|
||||||
|
if gajim.jid_is_transport(jid):
|
||||||
|
jid = jid.replace('@', '')
|
||||||
|
|
||||||
|
groupchat_control = gajim.interface.msg_win_mgr.get_control(jid, self.conn.name)
|
||||||
|
if not groupchat_control and \
|
||||||
|
jid in gajim.interface.minimized_controls[self.conn.name]:
|
||||||
|
groupchat_control = self.minimized_controls[self.conn.name][jid]
|
||||||
|
|
||||||
|
pm = False
|
||||||
|
if groupchat_control and groupchat_control.type_id == \
|
||||||
|
message_control.TYPE_GC:
|
||||||
|
# It's a Private message
|
||||||
|
pm = True
|
||||||
|
msg_type = 'pm'
|
||||||
|
|
||||||
|
jid_of_control = full_jid_with_resource
|
||||||
|
|
||||||
|
# Handle chat states
|
||||||
|
contact = gajim.contacts.get_contact(self.conn.name, jid, resource)
|
||||||
|
if contact:
|
||||||
|
if contact.composing_xep != 'XEP-0085': # We cache xep85 support
|
||||||
|
contact.composing_xep = composing_xep
|
||||||
|
if self.control and self.control.type_id == message_control.TYPE_CHAT:
|
||||||
|
if chatstate is not None:
|
||||||
|
# other peer sent us reply, so he supports jep85 or jep22
|
||||||
|
contact.chatstate = chatstate
|
||||||
|
if contact.our_chatstate == 'ask': # we were jep85 disco?
|
||||||
|
contact.our_chatstate = 'active' # no more
|
||||||
|
self.control.handle_incoming_chatstate()
|
||||||
|
elif contact.chatstate != 'active':
|
||||||
|
# got no valid jep85 answer, peer does not support it
|
||||||
|
contact.chatstate = False
|
||||||
|
elif chatstate == 'active':
|
||||||
|
# Brand new message, incoming.
|
||||||
|
contact.our_chatstate = chatstate
|
||||||
|
contact.chatstate = chatstate
|
||||||
|
if msg_id: # Do not overwrite an existing msg_id with None
|
||||||
|
contact.msg_id = msg_id
|
||||||
|
|
||||||
|
# THIS MUST BE AFTER chatstates handling
|
||||||
|
# AND BEFORE playsound (else we ear sounding on chatstates!)
|
||||||
|
if not message: # empty message text
|
||||||
|
return
|
||||||
|
|
||||||
|
if gajim.config.get('ignore_unknown_contacts') and \
|
||||||
|
not gajim.contacts.get_contacts(self.conn.name, jid) and not pm:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not contact:
|
||||||
|
# contact is not in the roster, create a fake one to display
|
||||||
|
# notification
|
||||||
|
contact = contacts.Contact(jid = jid, resource = resource)
|
||||||
|
advanced_notif_num = notify.get_advanced_notification('message_received',
|
||||||
|
self.conn.name, contact)
|
||||||
|
|
||||||
|
# Is it a first or next message received ?
|
||||||
|
first = False
|
||||||
|
if not self.control:
|
||||||
|
first = True
|
||||||
|
|
||||||
|
if pm:
|
||||||
|
nickname = resource
|
||||||
|
groupchat_control.on_private_message(nickname, message, array[2],
|
||||||
|
xhtml, session, msg_id)
|
||||||
|
else:
|
||||||
|
self.roster_message(jid, message, tim, encrypted, msg_type,
|
||||||
|
subject, resource, msg_id, user_nick, advanced_notif_num,
|
||||||
|
xhtml=xhtml, form_node=form_node)
|
||||||
|
|
||||||
|
nickname = gajim.get_name_from_jid(self.conn.name, jid)
|
||||||
|
# Check and do wanted notifications
|
||||||
|
msg = message
|
||||||
|
if subject:
|
||||||
|
msg = _('Subject: %s') % subject + '\n' + msg
|
||||||
|
focused = False
|
||||||
|
|
||||||
|
if self.control:
|
||||||
|
parent_win = self.control.parent_win
|
||||||
|
if self.control == parent_win.get_active_control() and \
|
||||||
|
parent_win.window.has_focus:
|
||||||
|
focused = True
|
||||||
|
|
||||||
|
notify.notify('new_message', jid_of_control, self.conn.name, [msg_type,
|
||||||
|
first, nickname, msg, focused], advanced_notif_num)
|
||||||
|
|
||||||
|
if gajim.interface.remote_ctrl:
|
||||||
|
gajim.interface.remote_ctrl.raise_signal('NewMessage', (self.conn.name, [full_jid_with_resource, message, tim, encrypted, msg_type, subject, chatstate, msg_id, composing_xep, user_nick, xhtml, form_node]))
|
||||||
|
|
||||||
|
def roster_message(self, jid, msg, tim, encrypted=False, msg_type='',
|
||||||
|
subject=None, resource='', msg_id=None, user_nick='',
|
||||||
|
advanced_notif_num=None, xhtml=None, form_node=None):
|
||||||
|
contact = None
|
||||||
|
# if chat window will be for specific resource
|
||||||
|
resource_for_chat = resource
|
||||||
|
|
||||||
|
fjid = jid
|
||||||
|
|
||||||
|
# Try to catch the contact with correct resource
|
||||||
|
if resource:
|
||||||
|
fjid = jid + '/' + resource
|
||||||
|
contact = gajim.contacts.get_contact(self.conn.name, jid, resource)
|
||||||
|
|
||||||
|
highest_contact = gajim.contacts.get_contact_with_highest_priority(
|
||||||
|
self.conn.name, jid)
|
||||||
|
if not contact:
|
||||||
|
# If there is another resource, it may be a message from an invisible
|
||||||
|
# resource
|
||||||
|
lcontact = gajim.contacts.get_contacts(self.conn.name, jid)
|
||||||
|
if (len(lcontact) > 1 or (lcontact and lcontact[0].resource and \
|
||||||
|
lcontact[0].show != 'offline')) and jid.find('@') > 0:
|
||||||
|
contact = gajim.contacts.copy_contact(highest_contact)
|
||||||
|
contact.resource = resource
|
||||||
|
if resource:
|
||||||
|
fjid = jid + '/' + resource
|
||||||
|
contact.priority = 0
|
||||||
|
contact.show = 'offline'
|
||||||
|
contact.status = ''
|
||||||
|
gajim.contacts.add_contact(self.conn.name, contact)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Default to highest prio
|
||||||
|
fjid = jid
|
||||||
|
resource_for_chat = None
|
||||||
|
contact = highest_contact
|
||||||
|
|
||||||
|
if not contact:
|
||||||
|
# contact is not in roster
|
||||||
|
contact = gajim.interface.roster.add_to_not_in_the_roster(self.conn.name, jid, user_nick)
|
||||||
|
|
||||||
|
path = gajim.interface.roster.get_path(jid, self.conn.name) # Try to get line of contact in roster
|
||||||
|
|
||||||
|
# Do we have a queue?
|
||||||
|
no_queue = len(gajim.events.get_events(self.conn.name, fjid)) == 0
|
||||||
|
|
||||||
|
popup = helpers.allow_popup_window(self.conn.name, advanced_notif_num)
|
||||||
|
|
||||||
|
if msg_type == 'normal' and popup: # it's single message to be autopopuped
|
||||||
|
dialogs.SingleMessageWindow(self.conn.name, contact.jid, action='receive',
|
||||||
|
from_whom=jid, subject=subject, message=msg, resource=resource,
|
||||||
|
session=self, form_node=form_node)
|
||||||
|
return
|
||||||
|
|
||||||
|
# We print if window is opened and it's not a single message
|
||||||
|
if self.control and msg_type != 'normal':
|
||||||
|
typ = ''
|
||||||
|
|
||||||
|
if msg_type == 'error':
|
||||||
|
typ = 'status'
|
||||||
|
|
||||||
|
self.control.print_conversation(msg, typ, tim = tim,
|
||||||
|
encrypted = encrypted, subject = subject, xhtml = xhtml)
|
||||||
|
|
||||||
|
if msg_id:
|
||||||
|
gajim.logger.set_read_messages([msg_id])
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
# We save it in a queue
|
||||||
|
type_ = 'chat'
|
||||||
|
event_type = 'message_received'
|
||||||
|
|
||||||
|
if msg_type == 'normal':
|
||||||
|
type_ = 'normal'
|
||||||
|
event_type = 'single_message_received'
|
||||||
|
|
||||||
|
show_in_roster = notify.get_show_in_roster(event_type, self.conn.name, contact)
|
||||||
|
show_in_systray = notify.get_show_in_systray(event_type, self.conn.name, contact)
|
||||||
|
|
||||||
|
event = gajim.events.create_event(type_, (msg, subject, msg_type, tim,
|
||||||
|
encrypted, resource, msg_id, xhtml, self, form_node),
|
||||||
|
show_in_roster=show_in_roster, show_in_systray=show_in_systray)
|
||||||
|
|
||||||
|
gajim.events.add_event(self.conn.name, fjid, event)
|
||||||
|
|
||||||
|
if popup:
|
||||||
|
if not self.control:
|
||||||
|
self.control = self.new_chat(self, contact, self.conn.name, resource=resource_for_chat)
|
||||||
|
|
||||||
|
if len(gajim.events.get_events(self.conn.name, fjid)):
|
||||||
|
self.control.read_queue()
|
||||||
|
|
||||||
|
if path and not gajim.interface.dragging and gajim.config.get(
|
||||||
|
'scroll_roster_to_last_message'):
|
||||||
|
# we curently see contact in our roster OR he
|
||||||
|
# is not in the roster at all.
|
||||||
|
# show and select his line in roster
|
||||||
|
# do not change selection while DND'ing
|
||||||
|
self.tree.expand_row(path[0:1], False)
|
||||||
|
self.tree.expand_row(path[0:2], False)
|
||||||
|
self.tree.scroll_to_cell(path)
|
||||||
|
self.tree.set_cursor(path)
|
||||||
|
else:
|
||||||
|
if no_queue: # We didn't have a queue: we change icons
|
||||||
|
gajim.interface.roster.draw_contact(jid, self.conn.name)
|
||||||
|
|
||||||
|
gajim.interface.roster.show_title() # we show the * or [n]
|
||||||
|
# Show contact in roster (if he is invisible for example) and select
|
||||||
|
# line
|
||||||
|
gajim.interface.roster.show_and_select_path(path, jid, self.conn.name)
|
Loading…
Reference in New Issue