[ekiga] Huge refactoring of the loudmouth plugin code (and some documentation of it)



commit 429032535e49a7d2f9694aa6b62a2f722a3accd1
Author: Julien Puydt <jpuydt newton localdomain>
Date:   Thu Sep 15 20:29:42 2011 +0200

    Huge refactoring of the loudmouth plugin code (and some documentation of it)
    
    It doesn't work better yet, but it was starting to get hairy ; a sure sign something was amiss

 plugins/loudmouth/Makefile.am                      |    5 +-
 plugins/loudmouth/explanations                     |   37 ++++
 plugins/loudmouth/loudmouth-account.cpp            |  169 +++++++++++++++--
 plugins/loudmouth/loudmouth-account.h              |   17 ++-
 plugins/loudmouth/loudmouth-chat-multiple.h        |    4 +-
 plugins/loudmouth/loudmouth-cluster.cpp            |   80 ++++++++-
 plugins/loudmouth/loudmouth-cluster.h              |   27 +++-
 plugins/loudmouth/loudmouth-dialect.cpp            |   34 ++++
 plugins/loudmouth/loudmouth-dialect.h              |   11 +
 ...oudmouth-heap.cpp => loudmouth-heap-roster.cpp} |  196 ++++++-------------
 .../{loudmouth-heap.h => loudmouth-heap-roster.h}  |   48 +++---
 plugins/loudmouth/loudmouth-main.cpp               |    2 +-
 12 files changed, 442 insertions(+), 188 deletions(-)
---
diff --git a/plugins/loudmouth/Makefile.am b/plugins/loudmouth/Makefile.am
index da8489a..b1e8b9b 100644
--- a/plugins/loudmouth/Makefile.am
+++ b/plugins/loudmouth/Makefile.am
@@ -14,14 +14,15 @@ INCLUDES = \
 libgmloudmouth_la_SOURCES = \
 	$(loudmouth_dir)/loudmouth-main.h \
 	$(loudmouth_dir)/loudmouth-main.cpp \
+	$(loudmouth_dir)/loudmouth-handler.h \
 	$(loudmouth_dir)/loudmouth-bank.h \
 	$(loudmouth_dir)/loudmouth-bank.cpp \
 	$(loudmouth_dir)/loudmouth-account.h \
 	$(loudmouth_dir)/loudmouth-account.cpp \
 	$(loudmouth_dir)/loudmouth-cluster.h \
 	$(loudmouth_dir)/loudmouth-cluster.cpp \
-	$(loudmouth_dir)/loudmouth-heap.h \
-	$(loudmouth_dir)/loudmouth-heap.cpp \
+	$(loudmouth_dir)/loudmouth-heap-roster.h \
+	$(loudmouth_dir)/loudmouth-heap-roster.cpp \
 	$(loudmouth_dir)/loudmouth-presentity.h \
 	$(loudmouth_dir)/loudmouth-presentity.cpp \
 	$(loudmouth_dir)/loudmouth-chat-simple.h \
diff --git a/plugins/loudmouth/explanations b/plugins/loudmouth/explanations
new file mode 100644
index 0000000..a089ba0
--- /dev/null
+++ b/plugins/loudmouth/explanations
@@ -0,0 +1,37 @@
+This directory contains a loudmouth plugin for ekiga.
+
+For short, "lm-" in a file name means "loudmouth-".
+
+The lm-main files are there to turn the rest into a plugin for ekiga.
+
+The lm-bank files implement an Ekiga::Bank class ; that is the way
+XMPP accounts get made available in ekiga's account window.
+
+The lm-account files provide an implementation of the Ekiga::Account
+class, and are what you'll find in the account window. Those are the
+master files in some sense : when you connect an account, that is the
+account which takes care of setting up the connection with the remote
+server, and serve as a hub for the rest of the plugin : the XMPP
+messages get here, and are then passed around the various other
+parts. For this reason, an abstract handler class is defined in
+lm-handler.h : as an XMPP message can be of three types ("iq", "message"
+and "presence"), there is one method for each, plus an handle_up/handle_down
+pair of methods to notify we're going online or offline.
+
+The lm-cluster files provide an implementation of the Ekiga::Cluster
+class, which makes the rosters/friend lists/contact lists available
+with presence in the main window. A roster is an instance of
+Ekiga::Heap, and the implementation is in the lm-heap-roster
+files. Each roster contains Ekiga::Presentity objects, which here are
+implemented in the lm-presentity files. The cluster implements the
+abstract handler class, so you are able to see the presence of your
+contacts.
+
+The lm-dialect files provide an implementation of the Ekiga::Dialect
+class, which makes it possible to have either simple text chats or
+multiple text chats (that meaning that they're either to a single
+contact or to several of them -- you can have several of each of
+them). Quite logically, you'll fin the implementations of those in the
+lm-chat-simple and lm-chat-multiple files. The dialect implements the
+abstract handler class, so you're able to get the messages from your
+contacts in the right tab of the dialog window.
\ No newline at end of file
diff --git a/plugins/loudmouth/loudmouth-account.cpp b/plugins/loudmouth/loudmouth-account.cpp
index badea4c..3651859 100644
--- a/plugins/loudmouth/loudmouth-account.cpp
+++ b/plugins/loudmouth/loudmouth-account.cpp
@@ -41,6 +41,12 @@
 
 #include "loudmouth-account.h"
 
