ekiga r7287 - trunk/lib/engine/components/resource-list



Author: jpuydt
Date: Sat Oct 25 13:25:32 2008
New Revision: 7287
URL: http://svn.gnome.org/viewvc/ekiga?rev=7287&view=rev

Log:
New resource-lists code

Added:
   trunk/lib/engine/components/resource-list/rl-presentity.cpp
   trunk/lib/engine/components/resource-list/rl-presentity.h
Modified:
   trunk/lib/engine/components/resource-list/Makefile.am
   trunk/lib/engine/components/resource-list/resource-list-main.cpp
   trunk/lib/engine/components/resource-list/rl-cluster.cpp
   trunk/lib/engine/components/resource-list/rl-cluster.h
   trunk/lib/engine/components/resource-list/rl-heap.cpp
   trunk/lib/engine/components/resource-list/rl-heap.h

Modified: trunk/lib/engine/components/resource-list/Makefile.am
==============================================================================
--- trunk/lib/engine/components/resource-list/Makefile.am	(original)
+++ trunk/lib/engine/components/resource-list/Makefile.am	Sat Oct 25 13:25:32 2008
@@ -15,12 +15,8 @@
 libgmresource_list_la_SOURCES = \
 	$(resource_list_dir)/resource-list-main.h \
 	$(resource_list_dir)/resource-list-main.cpp \
-	$(resource_list_dir)/rl-entry.h \
-	$(resource_list_dir)/rl-entry.cpp \
-	$(resource_list_dir)/rl-entry-ref.h \
-	$(resource_list_dir)/rl-entry-ref.cpp \
-	$(resource_list_dir)/rl-list.h \
-	$(resource_list_dir)/rl-list.cpp \
+	$(resource_list_dir)/rl-presentity.h \
+	$(resource_list_dir)/rl-presentity.cpp \
 	$(resource_list_dir)/rl-heap.h \
 	$(resource_list_dir)/rl-heap.cpp \
 	$(resource_list_dir)/rl-cluster.h \

Modified: trunk/lib/engine/components/resource-list/resource-list-main.cpp
==============================================================================
--- trunk/lib/engine/components/resource-list/resource-list-main.cpp	(original)
+++ trunk/lib/engine/components/resource-list/resource-list-main.cpp	Sat Oct 25 13:25:32 2008
@@ -38,6 +38,7 @@
 
 #include "resource-list-main.h"
 #include "presence-core.h"
+#include "xcap-core.h"
 #include "rl-cluster.h"
 
 bool

Modified: trunk/lib/engine/components/resource-list/rl-cluster.cpp
==============================================================================
--- trunk/lib/engine/components/resource-list/rl-cluster.cpp	(original)
+++ trunk/lib/engine/components/resource-list/rl-cluster.cpp	Sat Oct 25 13:25:32 2008
@@ -85,7 +85,7 @@
     doc = xmlNewDoc (BAD_CAST "1.0");
     xmlNodePtr root = xmlNewDocNode (doc, NULL, BAD_CAST "list", NULL);
     xmlDocSetRootElement (doc, root);
-    add ("https://xcap.sipthor.net/xcap-root";, "alice", "123", "alice example com", "XCAP Test"); // FIXME: remove
+    add ("https://xcap.sipthor.net/xcap-root";, "alice", "123", "alice example com", "XCAP Test", false); // FIXME: remove
   }
 }
 
@@ -100,7 +100,7 @@
 {
   builder.add_action ("new", _("New resource list"),
 		      sigc::bind (sigc::mem_fun (this, &RL::Cluster::new_heap),
-				  "", "", "", "", ""));
+				  "", "", "", "", "", false));
   return true;
 }
 
@@ -117,9 +117,10 @@
 		  const std::string username,
 		  const std::string password,
 		  const std::string user,
