From 168e87aefd40bf370d0ce9a100943bdfce536ac2 Mon Sep 17 00:00:00 2001
From: Yann Leboulanger <asterix@lagaule.org>
Date: Thu, 24 Mar 2011 22:48:56 +0100
Subject: [PATCH] [Phil] add 2 dbus signals: MessageSent and ChatState. Update
 UI on messagesent. Fixes #6787

---
 src/chat_control.py      | 43 ++++++++++++++++++++++++++++++++++++++--
 src/common/connection.py |  2 +-
 src/remote_control.py    | 25 +++++++++++++++++++++++
 3 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/src/chat_control.py b/src/chat_control.py
index b839ce561d..cec42c60f7 100644
--- a/src/chat_control.py
+++ b/src/chat_control.py
@@ -69,6 +69,11 @@ try:
 except ImportError:
     HAS_GTK_SPELL = False
 
+from common import dbus_support
+if dbus_support:
+    import dbus
+    import remote_control
+
 # the next script, executed in the "po" directory,
 # generates the following list.
 ##!/bin/sh
@@ -1421,6 +1426,18 @@ class ChatControl(ChatControlBase):
         ChatControlBase.__init__(self, self.TYPE_ID, parent_win,
                 'chat_control', contact, acct, resource)
 
+        self._dbus_message_sent_match = None
+        if dbus_support:
+            bus = dbus_support.session_bus.bus()
+            try:
+                obj = bus.get_object(remote_control.SERVICE, remote_control.OBJ_PATH)
+            except:
+                # likely dbus service not started
+                pass
+            else:
+                iface = dbus.Interface(obj, remote_control.INTERFACE)
+                self._dbus_message_sent_match = iface.connect_to_signal("MessageSent", self.on_message_sent)
+
         self.gpg_is_active = False
         # for muc use:
         # widget = self.xml.get_object('muc_window_actions_button')
@@ -2261,6 +2278,23 @@ class ChatControl(ChatControlBase):
                 callback_args=[contact, message, encrypted, xhtml, self.get_seclabel()],
                 process_commands=process_commands)
 
+
+    def on_message_sent(self, account_and_message):
+        # this is called when an external application sends a chat
+        # message using DBus. So we likely need to update the UI
+        # accordingly.
+        message = account_and_message[1][1]
+        jid_and_resource = account_and_message[1][0]
+        if not message:
+            return
+
+        # try to filter based on jid/resource to avoid duplicate
+        # messages.
+        if jid_and_resource.find('/') > -1:
+            jid = jid_and_resource.split('/')[0]
+            if jid == self.contact.jid:
+                self.print_conversation(message, frm='outgoing')
+
     def check_for_possible_paused_chatstate(self, arg):
         """
         Did we move mouse of that window or write something in message textview
@@ -2598,8 +2632,9 @@ class ChatControl(ChatControlBase):
             contact.our_chatstate = 'active'
             self.reset_kbd_mouse_timeout_vars()
 
-        MessageControl.send_message(self, None, chatstate=state,
-                msg_id=contact.msg_id, composing_xep=contact.composing_xep)
+        MessageControl.send_message(self, "", chatstate = state,
+                msg_id = contact.msg_id, composing_xep = contact.composing_xep)
+
         contact.our_chatstate = state
         if contact.our_chatstate == 'active':
             self.reset_kbd_mouse_timeout_vars()
@@ -2612,6 +2647,10 @@ class ChatControl(ChatControlBase):
         # instance object
         gajim.plugin_manager.remove_gui_extension_point('chat_control', self)        # Send 'gone' chatstate
 
+        # disconnect from the dbus MessageSent signal.
+        if self._dbus_message_sent_match:
+            self._dbus_message_sent_match.remove()
+
         gajim.ged.remove_event_handler('pep-received', ged.GUI1,
             self._nec_pep_received)
         gajim.ged.remove_event_handler('vcard-received', ged.GUI1,
diff --git a/src/common/connection.py b/src/common/connection.py
index a857156428..cc95480a22 100644
--- a/src/common/connection.py
+++ b/src/common/connection.py
@@ -1750,7 +1750,7 @@ class Connection(CommonConnection, ConnectionHandlers):
             msg_id = self.connection.send(msg_iq, now=now)
             jid = helpers.parse_jid(jid)
             gajim.nec.push_incoming_event(MessageSentEvent(None, conn=self,
-                jid=jid, message=msg, keyID=keyID))
+                jid=jid, message=msg, keyID=keyID, chatstate=chatstate))
             if callback:
                 callback(msg_id, *callback_args)
 
diff --git a/src/remote_control.py b/src/remote_control.py
index 24a36d110e..4dfe18f604 100644
--- a/src/remote_control.py
+++ b/src/remote_control.py
@@ -131,6 +131,23 @@ class Remote:
             self.on_account_created)
         gajim.ged.register_event_handler('vcard-received', ged.POSTGUI,
             self.on_vcard_received)
+        gajim.ged.register_event_handler('chatstate-received', ged.POSTGUI,
+            self.on_chatstate_received)
+        gajim.ged.register_event_handler('message-sent', ged.POSTGUI,
+            self.on_message_sent)
+
+    def on_chatstate_received(self, obj):
+        self.raise_signal('ChatState', (obj.conn.name, [
+            obj.jid, obj.fjid, obj.stanza, obj.resource, obj.composing_xep,
+            obj.chatstate]))
+
+    def on_message_sent(self, obj):
+        try:
+            chatstate = obj.chatstate
+        except AttributeError:
+            chatstate = ""
+        self.raise_signal('MessageSent', (obj.conn.name, [
+            obj.jid, obj.message, obj.keyID, chatstate]))
 
     def on_last_status_time(self, obj):
         self.raise_signal('LastStatusTime', (obj.conn.name, [
@@ -288,6 +305,14 @@ class SignalObject(dbus.service.Object):
     def NewGmail(self, account_and_array):
         pass
 
+    @dbus.service.signal(INTERFACE, signature='av')
+    def ChatState(self, account_and_array):
+        pass
+
+    @dbus.service.signal(INTERFACE, signature='av')
+    def MessageSent(self, account_and_array):
+        pass
+
     def raise_signal(self, signal, arg):
         """
         Raise a signal, with a single argument of unspecified type Instead of
-- 
GitLab