+#define DEBUG 0
+
+#if DEBUG
+#include <iostream>
+#endif
+
 /* here come the C callbacks, which just push to C++ code */
 static void
 on_connection_opened_c (LmConnection* /*unused*/,
@@ -66,6 +72,33 @@ on_authenticate_c (LmConnection* /*unused*/,
   account->on_authenticate (result);
 }
 
+static LmHandlerResult
+iq_handler_c (LmMessageHandler* /*handler*/,
+	      LmConnection* /*connection*/,
+	      LmMessage* message,
+	      LM::Account* account)
+{
+  return account->handle_iq (message);
+}
+
+static LmHandlerResult
+presence_handler_c (LmMessageHandler* /*handler*/,
+		    LmConnection* /*connection*/,
+		    LmMessage* message,
+		    LM::Account* account)
+{
+  return account->handle_presence (message);
+}
+
+static LmHandlerResult
+message_handler_c (LmMessageHandler* /*handler*/,
+		   LmConnection* /*connection*/,
+		   LmMessage* message,
+		   LM::Account* account)
+{
+  return account->handle_message (message);
+}
+
 /* and here is the C++ code : */
 
 LM::Account::Account (boost::shared_ptr<Ekiga::PersonalDetails> details_,
@@ -93,6 +126,16 @@ LM::Account::Account (boost::shared_ptr<Ekiga::PersonalDetails> details_,
   xmlFree (xml_str);
 
   connection = lm_connection_new (NULL);
+
+  iq_lm_handler = lm_message_handler_new ((LmHandleMessageFunction)iq_handler_c, this, NULL);
+  lm_connection_register_message_handler (connection, iq_lm_handler, LM_MESSAGE_TYPE_IQ, LM_HANDLER_PRIORITY_NORMAL);
+
+  presence_lm_handler = lm_message_handler_new ((LmHandleMessageFunction)presence_handler_c, this, NULL);
+  lm_connection_register_message_handler (connection, presence_lm_handler, LM_MESSAGE_TYPE_PRESENCE, LM_HANDLER_PRIORITY_NORMAL);
+
+  message_lm_handler = lm_message_handler_new ((LmHandleMessageFunction)message_handler_c, this, NULL);
+  lm_connection_register_message_handler (connection, message_lm_handler, LM_MESSAGE_TYPE_MESSAGE, LM_HANDLER_PRIORITY_NORMAL);
+
   lm_connection_set_disconnect_function (connection, (LmDisconnectFunction)on_disconnected_c,
 					 this, NULL);
   if (enable_on_startup) {
@@ -204,16 +247,24 @@ LM::Account::disable ()
 
 LM::Account::~Account ()
 {
-  if (heap) {
-
-    heap->disconnected ();
-    heap.reset ();
-  }
-
   if (lm_connection_is_open (connection)) {
 
+    handle_down ();
     lm_connection_close (connection, NULL);
   }
+
+  lm_connection_unregister_message_handler (connection, iq_lm_handler, LM_MESSAGE_TYPE_IQ);
+  lm_message_handler_unref (iq_lm_handler);
+  iq_lm_handler = 0;
+
+  lm_connection_unregister_message_handler (connection, presence_lm_handler, LM_MESSAGE_TYPE_PRESENCE);
+  lm_message_handler_unref (presence_lm_handler);
+  presence_lm_handler = 0;
+
+  lm_connection_unregister_message_handler (connection, message_lm_handler, LM_MESSAGE_TYPE_MESSAGE);
+  lm_message_handler_unref (message_lm_handler);
+  message_lm_handler = 0;
+
   lm_connection_unref (connection);
   connection = 0;
 }
@@ -244,13 +295,10 @@ LM::Account::on_connection_opened (bool result)
 void
 LM::Account::on_disconnected (LmDisconnectReason /*reason*/)
 {
-  if (heap) {
+  handle_down ();
 
-    heap->disconnected ();
-    heap.reset ();
-    status = _("disconnected");
-    updated ();
-  }
+  status = _("disconnected");
+  updated ();
 }
 
 void
@@ -258,13 +306,7 @@ LM::Account::on_authenticate (bool result)
 {
   if (result) {
 
-    heap = boost::shared_ptr<Heap> (new Heap (details, dialect, connection));
-    {
-      xmlChar *xml_str = xmlGetProp (node, BAD_CAST "name");
-      heap->set_name ((const char*)xml_str);
-      xmlFree (xml_str);
-    }
-    cluster->add_heap (heap);
+    handle_up ();
     status = _("connected");
     updated ();
   } else {
@@ -445,3 +487,92 @@ LM::Account::get_name () const
 
   return name;
 }
+
+void
+LM::Account::handle_up ()
+{
+  dialect->handle_up (connection, get_name ());
+  cluster->handle_up (connection, get_name ());
+}
+
+void
+LM::Account::handle_down ()
+{
+  dialect->handle_down (connection);
+  cluster->handle_down (connection);
+}
+
+LmHandlerResult
+LM::Account::handle_iq (LmMessage* message)
+{
+  LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+  if (result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS) {
+
+    result = dialect->handle_iq (connection, message);
+  }
+
+  if (result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS) {
+
+    result = cluster->handle_iq (connection, message);
+  }
+
+#if DEBUG
+  if (result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS) {
+
+    std::cout << "Nobody cared about : " << lm_message_node_to_string (lm_message_get_node (message)) << std::endl;
+  }
+#endif
+
+  return result;
+}
+
+LmHandlerResult
+LM::Account::handle_message (LmMessage* message)
+{
+  LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+  if (result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS) {
+
+    result = dialect->handle_message (connection, message);
+  }
+
+  if (result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS) {
+
+    result = cluster->handle_message (connection, message);
+  }
+
+#if DEBUG
+  if (result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS) {
+
+    std::cout << "Nobody cared about : " << lm_message_node_to_string (lm_message_get_node (message)) << std::endl;
+  }
+#endif
+
+  return result;
+}
+
+LmHandlerResult
+LM::Account::handle_presence (LmMessage* message)
+{
+  LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+  if (result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS) {
+
+    result = dialect->handle_presence (connection, message);
+  }
+
+  if (result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS) {
+
+    result = cluster->handle_presence (connection, message);
+  }
+
+#if DEBUG
+  if (result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS) {
+
+    std::cout << "Nobody cared about : " << lm_message_node_to_string (lm_message_get_node (message)) << std::endl;
+  }
+#endif
+
+  return result;
+}
diff --git a/plugins/loudmouth/loudmouth-account.h b/plugins/loudmouth/loudmouth-account.h
index eaa0732..4fa6ea4 100644
--- a/plugins/loudmouth/loudmouth-account.h
+++ b/plugins/loudmouth/loudmouth-account.h
@@ -40,6 +40,7 @@
 
 #include "account.h"
 
+#include "loudmouth-dialect.h"
 #include "loudmouth-cluster.h"
 
 namespace LM
@@ -88,8 +89,22 @@ namespace LM
 
     void on_authenticate (bool result);
 
+    /* LM::Handler-like interface
+     * but not exactly, since it's the hub from which all information flows
+     * to the real handlers
+     */
+    void handle_up ();
+    void handle_down ();
+    LmHandlerResult handle_iq (LmMessage* message);
+    LmHandlerResult handle_message (LmMessage* message);
+    LmHandlerResult handle_presence (LmMessage* message);
+
   private:
 
+    LmMessageHandler* iq_lm_handler;
+    LmMessageHandler* presence_lm_handler;
+    LmMessageHandler* message_lm_handler;
+
     void edit ();
     void on_edit_form_submitted (bool submitted,
 				 Ekiga::Form &result);
@@ -104,8 +119,6 @@ namespace LM
     std::string status;
 
     LmConnection* connection;
-
-    boost::shared_ptr<Heap> heap;
   };
 };
 
diff --git a/plugins/loudmouth/loudmouth-chat-multiple.h b/plugins/loudmouth/loudmouth-chat-multiple.h
index 0a26370..1359681 100644
--- a/plugins/loudmouth/loudmouth-chat-multiple.h
+++ b/plugins/loudmouth/loudmouth-chat-multiple.h
@@ -39,7 +39,7 @@
 #include "services.h"
 #include "chat-multiple.h"
 
-#include "loudmouth-heap.h"
+#include <loudmouth/loudmouth.h>
 
 namespace LM
 {
@@ -75,7 +75,7 @@ namespace LM
     Ekiga::ServiceCore& core;
     LmConnection* connection;
     std::list<boost::shared_ptr<Ekiga::ChatObserver> > observers;
-    HeapPtr heap;
+    Ekiga::HeapPtr heap; // FIXME: it needs a loudmouth-heap-chat!
     std::string my_name;
   };
 
diff --git a/plugins/loudmouth/loudmouth-cluster.cpp b/plugins/loudmouth/loudmouth-cluster.cpp
index 7c05520..ced121a 100644
--- a/plugins/loudmouth/loudmouth-cluster.cpp
+++ b/plugins/loudmouth/loudmouth-cluster.cpp
@@ -35,7 +35,9 @@
 
 #include "loudmouth-cluster.h"
 
-LM::Cluster::Cluster ()
+LM::Cluster::Cluster (boost::shared_ptr<LM::Dialect> dialect_,
+		      boost::shared_ptr<Ekiga::PersonalDetails> details_):
+  dialect(dialect_), details(details_)
 {
 }
 
@@ -48,3 +50,79 @@ LM::Cluster::populate_menu (Ekiga::MenuBuilder& /*builder*/)
 {
   return false;
 }
+
+void
+LM::Cluster::handle_up (LmConnection* connection,
+			const std::string name)
+{
+  HeapRosterPtr heap = boost::shared_ptr<HeapRoster> (new HeapRoster (details, dialect));
+  add_heap (heap);
+  heap->handle_up (connection, name);
+}
+
+void
+LM::Cluster::handle_down (LmConnection* connection)
+{
+  for (iterator it = begin (); it != end (); ++it) {
+
+    if ((*it)->get_connection () == connection) {
+
+      (*it)->handle_down (connection);
+      break;
+    }
+  }
+}
+
+LmHandlerResult
+LM::Cluster::handle_iq (LmConnection* connection,
+			LmMessage* message)
+{
+  LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+  for (iterator it = begin (); it != end (); ++it) {
+
+    if ((*it)->get_connection () == connection) {
+
+      result = (*it)->handle_iq (connection, message);
+      break;
+    }
+  }
+
+  return result;
+}
+
+LmHandlerResult
+LM::Cluster::handle_message (LmConnection* connection,
+			     LmMessage* message)
+{
+  LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+  for (iterator it = begin (); it != end (); ++it) {
+
+    if ((*it)->get_connection () == connection) {
+
+      result = (*it)->handle_message (connection, message);
+      break;
+    }
+  }
+
+  return result;
+}
+
+LmHandlerResult
+LM::Cluster::handle_presence (LmConnection* connection,
+			      LmMessage* message)
+{
+  LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+  for (iterator it = begin (); it != end (); ++it) {
+
+    if ((*it)->get_connection () == connection) {
+
+      result = (*it)->handle_presence (connection, message);
+      break;
+    }
+  }
+
+  return result;
+}
diff --git a/plugins/loudmouth/loudmouth-cluster.h b/plugins/loudmouth/loudmouth-cluster.h
index f99c1b8..54647e0 100644
--- a/plugins/loudmouth/loudmouth-cluster.h
+++ b/plugins/loudmouth/loudmouth-cluster.h
@@ -38,22 +38,41 @@
 
 #include "cluster-impl.h"
 
-#include "loudmouth-heap.h"
+#include "loudmouth-handler.h"
+#include "loudmouth-heap-roster.h"
 
 namespace LM
 {
   class Cluster:
-    public Ekiga::ClusterImpl<Heap>
+    public Ekiga::ClusterImpl<HeapRoster>,
+    public LM::Handler
   {
   public:
 
-    Cluster ();
+    Cluster (boost::shared_ptr<LM::Dialect> dialect_,
+	     boost::shared_ptr<Ekiga::PersonalDetails> details_);
 
     ~Cluster ();
 
-    using Ekiga::ClusterImpl<Heap>::add_heap;
+    using Ekiga::ClusterImpl<HeapRoster>::add_heap;
 
     bool populate_menu (Ekiga::MenuBuilder& builder);
+
+    /* LM::Handler implementation */
+    void handle_up (LmConnection* connection,
+		    const std::string name);
+    void handle_down (LmConnection* connection);
+    LmHandlerResult handle_iq (LmConnection* connection,
+			       LmMessage* message);
+    LmHandlerResult handle_message (LmConnection* connection,
+				    LmMessage* message);
+    LmHandlerResult handle_presence (LmConnection* connection,
+				     LmMessage* message);
+
+  private:
+
+    boost::shared_ptr<LM::Dialect> dialect;
+    boost::shared_ptr<Ekiga::PersonalDetails> details;
   };
 
   typedef boost::shared_ptr<Cluster> ClusterPtr;
diff --git a/plugins/loudmouth/loudmouth-dialect.cpp b/plugins/loudmouth/loudmouth-dialect.cpp
index 3825271..17c5d26 100644
--- a/plugins/loudmouth/loudmouth-dialect.cpp
+++ b/plugins/loudmouth/loudmouth-dialect.cpp
@@ -152,3 +152,37 @@ LM::Dialect::on_open_group_chat_submitted (bool submitted,
 
   std::cout << "Should enter the room '" << name << "' with pseudonym '" << pseudo << "'" << std::endl;
 }
+
+void
+LM::Dialect::handle_up (LmConnection* connection,
+			const std::string name)
+{
+  /* nothing to do afaict */
+}
+
+void
+LM::Dialect::handle_down (LmConnection* connection)
+{
+  // FIXME: here we should find all dead c(h)ats
+}
+
+LmHandlerResult
+LM::Dialect::handle_iq (LmConnection* connection,
+			LmMessage* message)
+{
+  return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // FIXME: implement properly
+}
+
+LmHandlerResult
+LM::Dialect::handle_message (LmConnection* connection,
+			     LmMessage* message)
+{
+  return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // FIXME: implement properly
+}
+
+LmHandlerResult
+LM::Dialect::handle_presence (LmConnection* connection,
+			      LmMessage* message)
+{
+  return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // FIXME: implement properly
+}
diff --git a/plugins/loudmouth/loudmouth-dialect.h b/plugins/loudmouth/loudmouth-dialect.h
index 77e7cea..aff221f 100644
--- a/plugins/loudmouth/loudmouth-dialect.h
+++ b/plugins/loudmouth/loudmouth-dialect.h
@@ -59,6 +59,17 @@ namespace LM
 
     void open_chat (PresentityPtr presentity);
 
+    /* LM::Handler implementation */
+    void handle_up (LmConnection* connection,
+		    const std::string name);
+    void handle_down (LmConnection* connection);
+    LmHandlerResult handle_iq (LmConnection* connection,
+			       LmMessage* message);
+    LmHandlerResult handle_message (LmConnection* connection,
+				    LmMessage* message);
+    LmHandlerResult handle_presence (LmConnection* connection,
+				     LmMessage* message);
+
   private:
 
     Ekiga::ServiceCore& core;
diff --git a/plugins/loudmouth/loudmouth-heap.cpp b/plugins/loudmouth/loudmouth-heap-roster.cpp
similarity index 69%
rename from plugins/loudmouth/loudmouth-heap.cpp
rename to plugins/loudmouth/loudmouth-heap-roster.cpp
index 382ec6b..e366b32 100644
--- a/plugins/loudmouth/loudmouth-heap.cpp
+++ b/plugins/loudmouth/loudmouth-heap-roster.cpp
@@ -38,52 +38,52 @@
 
 #include "form-request-simple.h"
 
-#include "loudmouth-heap.h"
+#include "loudmouth-heap-roster.h"
 
-static LmHandlerResult
-iq_handler_c (LmMessageHandler* /*handler*/,
-	      LmConnection* /*connection*/,
-	      LmMessage* message,
-	      LM::Heap* heap)
+LM::HeapRoster::HeapRoster (boost::shared_ptr<Ekiga::PersonalDetails> details_,
+			    DialectPtr dialect_):
+  details(details_), dialect(dialect_)
 {
-  return heap->iq_handler (message);
+  details->updated.connect (boost::bind (&LM::HeapRoster::on_personal_details_updated, this));
 }
 
-static LmHandlerResult
-presence_handler_c (LmMessageHandler* /*handler*/,
-		    LmConnection* /*connection*/,
-		    LmMessage* message,
-		    LM::Heap* heap)
+LM::HeapRoster::~HeapRoster ()
 {
-  return heap->presence_handler (message);
 }
 
-static LmHandlerResult
-message_handler_c (LmMessageHandler* /*handler*/,
-		   LmConnection* /*connection*/,
-		   LmMessage* message,
-		   LM::Heap* heap)
+const std::string
+LM::HeapRoster::get_name () const
 {
-  return heap->message_handler (message);
+  return name;
 }
 
-LM::Heap::Heap (boost::shared_ptr<Ekiga::PersonalDetails> details_,
-		DialectPtr dialect_,
-		LmConnection* connection_):
-  details(details_), dialect(dialect_), connection(connection_)
+LmConnection*
+LM::HeapRoster::get_connection () const
 {
-  details->updated.connect (boost::bind (&LM::Heap::on_personal_details_updated, this));
-
-  lm_connection_ref (connection);
+  return connection;
+}
 
-  iq_lm_handler = lm_message_handler_new ((LmHandleMessageFunction)iq_handler_c, this, NULL);
-  lm_connection_register_message_handler (connection, iq_lm_handler, LM_MESSAGE_TYPE_IQ, LM_HANDLER_PRIORITY_NORMAL);
+bool
+LM::HeapRoster::populate_menu (Ekiga::MenuBuilder& builder)
+{
+  builder.add_action ("new", _("New _Contact"), boost::bind (&LM::HeapRoster::add_item, this));
+  dialect->populate_menu (builder);
+  return true;
+}
 
-  presence_lm_handler = lm_message_handler_new ((LmHandleMessageFunction)presence_handler_c, this, NULL);
-  lm_connection_register_message_handler (connection, presence_lm_handler, LM_MESSAGE_TYPE_PRESENCE, LM_HANDLER_PRIORITY_NORMAL);
+bool
+LM::HeapRoster::populate_menu_for_group (const std::string /*group*/,
+					 Ekiga::MenuBuilder& /*builder*/)
+{
+  return false;
+}
 
-  message_lm_handler = lm_message_handler_new ((LmHandleMessageFunction)message_handler_c, this, NULL);
-  lm_connection_register_message_handler (connection, message_lm_handler, LM_MESSAGE_TYPE_MESSAGE, LM_HANDLER_PRIORITY_NORMAL);
+void
+LM::HeapRoster::handle_up (LmConnection* connection_,
+			   const std::string name_)
+{
+  connection = connection_;
+  name = name_;
 
   { // populate the roster
     LmMessage* roster_request = lm_message_new_with_sub_type (NULL, LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_GET);
@@ -99,76 +99,20 @@ LM::Heap::Heap (boost::shared_ptr<Ekiga::PersonalDetails> details_,
   }
 
   on_personal_details_updated (); // fake, but if we start as dnd, we want it known
-}
-
-LM::Heap::~Heap ()
-{
-  lm_connection_unregister_message_handler (connection, iq_lm_handler, LM_MESSAGE_TYPE_IQ);
-  lm_message_handler_unref (iq_lm_handler);
-  iq_lm_handler = 0;
-
-  lm_connection_unregister_message_handler (connection, presence_lm_handler, LM_MESSAGE_TYPE_PRESENCE);
-  lm_message_handler_unref (presence_lm_handler);
-  presence_lm_handler = 0;
-
-  lm_connection_unregister_message_handler (connection, message_lm_handler, LM_MESSAGE_TYPE_MESSAGE);
-  lm_message_handler_unref (message_lm_handler);
-  message_lm_handler = 0;
-
-  lm_connection_unref (connection);
-  connection = 0;
-}
-
-const std::string
-LM::Heap::get_name () const
-{
-  return name;
-}
-
-void
-LM::Heap::set_name (const std::string name_)
-{
-  name = name_;
   updated ();
 }
 
-bool
-LM::Heap::populate_menu (Ekiga::MenuBuilder& builder)
-{
-  builder.add_action ("new", _("New _Contact"), boost::bind (&LM::Heap::add_item, this));
-  dialect->populate_menu (builder);
-  return true;
-}
-
-bool
-LM::Heap::populate_menu_for_group (const std::string /*group*/,
-				   Ekiga::MenuBuilder& /*builder*/)
-{
-  return false;
-}
-
-
 void
-LM::Heap::disconnected ()
+LM::HeapRoster::handle_down (LmConnection* /*connection*/)
 {
   removed ();
 }
 
 LmHandlerResult
-LM::Heap::iq_handler (LmMessage* message)
-{
-  return iq_handler_roster (message);
-}
-
-LmHandlerResult
-LM::Heap::iq_handler_muc (LmMessage* message)
-{
-  return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // FIXME: implement properly
-}
-
-LmHandlerResult
-LM::Heap::iq_handler_roster (LmMessage* message)
+LM::HeapRoster::handle_iq (LmConnection* /*connection*/,
+			   LmMessage* message)
 {
+  LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
   if (lm_message_get_sub_type (message) == LM_MESSAGE_SUB_TYPE_SET
       || lm_message_get_sub_type (message) == LM_MESSAGE_SUB_TYPE_RESULT) {
 
@@ -179,28 +123,19 @@ LM::Heap::iq_handler_roster (LmMessage* message)
       if (xmlns != NULL && strcmp (xmlns, "jabber:iq:roster") == 0) {
 
 	parse_roster (node);
+	result = LM_HANDLER_RESULT_REMOVE_MESSAGE;
       }
     }
   }
 
-  return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
-}
-
-LmHandlerResult
-LM::Heap::presence_handler (LmMessage* message)
-{
-  return presence_handler_roster (message);
-}
-
-LmHandlerResult
-LM::Heap::presence_handler_muc (LmMessage* message)
-{
-  return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // FIXME: implement properly
+  return result;
 }
 
 LmHandlerResult
-LM::Heap::presence_handler_roster (LmMessage* message)
+LM::HeapRoster::handle_presence (LmConnection* /*connection*/,
+				 LmMessage* message)
 {
+  LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
   const gchar* from_c = lm_message_node_get_attribute (lm_message_get_node (message), "from");
   const gchar* type_attr = lm_message_node_get_attribute (lm_message_get_node (message), "type");
   std::string base_jid;
@@ -218,7 +153,8 @@ LM::Heap::presence_handler_roster (LmMessage* message)
 
   if (type_attr != NULL && strcmp (type_attr, "subscribe") == 0) {
 
-    boost::shared_ptr<Ekiga::FormRequestSimple> request = boost::shared_ptr<Ekiga::FormRequestSimple> (new Ekiga::FormRequestSimple (boost::bind (&LM::Heap::subscribe_from_form_submitted, this, _1, _2)));
+    result = LM_HANDLER_RESULT_REMOVE_MESSAGE;
+    boost::shared_ptr<Ekiga::FormRequestSimple> request = boost::shared_ptr<Ekiga::FormRequestSimple> (new Ekiga::FormRequestSimple (boost::bind (&LM::HeapRoster::subscribe_from_form_submitted, this, _1, _2)));
     LmMessageNode* status = lm_message_node_find_child (lm_message_get_node (message), "status");
     gchar* instructions = NULL;
     std::string item_name;
@@ -258,28 +194,19 @@ LM::Heap::presence_handler_roster (LmMessage* message)
 
     if (item) {
 
-      item->push_presence (resource, lm_message_get_node (message));
+     result = LM_HANDLER_RESULT_REMOVE_MESSAGE;
+     item->push_presence (resource, lm_message_get_node (message));
     }
   }
 
-  return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
-}
-
-LmHandlerResult
-LM::Heap::message_handler (LmMessage* message)
-{
-  return message_handler_roster (message);
-}
-
-LmHandlerResult
-LM::Heap::message_handler_muc (LmMessage* message)
-{
-  return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // FIXME: implement properly
+  return result;
 }
 
 LmHandlerResult
-LM::Heap::message_handler_roster (LmMessage* message)
+LM::HeapRoster::handle_message (LmConnection* /*connection*/,
+				LmMessage* message)
 {
+  LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
   LmMessageNode* node = lm_message_get_node (message);
   const gchar* from_c = lm_message_node_get_attribute (node, "from");
   const gchar* type_attr = lm_message_node_get_attribute (node, "type");
@@ -302,16 +229,17 @@ LM::Heap::message_handler_roster (LmMessage* message)
     LmMessageNode* body = lm_message_node_find_child (node, "body");
     if (body && lm_message_node_get_value (body) != NULL) {
 
+      result = LM_HANDLER_RESULT_REMOVE_MESSAGE;
       dialect->push_message (item, lm_message_node_get_value (body));
     }
     // it could also be an avatar or a pubsub event or...
   }
 
-  return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  return result;
 }
 
 void
-LM::Heap::parse_roster (LmMessageNode* query)
+LM::HeapRoster::parse_roster (LmMessageNode* query)
 {
   for (LmMessageNode* node = query->children; node != NULL; node = node->next) {
 
@@ -340,16 +268,16 @@ LM::Heap::parse_roster (LmMessageNode* query)
     if ( !found) {
 
       PresentityPtr presentity(new Presentity (connection, node));
-      presentity->chat_requested.connect (boost::bind (&LM::Heap::on_chat_requested, this, presentity));
+      presentity->chat_requested.connect (boost::bind (&LM::HeapRoster::on_chat_requested, this, presentity));
       add_presentity (presentity);
     }
   }
 }
 
 void
-LM::Heap::add_item ()
+LM::HeapRoster::add_item ()
 {
-  boost::shared_ptr<Ekiga::FormRequestSimple> request = boost::shared_ptr<Ekiga::FormRequestSimple> (new Ekiga::FormRequestSimple (boost::bind (&LM::Heap::add_item_form_submitted, this, _1, _2)));
+  boost::shared_ptr<Ekiga::FormRequestSimple> request = boost::shared_ptr<Ekiga::FormRequestSimple> (new Ekiga::FormRequestSimple (boost::bind (&LM::HeapRoster::add_item_form_submitted, this, _1, _2)));
 
   request->title (_("Add a roster element"));
   request->instructions (_("Please fill in this form to add a new"
@@ -360,8 +288,8 @@ LM::Heap::add_item ()
 }
 
 void
-LM::Heap::add_item_form_submitted (bool submitted,
-				   Ekiga::Form& result)
+LM::HeapRoster::add_item_form_submitted (bool submitted,
+					 Ekiga::Form& result)
 {
   if ( !submitted)
     return;
@@ -380,8 +308,8 @@ LM::Heap::add_item_form_submitted (bool submitted,
 }
 
 void
-LM::Heap::subscribe_from_form_submitted (bool submitted,
-					 Ekiga::Form& result)
+LM::HeapRoster::subscribe_from_form_submitted (bool submitted,
+					       Ekiga::Form& result)
 {
   if ( !submitted)
     return;
@@ -418,7 +346,7 @@ LM::Heap::subscribe_from_form_submitted (bool submitted,
 }
 
 LM::PresentityPtr
-LM::Heap::find_item (const std::string jid)
+LM::HeapRoster::find_item (const std::string jid)
 {
   PresentityPtr result;
 
@@ -435,7 +363,7 @@ LM::Heap::find_item (const std::string jid)
 }
 
 void
-LM::Heap::on_personal_details_updated ()
+LM::HeapRoster::on_personal_details_updated ()
 {
   LmMessage* message = lm_message_new (NULL, LM_MESSAGE_TYPE_PRESENCE);
 
@@ -447,7 +375,7 @@ LM::Heap::on_personal_details_updated ()
 }
 
 void
-LM::Heap::on_chat_requested (PresentityPtr presentity)
+LM::HeapRoster::on_chat_requested (PresentityPtr presentity)
 {
   dialect->open_chat (presentity);
 }
diff --git a/plugins/loudmouth/loudmouth-heap.h b/plugins/loudmouth/loudmouth-heap-roster.h
similarity index 72%
rename from plugins/loudmouth/loudmouth-heap.h
rename to plugins/loudmouth/loudmouth-heap-roster.h
index 34c9f2b..0fe45d9 100644
--- a/plugins/loudmouth/loudmouth-heap.h
+++ b/plugins/loudmouth/loudmouth-heap-roster.h
@@ -25,34 +25,35 @@
 
 
 /*
- *                         loudmouth-heap.h  -  description
+ *                         loudmouth-heap-roster.h  -  description
  *                         ------------------------------------------
- *   begin                : written in 2008 by Julien Puydt
- *   copyright            : (c) 2008 by Julien Puydt
- *   description          : declaration of a loudmouth heap
+ *   begin                : written in 2008-2011 by Julien Puydt
+ *   copyright            : (c) 2008-2011 by Julien Puydt
+ *   description          : declaration of a loudmouth heap for the roster
  *
  */
 
-#ifndef __LOUDMOUTH_HEAP_H__
-#define __LOUDMOUTH_HEAP_H__
+#ifndef __LOUDMOUTH_HEAP_ROSTER_H__
+#define __LOUDMOUTH_HEAP_ROSTER_H__
 
 #include "heap-impl.h"
 #include "personal-details.h"
 #include "loudmouth-dialect.h"
+#include "loudmouth-handler.h"
 
 namespace LM
 {
-  class Heap:
+  class HeapRoster:
     public Ekiga::HeapImpl<Presentity>,
+    public LM::Handler,
     public boost::signals::trackable
   {
   public:
 
-    Heap (boost::shared_ptr<Ekiga::PersonalDetails> details_,
-	  DialectPtr dialect_,
-	  LmConnection* connection_);
+    HeapRoster (boost::shared_ptr<Ekiga::PersonalDetails> details_,
+		DialectPtr dialect_);
 
-    ~Heap ();
+    ~HeapRoster ();
 
     const std::string get_name () const;
 
@@ -61,11 +62,7 @@ namespace LM
     bool populate_menu_for_group (const std::string group,
 				  Ekiga::MenuBuilder& builder);
 
-    void disconnected ();
-
-    /* public to be accessed by the account */
-
-    void set_name (const std::string name_);
+    LmConnection* get_connection () const;
 
     /* public to be accessed by C callbacks */
 
@@ -75,6 +72,17 @@ namespace LM
 
     LmHandlerResult message_handler (LmMessage* message);
 
+    // implementation of the LM::Handler abstract class :
+    void handle_up (LmConnection* connection,
+		    const std::string name);
+    void handle_down (LmConnection* connection);
+    LmHandlerResult handle_iq (LmConnection* connection,
+			       LmMessage* message);
+    LmHandlerResult handle_message (LmConnection* connection,
+				    LmMessage* message);
+    LmHandlerResult handle_presence (LmConnection* connection,
+				     LmMessage* message);
+
   private:
 
     boost::shared_ptr<Ekiga::PersonalDetails> details;
@@ -85,12 +93,6 @@ namespace LM
 
     LmConnection* connection;
 
-    LmMessageHandler* iq_lm_handler;
-
-    LmMessageHandler* presence_lm_handler;
-
-    LmMessageHandler* message_lm_handler;
-
     void parse_roster (LmMessageNode* query);
 
     void add_item ();
@@ -117,7 +119,7 @@ namespace LM
     LmHandlerResult message_handler_muc (LmMessage* message);
   };
 
-  typedef boost::shared_ptr<Heap> HeapPtr;
+  typedef boost::shared_ptr<HeapRoster> HeapRosterPtr;
 
 };
 
diff --git a/plugins/loudmouth/loudmouth-main.cpp b/plugins/loudmouth/loudmouth-main.cpp
index 311ebc5..66a1073 100644
--- a/plugins/loudmouth/loudmouth-main.cpp
+++ b/plugins/loudmouth/loudmouth-main.cpp
@@ -62,7 +62,7 @@ struct LOUDMOUTHSpark: public Ekiga::Spark
     if (presence && account && chat && details) {
 
       LM::DialectPtr dialect(new LM::Dialect (core));
-      LM::ClusterPtr cluster(new LM::Cluster);
+      LM::ClusterPtr cluster(new LM::Cluster (dialect, details));
       LM::BankPtr bank (new LM::Bank (details, dialect, cluster));
       if (core.add (bank)) {
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]