-		  const std::string name)
+		  const std::string name,
+		  bool writable)
 {
-  Heap* heap = new Heap (core, name, uri, user, username, password);
+  Heap* heap = new Heap (core, name, uri, user, username, password, writable);
   xmlNodePtr root = xmlDocGetRootElement (doc);
 
   xmlAddChild (root, heap->get_node ());
@@ -156,7 +157,8 @@
 		       const std::string uri,
 		       const std::string username,
 		       const std::string password,
-		       const std::string user)
+		       const std::string user,
+		       bool writable)
 {
   Ekiga::FormRequestSimple request(sigc::mem_fun (this, &RL::Cluster::on_new_heap_form_submitted));
 
@@ -165,6 +167,7 @@
 			  "contact list to ekiga's remote roster"));
   request.text ("name", _("Name:"), name);
   request.text ("uri", _("Address:"), uri);
+  request.boolean ("writable", _("Writable:"), writable);
   request.text ("username", _("Username:"), username);
   request.private_text ("password", _("Password:"), password);
   request.text ("user", _("User:"), user);
@@ -193,8 +196,9 @@
     const std::string username = result.text ("username");
     const std::string password = result.private_text ("password");
     const std::string user = result.text ("user");
+    bool writable = result.boolean ("writable");
 
-    add (name, uri, username, password, user);
+    add (name, uri, username, password, user, writable);
   } catch (Ekiga::Form::not_found) {
 
 #ifdef __GNUC__

Modified: trunk/lib/engine/components/resource-list/rl-cluster.h
==============================================================================
--- trunk/lib/engine/components/resource-list/rl-cluster.h	(original)
+++ trunk/lib/engine/components/resource-list/rl-cluster.h	Sat Oct 25 13:25:32 2008
@@ -72,7 +72,8 @@
 	      const std::string username,
 	      const std::string password,
 	      const std::string user,
-	      const std::string name);
+	      const std::string name,
+	      bool writable);
     void common_add (Heap& heap);
     void save () const;
 
@@ -80,7 +81,8 @@
 		   const std::string uri,
 		   const std::string username,
 		   const std::string password,
-		   const std::string user);
+		   const std::string user,
+		   bool writable);
 
     void on_new_heap_form_submitted (bool submitted,
 				     Ekiga::Form& result);

Modified: trunk/lib/engine/components/resource-list/rl-heap.cpp
==============================================================================
--- trunk/lib/engine/components/resource-list/rl-heap.cpp	(original)
+++ trunk/lib/engine/components/resource-list/rl-heap.cpp	Sat Oct 25 13:25:32 2008
@@ -41,17 +41,29 @@
 
 #include "robust-xml.h"
 #include "form-request-simple.h"
+#include "xcap-core.h"
 
 #include "rl-heap.h"
 
