handle outgoing messages with events. Fixes #6743
This commit is contained in:
parent
9fc82bbffc
commit
4ac1768040
|
@ -54,6 +54,7 @@ from common.pep import MOODS, ACTIVITIES
|
|||
from common.xmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC
|
||||
from common.xmpp.protocol import NS_RECEIPTS, NS_ESESSION
|
||||
from common.xmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO, NS_JINGLE_ICE_UDP
|
||||
from common.connection_handlers_events import MessageOutgoingEvent
|
||||
|
||||
from command_system.implementation.middleware import ChatCommandProcessor
|
||||
from command_system.implementation.middleware import CommandTools
|
||||
|
@ -517,6 +518,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
menu.show_all()
|
||||
|
||||
def shutdown(self):
|
||||
super(ChatControlBase, self).shutdown()
|
||||
# PluginSystem: removing GUI extension points connected with ChatControlBase
|
||||
# instance object
|
||||
gajim.plugin_manager.remove_gui_extension_point('chat_control_base', self)
|
||||
|
@ -848,8 +850,8 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
return label
|
||||
|
||||
def send_message(self, message, keyID='', type_='chat', chatstate=None,
|
||||
msg_id=None, composing_xep=None, resource=None, xhtml=None,
|
||||
callback=None, callback_args=[], process_commands=True):
|
||||
msg_id=None, composing_xep=None, resource=None, xhtml=None, callback=None,
|
||||
callback_args=[], process_commands=True):
|
||||
"""
|
||||
Send the given message to the active tab. Doesn't return None if error
|
||||
"""
|
||||
|
@ -860,11 +862,12 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
return
|
||||
|
||||
label = self.get_seclabel()
|
||||
MessageControl.send_message(self, message, 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)
|
||||
|
||||
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
|
||||
account=self.account, message=message, 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))
|
||||
|
||||
# Record the history of sent messages
|
||||
self.save_message(message, 'sent')
|
||||
|
@ -2209,6 +2212,7 @@ class ChatControl(ChatControlBase):
|
|||
"""
|
||||
Send a message to contact
|
||||
"""
|
||||
message = helpers.remove_invalid_xml_chars(message)
|
||||
if message in ('', None, '\n'):
|
||||
return None
|
||||
|
||||
|
@ -2624,12 +2628,14 @@ class ChatControl(ChatControlBase):
|
|||
# if we're inactive prevent composing (JEP violation)
|
||||
if contact.our_chatstate == 'inactive' and state == 'composing':
|
||||
# go active before
|
||||
MessageControl.send_message(self, None, chatstate='active')
|
||||
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
|
||||
account=self.account, chatstate='active'))
|
||||
contact.our_chatstate = 'active'
|
||||
self.reset_kbd_mouse_timeout_vars()
|
||||
|
||||
MessageControl.send_message(self, "", chatstate = state,
|
||||
msg_id = contact.msg_id, composing_xep = contact.composing_xep)
|
||||
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
|
||||
account=self.account, chatstate=state, msg_id=contact.msg_id,
|
||||
composing_xep=contact.composing_xep))
|
||||
|
||||
contact.our_chatstate = state
|
||||
if contact.our_chatstate == 'active':
|
||||
|
|
|
@ -717,6 +717,8 @@ class Connection(CommonConnection, ConnectionHandlers):
|
|||
self._nec_agent_info_error_received)
|
||||
gajim.ged.register_event_handler('agent-info-received', ged.CORE,
|
||||
self._nec_agent_info_received)
|
||||
gajim.ged.register_event_handler('message-outgoing', ged.OUT_CORE,
|
||||
self._nec_message_outgoing)
|
||||
# END __init__
|
||||
|
||||
def cleanup(self):
|
||||
|
@ -727,6 +729,8 @@ class Connection(CommonConnection, ConnectionHandlers):
|
|||
self._nec_agent_info_error_received)
|
||||
gajim.ged.remove_event_handler('agent-info-received', ged.CORE,
|
||||
self._nec_agent_info_received)
|
||||
gajim.ged.remove_event_handler('message-outgoing', ged.OUT_CORE,
|
||||
self._nec_message_outgoing)
|
||||
|
||||
def get_config_values_or_default(self):
|
||||
if gajim.config.get_per('accounts', self.name, 'keep_alives_enabled'):
|
||||
|
@ -1764,6 +1768,30 @@ class Connection(CommonConnection, ConnectionHandlers):
|
|||
session=session, forward_from=forward_from, form_node=form_node,
|
||||
original_message=original_message, delayed=delayed, callback=cb)
|
||||
|
||||
def _nec_message_outgoing(self, obj):
|
||||
if obj.account != self.name:
|
||||
return
|
||||
|
||||
def cb(jid, msg, keyID, forward_from, session, original_message,
|
||||
subject, type_, msg_iq):
|
||||
msg_id = self.connection.send(msg_iq, now=obj.now)
|
||||
jid = helpers.parse_jid(obj.jid)
|
||||
gajim.nec.push_incoming_event(MessageSentEvent(None, conn=self,
|
||||
jid=jid, message=msg, keyID=keyID, chatstate=obj.chatstate))
|
||||
if obj.callback:
|
||||
obj.callback(msg_id, *obj.callback_args)
|
||||
|
||||
self.log_message(jid, msg, forward_from, session, original_message,
|
||||
subject, type_)
|
||||
|
||||
self._prepare_message(obj.jid, obj.message, obj.keyID, type_=obj.type_,
|
||||
subject=obj.subject, chatstate=obj.chatstate, msg_id=obj.msg_id,
|
||||
composing_xep=obj.composing_xep, resource=obj.resource,
|
||||
user_nick=obj.user_nick, xhtml=obj.xhtml, label=obj.label,
|
||||
session=obj.session, forward_from=obj.forward_from,
|
||||
form_node=obj.form_node, original_message=obj.original_message,
|
||||
delayed=obj.delayed, callback=cb)
|
||||
|
||||
def send_contacts(self, contacts, jid):
|
||||
"""
|
||||
Send contacts with RosterX (Xep-0144)
|
||||
|
|
|
@ -2042,3 +2042,31 @@ class NotificationEvent(nec.NetworkIncomingEvent):
|
|||
elif self.notif_type == 'pres':
|
||||
self.handle_incoming_pres_event(self.base_event)
|
||||
return True
|
||||
|
||||
class MessageOutgoingEvent(nec.NetworkIncomingEvent):
|
||||
name = 'message-outgoing'
|
||||
base_network_events = []
|
||||
|
||||
def init(self):
|
||||
self.message = ''
|
||||
self.keyID = None
|
||||
self.type_ = 'chat'
|
||||
self.subject = ''
|
||||
self.chatstate = None
|
||||
self.msg_id = None
|
||||
self.composing_xep = None
|
||||
self.resource = None
|
||||
self.user_nick = None
|
||||
self.xhtml = None
|
||||
self.label = None
|
||||
self.session = None
|
||||
self.forward_from = None
|
||||
self.form_node = None
|
||||
self.original_message = ''
|
||||
self.delayed = None
|
||||
self.callback = None
|
||||
self.callback_args = []
|
||||
self.now = False
|
||||
|
||||
def generate(self):
|
||||
return True
|
|
@ -21,6 +21,7 @@ Global Events Dispatcher module.
|
|||
:author: Mateusz Biliński <mateusz@bilinski.it>
|
||||
:since: 8th August 2008
|
||||
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
|
||||
:copyright: Copyright (2011) Yann Leboulanger <asterix@lagaule.org>
|
||||
:license: GPL
|
||||
'''
|
||||
|
||||
|
@ -39,6 +40,18 @@ GUI2 = 90
|
|||
POSTGUI2 = 100
|
||||
POSTGUI = 110
|
||||
|
||||
OUT_PREGUI = 10
|
||||
OUT_PREGUI1 = 20
|
||||
OUT_GUI1 = 30
|
||||
OUT_POSTGUI1 = 40
|
||||
OUT_PREGUI2 = 50
|
||||
OUT_GUI2 = 60
|
||||
OUT_POSTGUI2 = 70
|
||||
OUT_POSTGUI = 80
|
||||
OUT_PRECORE = 90
|
||||
OUT_CORE = 100
|
||||
OUT_POSTCORE = 110
|
||||
|
||||
class GlobalEventsDispatcher(object):
|
||||
|
||||
def __init__(self):
|
||||
|
|
|
@ -21,6 +21,7 @@ Network Events Controller.
|
|||
:author: Mateusz Biliński <mateusz@bilinski.it>
|
||||
:since: 10th August 2008
|
||||
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
|
||||
:copyright: Copyright (2011) Yann Leboulanger <asterix@lagaule.org>
|
||||
:license: GPL
|
||||
'''
|
||||
|
||||
|
@ -38,23 +39,38 @@ class NetworkEventsController(object):
|
|||
Values: list of class objects that are subclasses
|
||||
of `NetworkIncomingEvent`
|
||||
'''
|
||||
self.outgoing_events_generators = {}
|
||||
'''
|
||||
Keys: names of events
|
||||
Values: list of class objects that are subclasses
|
||||
of `NetworkOutgoingEvent`
|
||||
'''
|
||||
|
||||
def register_incoming_event(self, event_class):
|
||||
for base_event_name in event_class.base_network_events:
|
||||
event_list = self.incoming_events_generators.setdefault(base_event_name, [])
|
||||
event_list = self.incoming_events_generators.setdefault(
|
||||
base_event_name, [])
|
||||
if not event_class in event_list:
|
||||
event_list.append(event_class)
|
||||
|
||||
def unregister_incoming_event(self, event_class):
|
||||
for base_event_name in event_class.base_network_events:
|
||||
if base_event_name in self.incoming_events_generators:
|
||||
self.incoming_events_generators[base_event_name].remove(event_class)
|
||||
self.incoming_events_generators[base_event_name].remove(
|
||||
event_class)
|
||||
|
||||
def register_outgoing_event(self, event_class):
|
||||
pass
|
||||
for base_event_name in event_class.base_network_events:
|
||||
event_list = self.outgoing_events_generators.setdefault(
|
||||
base_event_name, [])
|
||||
if not event_class in event_list:
|
||||
event_list.append(event_class)
|
||||
|
||||
def unregister_outgoing_event(self, event_class):
|
||||
pass
|
||||
for base_event_name in event_class.base_network_events:
|
||||
if base_event_name in self.outgoing_events_generators:
|
||||
self.outgoing_events_generators[base_event_name].remove(
|
||||
event_class)
|
||||
|
||||
def push_incoming_event(self, event_object):
|
||||
if event_object.generate():
|
||||
|
@ -62,7 +78,9 @@ class NetworkEventsController(object):
|
|||
self._generate_events_based_on_incoming_event(event_object)
|
||||
|
||||
def push_outgoing_event(self, event_object):
|
||||
pass
|
||||
if event_object.generate():
|
||||
if not gajim.ged.raise_event(event_object.name, event_object):
|
||||
self._generate_events_based_on_outgoing_event(event_object)
|
||||
|
||||
def _generate_events_based_on_incoming_event(self, event_object):
|
||||
'''
|
||||
|
@ -75,11 +93,36 @@ class NetworkEventsController(object):
|
|||
'''
|
||||
base_event_name = event_object.name
|
||||
if base_event_name in self.incoming_events_generators:
|
||||
for new_event_class in self.incoming_events_generators[base_event_name]:
|
||||
new_event_object = new_event_class(None, base_event=event_object)
|
||||
for new_event_class in self.incoming_events_generators[
|
||||
base_event_name]:
|
||||
new_event_object = new_event_class(None,
|
||||
base_event=event_object)
|
||||
if new_event_object.generate():
|
||||
if not gajim.ged.raise_event(new_event_object.name, new_event_object):
|
||||
self._generate_events_based_on_incoming_event(new_event_object)
|
||||
if not gajim.ged.raise_event(new_event_object.name,
|
||||
new_event_object):
|
||||
self._generate_events_based_on_incoming_event(
|
||||
new_event_object)
|
||||
|
||||
def _generate_events_based_on_outgoing_event(self, event_object):
|
||||
'''
|
||||
:return: True if even_object should be dispatched through Global
|
||||
Events Dispatcher, False otherwise. This can be used to replace
|
||||
base events with those that more data computed (easier to use
|
||||
by handlers).
|
||||
:note: replacing mechanism is not implemented currently, but will be
|
||||
based on attribute in new network events object.
|
||||
'''
|
||||
base_event_name = event_object.name
|
||||
if base_event_name in self.outgoing_events_generators:
|
||||
for new_event_class in self.outgoing_events_generators[
|
||||
base_event_name]:
|
||||
new_event_object = new_event_class(None,
|
||||
base_event=event_object)
|
||||
if new_event_object.generate():
|
||||
if not gajim.ged.raise_event(new_event_object.name,
|
||||
new_event_object):
|
||||
self._generate_events_based_on_outgoing_event(
|
||||
new_event_object)
|
||||
|
||||
class NetworkEvent(object):
|
||||
name = ''
|
||||
|
@ -88,10 +131,10 @@ class NetworkEvent(object):
|
|||
if new_name:
|
||||
self.name = new_name
|
||||
|
||||
self._set_kwargs_as_attributes(**kwargs)
|
||||
|
||||
self.init()
|
||||
|
||||
self._set_kwargs_as_attributes(**kwargs)
|
||||
|
||||
def init(self):
|
||||
pass
|
||||
|
||||
|
@ -130,5 +173,7 @@ class NetworkIncomingEvent(NetworkEvent):
|
|||
|
||||
|
||||
class NetworkOutgoingEvent(NetworkEvent):
|
||||
pass
|
||||
|
||||
base_network_events = []
|
||||
'''
|
||||
Names of base network events that new event is going to be generated on.
|
||||
'''
|
|
@ -30,6 +30,7 @@ import gtkgui_helpers
|
|||
|
||||
from common import gajim
|
||||
from common import helpers
|
||||
from common import ged
|
||||
from common.stanza_session import EncryptedStanzaSession, ArchivingStanzaSession
|
||||
|
||||
# Derived types MUST register their type IDs here if custom behavor is required
|
||||
|
@ -64,6 +65,9 @@ class MessageControl(object):
|
|||
self.xml = gtkgui_helpers.get_gtk_builder('%s.ui' % widget_name)
|
||||
self.widget = self.xml.get_object('%s_hbox' % widget_name)
|
||||
|
||||
gajim.ged.register_event_handler('message-outgoing', ged.OUT_GUI1,
|
||||
self._nec_message_outgoing)
|
||||
|
||||
def get_full_jid(self):
|
||||
fjid = self.contact.jid
|
||||
if self.resource:
|
||||
|
@ -110,7 +114,8 @@ class MessageControl(object):
|
|||
"""
|
||||
Derived classes MUST implement this
|
||||
"""
|
||||
pass
|
||||
gajim.ged.remove_event_handler('message-outgoing', ged.OUT_GUI1,
|
||||
self._nec_message_outgoing)
|
||||
|
||||
def repaint_themed_widgets(self):
|
||||
"""
|
||||
|
@ -214,40 +219,35 @@ class MessageControl(object):
|
|||
if crypto_changed or archiving_changed:
|
||||
self.print_session_details()
|
||||
|
||||
def send_message(self, message, keyID='', type_='chat', chatstate=None,
|
||||
msg_id=None, composing_xep=None, resource=None, user_nick=None,
|
||||
xhtml=None, label=None, callback=None, callback_args=[]):
|
||||
def _nec_message_outgoing(self, obj):
|
||||
# Send the given message to the active tab.
|
||||
# Doesn't return None if error
|
||||
jid = self.contact.jid
|
||||
if obj.account != self.account:
|
||||
return
|
||||
|
||||
message = helpers.remove_invalid_xml_chars(message)
|
||||
obj.jid = self.contact.jid
|
||||
obj.message = helpers.remove_invalid_xml_chars(obj.message)
|
||||
obj.original_message = obj.message
|
||||
|
||||
original_message = message
|
||||
conn = gajim.connections[self.account]
|
||||
|
||||
if not self.session:
|
||||
if not resource:
|
||||
if not obj.resource:
|
||||
if self.resource:
|
||||
resource = self.resource
|
||||
obj.resource = self.resource
|
||||
else:
|
||||
resource = self.contact.resource
|
||||
sess = conn.find_controlless_session(jid, resource=resource)
|
||||
obj.resource = self.contact.resource
|
||||
sess = conn.find_controlless_session(obj.jid, resource=obj.resource)
|
||||
|
||||
if self.resource:
|
||||
jid += '/' + self.resource
|
||||
obj.jid += '/' + self.resource
|
||||
|
||||
if not sess:
|
||||
if self.type_id == TYPE_PM:
|
||||
sess = conn.make_new_session(jid, type_='pm')
|
||||
sess = conn.make_new_session(obj.jid, type_='pm')
|
||||
else:
|
||||
sess = conn.make_new_session(jid)
|
||||
sess = conn.make_new_session(obj.jid)
|
||||
|
||||
self.set_session(sess)
|
||||
|
||||
# Send and update history
|
||||
conn.send_message(jid, message, keyID, type_=type_, chatstate=chatstate,
|
||||
msg_id=msg_id, composing_xep=composing_xep, resource=self.resource,
|
||||
user_nick=user_nick, session=self.session,
|
||||
original_message=original_message, xhtml=xhtml, label=label, callback=callback,
|
||||
callback_args=callback_args)
|
||||
obj.session = self.session
|
||||
|
|
Loading…
Reference in New Issue