-RL::Heap::Heap (Ekiga::ServiceCore& core_,
+RL::Heap::Heap (Ekiga::ServiceCore& services_,
 		xmlNodePtr node_):
-  core(core_),
+  services(services_),
   node(node_), name(NULL),
   root(NULL), user(NULL),
   username(NULL), password(NULL),
   doc(NULL)
 {
+  {
+    xmlChar* xml_str = NULL;
+
+    xml_str = xmlGetProp (node, BAD_CAST "writable");
+    if (xml_str != NULL)
+	xmlFree (xml_str);
+    else {
+      xmlSetProp (node, BAD_CAST "writable", BAD_CAST "0");
+    }
+  }
+
   for (xmlNodePtr child = node->children; child != NULL; child = child->next) {
 
     if (child->type == XML_ELEMENT_NODE
@@ -101,19 +113,25 @@
   refresh ();
 }
 
-RL::Heap::Heap (Ekiga::ServiceCore& core_,
+RL::Heap::Heap (Ekiga::ServiceCore& services_,
 		const std::string name_,
 		const std::string root_,
 		const std::string user_,
 		const std::string username_,
-		const std::string password_):
-  core(core_),
+		const std::string password_,
+		bool writable_):
+  services(services_),
   node(NULL), name(NULL),
   root(NULL), user(NULL),
   username(NULL), password(NULL),
   doc(NULL)
 {
   node = xmlNewNode (NULL, BAD_CAST "entry");
+  if (writable_)
+    xmlSetProp (node, BAD_CAST "writable", BAD_CAST "1");
+  else
+    xmlSetProp (node, BAD_CAST "writable", BAD_CAST "0");
+
   if ( !name_.empty ())
     name = xmlNewChild (node, NULL,
 			BAD_CAST "name",
@@ -169,10 +187,11 @@
 {
   bool go_on = true;
 
-  for (std::list<gmref_ptr<List> >::iterator iter = lists.begin ();
-       go_on && iter != lists.end ();
+  for (std::map<gmref_ptr<Presentity>,std::list<sigc::connection> >::iterator
+	 iter = presentities.begin ();
+       go_on && iter != presentities.end ();
        ++iter)
-    go_on = (*iter)->visit_presentities (visitor);
+    go_on = visitor (*iter->first);
 }
 
 bool
@@ -201,7 +220,7 @@
 void
 RL::Heap::refresh ()
 {
-  gmref_ptr<XCAP::Core> xcap = core.get ("xcap-core");
+  gmref_ptr<XCAP::Core> xcap(services.get ("xcap-core"));
   std::string root_str;
   std::string username_str;
   std::string password_str;
@@ -232,11 +251,16 @@
   path->set_credentials (username_str, password_str);
   path = path->build_child ("resource-lists");
 
-  for (std::list<gmref_ptr<List> >::iterator iter = lists.begin ();
-       iter != lists.end ();
-       ++iter)
-    (*iter)->flush ();
-  lists.clear ();
+  while (presentities.begin () != presentities.end ()) {
+
+    presentities.begin()->first->removed.emit ();
+    for (std::list<sigc::connection>::iterator iter2
+	   = presentities.begin()->second.begin ();
+	 iter2 != presentities.begin()->second.end ();
+	 ++iter2)
+      iter2->disconnect ();
+    presentities.erase (presentities.begin()->first);
+  }
 
   if (doc)
     xmlFreeDoc (doc);
@@ -276,37 +300,6 @@
     doc = NULL;
   } else {
 
-    int pos = 1;
-    std::string root_str;
-    std::string user_str;
-    std::string username_str;
-    std::string password_str;
-
-    {
-      xmlChar* str = xmlNodeGetContent (root);
-      if (str != NULL)
-	root_str = (const char*)str;
-    }
-    {
-      xmlChar* str = xmlNodeGetContent (user);
-      if (str != NULL)
-	user_str = (const char*)str;
-    }
-    {
-      xmlChar* str = xmlNodeGetContent (username);
-      if (str != NULL)
-	username_str = (const char*)str;
-    }
-    {
-      xmlChar* str = xmlNodeGetContent (password);
-      if (str != NULL)
-	password_str = (const char*)str;
-    }
-
-    gmref_ptr<XCAP::Path> path(new XCAP::Path (root_str, "resource-lists",
-					       user_str));
-    path->set_credentials (username_str, password_str);
-    path = path->build_child ("resource-lists");
 
     for (xmlNodePtr child = doc_root->children;
 	 child != NULL;
@@ -315,54 +308,101 @@
 	  && child->name != NULL
 	  && xmlStrEqual (BAD_CAST ("list"), child->name)) {
 
-	gmref_ptr<List> list(new List (core, path, pos, "", child));
-	list->entry_added.connect (sigc::mem_fun (this, &RL::Heap::on_entry_added));
-	list->entry_updated.connect (sigc::mem_fun (this, &RL::Heap::on_entry_updated));
-	list->entry_removed.connect (sigc::mem_fun (this, &RL::Heap::on_entry_removed));
-	lists.push_back (list);
-	pos++;
-	list->publish ();
-	continue;
+	parse_list (child);
+	break; // read only one!
       }
   }
 }
 
 void
-RL::Heap::push_presence (const std::string uri_,
-			 const std::string presence)
+RL::Heap::parse_list (xmlNodePtr list)
 {
-  for (std::list<gmref_ptr<List> >::iterator iter = lists.begin ();
-       iter != lists.end ();
-       ++iter)
-    (*iter)->push_presence (uri_, presence);
-}
+  std::string root_str;
+  std::string user_str;
+  std::string username_str;
+  std::string password_str;
+  bool writable = false;
 
-void
-RL::Heap::push_status (const std::string uri_,
-		       const std::string status)
-{
-  for (std::list<gmref_ptr<List> >::iterator iter = lists.begin ();
-       iter != lists.end ();
-       ++iter)
-    (*iter)->push_status (uri_, status);
-}
+  {
+    xmlChar* str = xmlNodeGetContent (root);
+    if (str != NULL)
+      root_str = (const char*)str;
+  }
+  {
+    xmlChar* str = xmlNodeGetContent (user);
+    if (str != NULL)
+      user_str = (const char*)str;
+  }
+  {
+    xmlChar* str = xmlNodeGetContent (username);
+    if (str != NULL)
+      username_str = (const char*)str;
+  }
+  {
+    xmlChar* str = xmlNodeGetContent (password);
+    if (str != NULL)
+      password_str = (const char*)str;
+  }
+  {
+    xmlChar* str = xmlGetProp (node, BAD_CAST "writable");
+    if (str != NULL) {
 
-void
-RL::Heap::on_entry_added (gmref_ptr<Entry> entry)
-{
-  presentity_added.emit (*entry);
+      if (xmlStrEqual (str, BAD_CAST "1"))
+	writable = true;
+      xmlFree (str);
+    }
+  }
+
+  gmref_ptr<XCAP::Path> path(new XCAP::Path (root_str, "resource-lists",
+					     user_str));
+  path->set_credentials (username_str, password_str);
+  path = path->build_child ("resource-lists");
+  path = path->build_child ("list");
+
+  for (xmlNodePtr child = list->children;
+       child != NULL;
+       child = child->next)
+    if (child->type == XML_ELEMENT_NODE
+	&& child->name != NULL
+	&& xmlStrEqual (BAD_CAST ("entry"), child->name)) {
+
+      gmref_ptr<Presentity> presentity(new Presentity (services, path, child, writable));
+      std::list<sigc::connection> conns;
+      conns.push_back (presentity->updated.connect (sigc::bind (sigc::mem_fun (this, &RL::Heap::on_presentity_updated),presentity)));
+      conns.push_back (presentity->removed.connect (sigc::bind(sigc::mem_fun (this, &RL::Heap::on_presentity_removed),presentity)));
+      conns.push_back (presentity->questions.connect (questions.make_slot()));
+      presentities[presentity]=conns;
+      presentity_added.emit (*presentity);
+      continue;
+    }
 }
 
 void
-RL::Heap::on_entry_updated (gmref_ptr<Entry> entry)
+RL::Heap::push_presence (const std::string uri_,
+			 const std::string presence)
 {
-  presentity_updated.emit (*entry);
+  for (std::map<gmref_ptr<Presentity>,std::list<sigc::connection> >::iterator
+	 iter = presentities.begin ();
+       iter != presentities.end ();
+       ++iter) {
+
+    if (iter->first->get_uri () == uri_)
+      iter->first->set_presence (presence);
+  }
 }
 
 void
-RL::Heap::on_entry_removed (gmref_ptr<Entry> entry)
+RL::Heap::push_status (const std::string uri_,
+		       const std::string status)
 {
-  presentity_removed.emit (*entry);
+  for (std::map<gmref_ptr<Presentity>,std::list<sigc::connection> >::iterator
+	 iter = presentities.begin ();
+       iter != presentities.end ();
+       ++iter) {
+
+    if (iter->first->get_uri () == uri_)
+      iter->first->set_status (status);
+  }
 }
 
 void
@@ -376,26 +416,48 @@
   std::string username_str;
   std::string password_str;
   std::string user_str;
+  bool writable = false;
 
   {
     xmlChar* str = xmlNodeGetContent (root);
-    if (str != NULL)
+    if (str != NULL) {
+
       root_str = (const char*)str;
+      xmlFree (str);
+    }
   }
   {
     xmlChar* str = xmlNodeGetContent (user);
-    if (str != NULL)
+    if (str != NULL) {
+
       user_str = (const char*)str;
+      xmlFree (str);
+    }
   }
   {
     xmlChar* str = xmlNodeGetContent (username);
-    if (str != NULL)
+    if (str != NULL) {
+
       username_str = (const char*)str;
+      xmlFree (str);
+    }
   }
   {
     xmlChar* str = xmlNodeGetContent (password);
-    if (str != NULL)
+    if (str != NULL) {
+
       password_str = (const char*)str;
+      xmlFree (str);
+    }
+  }
+  {
+    xmlChar* str = xmlGetProp (node, BAD_CAST "writable");
+    if (str != NULL) {
+
+      if (xmlStrEqual (str, BAD_CAST "1"))
+	writable = true;
+      xmlFree (str);
+    }
   }
 
   request.title (_("Edit contact list properties"));
@@ -406,6 +468,7 @@
   request.text ("name", _("Contact list's name"), get_name ());
   request.text ("root", _("Document root"), root_str);
   request.text ("user", _("Identifier"), user_str);
+  request.boolean ("writable", _("Writable"), writable);
   request.text ("username", _("Server username"), username_str);
   request.private_text ("password", _("Server password"), password_str);
 
@@ -433,7 +496,12 @@
     std::string user_str = result.text ("user");
     std::string username_str = result.text ("username");
     std::string password_str = result.private_text ("password");
+    bool writable = result.boolean ("writable");
 
+    if (writable)
+      xmlSetProp (node, BAD_CAST "writable", BAD_CAST "1");
+    else
+      xmlSetProp (node, BAD_CAST "writable", BAD_CAST "0");
     robust_xmlNodeSetContent (node, &name, "name", name_str);
     robust_xmlNodeSetContent (node, &root, "root", root_str);
     robust_xmlNodeSetContent (node, &user, "user", user_str);
@@ -448,3 +516,15 @@
     std::cerr << "Invalid result form" << std::endl; // FIXME: do better
   }
 }
+
+void
+RL::Heap::on_presentity_updated (gmref_ptr<Presentity> presentity)
+{
+  presentity_updated.emit (*presentity);
+}
+
+void
+RL::Heap::on_presentity_removed (gmref_ptr<Presentity> presentity)
+{
+  presentity_removed.emit (*presentity);
+}

Modified: trunk/lib/engine/components/resource-list/rl-heap.h
==============================================================================
--- trunk/lib/engine/components/resource-list/rl-heap.h	(original)
+++ trunk/lib/engine/components/resource-list/rl-heap.h	Sat Oct 25 13:25:32 2008
@@ -40,7 +40,7 @@
 
 #include "heap.h"
 
-#include "rl-list.h"
+#include "rl-presentity.h"
 
 namespace RL {
 
@@ -48,7 +48,7 @@
   {
   public:
 
-    Heap (Ekiga::ServiceCore& core_,
+    Heap (Ekiga::ServiceCore& services_,
 	  xmlNodePtr node);
 
     /* name: the name of the Heap in the GUI
@@ -56,6 +56,7 @@
      * user: the user as XCAP user
      * username: the username on the HTTP server
      * password: the password on the HTTP server
+     * writable: whether we have write rights on the server
      *
      * Don't complain to me(Snark) it's complex : read RFC4825 and cry with me
      *
@@ -65,7 +66,8 @@
 	  const std::string root_,
 	  const std::string user_,
 	  const std::string username_,
-	  const std::string password_);
+	  const std::string password_,
+	  bool writable_);
 
     ~Heap ();
 
@@ -90,7 +92,7 @@
 
   private:
 
-    Ekiga::ServiceCore& core;
+    Ekiga::ServiceCore& services;
 
     xmlNodePtr node;
     xmlNodePtr name;
@@ -101,7 +103,7 @@
 
     xmlDocPtr doc;
 
-    std::list<gmref_ptr<List> > lists;
+    std::map<gmref_ptr<Presentity>, std::list<sigc::connection> > presentities;
 
     void refresh ();
 
@@ -109,14 +111,14 @@
 			       std::string doc);
 
     void parse_doc (std::string doc);
-
-    void on_entry_added (gmref_ptr<Entry> entry);
-    void on_entry_updated (gmref_ptr<Entry> entry);
-    void on_entry_removed (gmref_ptr<Entry> entry);
+    void parse_list (xmlNodePtr node);
 
     void edit ();
     void on_edit_form_submitted (bool submitted,
 				 Ekiga::Form& result);
+
+    void on_presentity_updated (gmref_ptr<Presentity> presentity);
+    void on_presentity_removed (gmref_ptr<Presentity> presentity);
   };
 };
 

Added: trunk/lib/engine/components/resource-list/rl-presentity.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/components/resource-list/rl-presentity.cpp	Sat Oct 25 13:25:32 2008
@@ -0,0 +1,368 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program is free software; you can  redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         rl-presentity.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Julien Puydt
+ *   copyright            : (c) 2008 by Julien Puydt
+ *   description          : implementation of a presentity in a resource-list
+ *
+ */
+
+#include <algorithm>
+#include <iostream>
+#include <set>
+
+#include "config.h"
+
+#include "form-request-simple.h"
+#include "robust-xml.h"
+#include "xcap-core.h"
+
+#include "rl-presentity.h"
+
+
+RL::Presentity::Presentity (Ekiga::ServiceCore &services_,
+			    gmref_ptr<XCAP::Path> path_,
+			    xmlNodePtr node_,
+			    bool writable_) :
+  services(services_), node(node_), writable(writable_), name_node(NULL),
+  presence("unknown"), status(""), avatar("")
+{
+  gmref_ptr<Ekiga::PresenceCore> presence_core(services.get ("presence-core"));
+  xmlChar *xml_str = NULL;
+  xmlNsPtr ns = xmlSearchNsByHref (node->doc, node,
+				   BAD_CAST "http://www.ekiga.org";);
+
+  if (ns == NULL) {
+
+    // FIXME: we should handle the case, even if it shouldn't happen
+  }
+
+  xml_str = xmlGetProp (node, BAD_CAST "uri");
+  if (xml_str != NULL) {
+
+    uri = (const char *)xml_str;
+    path = path_->build_child_with_attribute ("entry", "uri", uri);
+    xmlFree (xml_str);
+  } else {
+
+    // FIXME: we should handle the case, even if it shouldn't happen
+  
+  }
+
+  for (xmlNodePtr child = node->children ;
+       child != NULL ;
+       child = child->next) {
+
+    if (child->type == XML_ELEMENT_NODE
+        && child->name != NULL) {
+
+      if (xmlStrEqual (BAD_CAST ("display-name"), child->name)) {
+
+	name_node = child;
+	continue;
+      }
+      else if (xmlStrEqual (BAD_CAST ("group"), child->name)
+	       && child->ns == ns) {
+
+        xml_str = xmlNodeGetContent (child);
+	if (xml_str != NULL)
+	  group_nodes[(const char *)xml_str] = child;
+	else
+	  group_nodes[""] = child;
+        xmlFree (xml_str);
+	continue;
+      }
+    }
+  }
+
+  for (std::map<std::string, xmlNodePtr>::const_iterator iter
+	 = group_nodes.begin ();
+       iter != group_nodes.end ();
+       iter++)
+    groups.insert (iter->first);
+
+  presence_core->fetch_presence (uri);
+}
+
+RL::Presentity::~Presentity ()
+{
+}
+
+
+const std::string
+RL::Presentity::get_name () const
+{
+  std::string result;
+
+  if (name_node != NULL) {
+
+    xmlChar* str = xmlNodeGetContent (name_node);
+    if (str != NULL) {
+
+      result = ((const char*)str);
+      xmlFree (str);
+    }
+  } else {
+
+    result = _("Unnamed");
+  }
+
+  return result;
+}
+
+
+const std::string
+RL::Presentity::get_presence () const
+{
+  return presence;
+}
+
+
+const std::string
+RL::Presentity::get_status () const
+{
+  return status;
+}
+
+
+const std::string
+RL::Presentity::get_avatar () const
+{
+  return avatar;
+}
+
+
+const std::set<std::string>
+RL::Presentity::get_groups () const
+{
+  return groups;
+}
+
+
+const std::string
+RL::Presentity::get_uri () const
+{
+  return uri;
+}
+
+
+void
+RL::Presentity::set_presence (const std::string _presence)
+{
+  presence = _presence;
+  updated.emit ();
+}
+
+void
+RL::Presentity::set_status (const std::string _status)
+{
+  status = _status;
+  updated.emit ();
+}
+
+
+bool
+RL::Presentity::populate_menu (Ekiga::MenuBuilder &builder)
+{
+  bool populated = false;
+  gmref_ptr<Ekiga::PresenceCore> presence_core(services.get ("presence-core"));
+
+  populated = presence_core->populate_presentity_menu (*this, uri, builder);
+
+  if (writable) {
+
+    if (populated)
+      builder.add_separator ();
+
+    builder.add_action ("edit", _("_Edit"),
+			sigc::mem_fun (this, &RL::Presentity::edit_presentity));
+    builder.add_action ("remove", _("_Remove"),
+			sigc::mem_fun (this, &RL::Presentity::remove));
+  }
+
+  return true;
+}
+
+
+void
+RL::Presentity::edit_presentity ()
+{
+  Ekiga::FormRequestSimple request(sigc::mem_fun (this, &RL::Presentity::edit_presentity_form_submitted));
+
+   // FIXME: we should be able to know all groups in the heap
+  std::set<std::string> all_groups = groups;
+
+  request.title (_("Edit remote contact"));
+  request.instructions (_("Please fill in this form to change an existing "
+			  "contact on a remote server"));
+  request.text ("name", _("Name:"), get_name ());
+  request.text ("uri", _("Address:"), uri);
+
+  request.editable_set ("groups", _("Choose groups:"),
+			groups, all_groups);
+
+  if (!questions.handle_request (&request)) {
+
+    // FIXME: better error reporting
+#ifdef __GNUC__
+    std::cout << "Unhandled form request in "
+	      << __PRETTY_FUNCTION__ << std::endl;
+#endif
+  }
+}
+
+
+void
+RL::Presentity::edit_presentity_form_submitted (bool submitted,
+						Ekiga::Form &result)
+{
+  if (!submitted)
+    return;
+
+  try {
+
+    const std::string new_name = result.text ("name");
+    const std::string new_uri = result.text ("uri");
+    const std::set<std::string> new_groups = result.editable_set ("groups");
+    std::map<std::string, xmlNodePtr> future_group_nodes;
+    xmlNsPtr ns = xmlSearchNsByHref (node->doc, node,
+				     BAD_CAST "http://www.ekiga.org";);
+    bool reload = false;
+
+    robust_xmlNodeSetContent (node, &name_node, "name", new_name);
+
+    if (uri != new_uri) {
+
+      xmlSetProp (node, (const xmlChar*)"uri", (const xmlChar*)uri.c_str ());
+      gmref_ptr<Ekiga::PresenceCore> presence_core(services.get ("presence-core"));
+      presence_core->unfetch_presence (uri);
+      reload = true;
+    }
+
+    for (std::map<std::string, xmlNodePtr>::const_iterator iter
+	   = group_nodes.begin ();
+	 iter != group_nodes.end () ;
+	 iter++) {
+
+      if (new_groups.find (iter->first) == new_groups.end ()) {
+
+	xmlUnlinkNode (iter->second);
+	xmlFreeNode (iter->second);
+      }
+      else {
+	future_group_nodes[iter->first] = iter->second;
+      }
+    }
+
+    for (std::set<std::string>::const_iterator iter = new_groups.begin ();
+	 iter != new_groups.end ();
+	 iter++) {
+
+      if (std::find (groups.begin (), groups.end (), *iter) == groups.end ())
+	future_group_nodes[*iter] = xmlNewChild (node, ns,
+						 BAD_CAST "group",
+						 BAD_CAST robust_xmlEscape (node->doc, *iter).c_str ());
+    }
+
+    group_nodes = future_group_nodes;
+    groups = new_groups;
+
+    save (reload);
+  } catch (Ekiga::Form::not_found) {
+#ifdef __GNUC__
+    std::cerr << "Invalid form submitted to "
+	      << __PRETTY_FUNCTION__ << std::endl;
+#endif
+  }
+}
+
+void
+RL::Presentity::save (bool reload)
+{
+  xmlBufferPtr buffer = xmlBufferCreate ();
+  int result = xmlNodeDump (buffer, node->doc, node, 0, 0);
+
+  if (result >= 0) {
+
+    gmref_ptr<XCAP::Core> xcap(services.get ("xcap-core"));
+    xcap->write (path, "application/resource-lists+xml",
+		 (const char*)xmlBufferContent (buffer),
+		 sigc::bind (sigc::mem_fun (this,
+					    &RL::Presentity::save_result),
+			     reload));
+  }
+
+  xmlBufferFree (buffer);
+
+}
+
+void
+RL::Presentity::remove ()
+{
+  xmlUnlinkNode (node);
+  xmlFreeNode (node);
+  gmref_ptr<Ekiga::PresenceCore> presence_core(services.get ("presence-core"));
+
+  presence_core->unfetch_presence (uri);
+
+  gmref_ptr<XCAP::Core> xcap(services.get ("xcap-core"));
+  xcap->erase (path,
+	       sigc::mem_fun (this,
+			      &RL::Presentity::erase_result));
+}
+
+void
+RL::Presentity::save_result (std::string error,
+			     bool reload)
+{
+  if ( !error.empty ()) {
+
+    // FIXME: do better
+    std::cout << "XCAP error: " << error << std::endl;
+    trigger_reload.emit ();
+  } else {
+
+    if (reload)
+      trigger_reload.emit ();
+    else
+      updated.emit ();
+  }
+}
+
+void
+RL::Presentity::erase_result (std::string error)
+{
+  if ( !error.empty ()) {
+
+    // FIXME: do better
+    std::cout << "XCAP error: " << error << std::endl;
+  }
+
+  trigger_reload.emit ();
+}

Added: trunk/lib/engine/components/resource-list/rl-presentity.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/components/resource-list/rl-presentity.h	Sat Oct 25 13:25:32 2008
@@ -0,0 +1,117 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program is free software; you can  redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         rl-presentity.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Julien Puydt
+ *   copyright            : (c) 2008 by Julien Puydt
+ *   description          : declaration of a presentity in a resource-list
+ *
+ */
+
+
+
+#ifndef __RL_PRESENTITY_H__
+#define __RL_PRESENTITY_H__
+
+#include <libxml/tree.h>
+
+#include "form.h"
+#include "presence-core.h"
+#include "presentity.h"
+#include "xcap-path.h"
+
+namespace RL
+{
+  class Presentity:
+    public virtual GmRefCounted,
+    public Ekiga::Presentity
+  {
+  public:
+
+    Presentity (Ekiga::ServiceCore &_core,
+		gmref_ptr<XCAP::Path> path_,
+		xmlNodePtr _node,
+		bool writable_);
+
+    ~Presentity ();
+
+    const std::string get_name () const;
+
+    const std::string get_presence () const;
+
+    const std::string get_status () const;
+
+    const std::string get_avatar () const;
+
+    const std::set<std::string> get_groups () const;
+
+    const std::string get_uri () const;
+
+    void set_presence (const std::string _presence);
+
+    void set_status (const std::string _status);
+
+    bool populate_menu (Ekiga::MenuBuilder &);
+
+    sigc::signal<void> trigger_reload;
+
+  private:
+
+    void edit_presentity ();
+
+    void edit_presentity_form_submitted (bool submitted,
+					 Ekiga::Form &result);
+
+    void save (bool reload);
+
+    void remove ();
+
+    void save_result (std::string error,
+		      bool reload);
+
+    void erase_result (std::string error);
+
+    Ekiga::ServiceCore &services;
+
+    gmref_ptr<XCAP::Path> path;
+    xmlNodePtr node;
+    bool writable;
+
+    xmlNodePtr name_node;
+
+    std::string uri;
+    std::string presence;
+    std::string status;
+    std::string avatar;
+
+    std::map<std::string, xmlNodePtr> group_nodes;
+    std::set<std::string> groups;
+  };
+};
+
+#endif



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