ekiga r7221 - trunk/lib/engine/components/resource-list
- From: jpuydt svn gnome org
- To: svn-commits-list gnome org
- Subject: ekiga r7221 - trunk/lib/engine/components/resource-list
- Date: Wed, 15 Oct 2008 12:48:01 +0000 (UTC)
Author: jpuydt
Date: Wed Oct 15 12:48:01 2008
New Revision: 7221
URL: http://svn.gnome.org/viewvc/ekiga?rev=7221&view=rev
Log:
Reworked the resource-list code : does the same thing as before, but should be more extensible (entry-ref and external, for example)
Added:
trunk/lib/engine/components/resource-list/rl-entry-ref.cpp
trunk/lib/engine/components/resource-list/rl-entry-ref.h
- copied, changed from r7220, /trunk/lib/engine/components/resource-list/rl-presentity.h
trunk/lib/engine/components/resource-list/rl-entry.cpp
trunk/lib/engine/components/resource-list/rl-entry.h
- copied, changed from r7220, /trunk/lib/engine/components/resource-list/rl-presentity.h
trunk/lib/engine/components/resource-list/rl-list.cpp
trunk/lib/engine/components/resource-list/rl-list.h
- copied, changed from r7220, /trunk/lib/engine/components/resource-list/rl-heap.h
Removed:
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/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 Wed Oct 15 12:48:01 2008
@@ -6,6 +6,7 @@
INCLUDES = \
-I$(top_srcdir)/lib/gmconf \
+ -I$(top_srcdir)/lib/gmref \
-I$(top_srcdir)/lib/engine/framework \
-I$(top_srcdir)/lib/engine/presence/skel \
-I$(top_srcdir)/lib/engine/account/skel \
@@ -14,8 +15,12 @@
libgmresource_list_la_SOURCES = \
$(resource_list_dir)/resource-list-main.h \
$(resource_list_dir)/resource-list-main.cpp \
- $(resource_list_dir)/rl-presentity.h \
- $(resource_list_dir)/rl-presentity.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-heap.h \
$(resource_list_dir)/rl-heap.cpp \
$(resource_list_dir)/rl-cluster.h \
Added: trunk/lib/engine/components/resource-list/rl-entry-ref.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/components/resource-list/rl-entry-ref.cpp Wed Oct 15 12:48:01 2008
@@ -0,0 +1,152 @@
+
+/* 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-entry-ref.cpp - description
+ * ------------------------------------------
+ * begin : written in 2008 by Julien Puydt
+ * copyright : (c) 2008 by Julien Puydt
+ * description : resource-list entry-ref class
+ *
+ */
+
+#include "config.h"
+
+#include "rl-entry-ref.h"
+
+#include "presence-core.h"
+
+RL::EntryRef::EntryRef (Ekiga::ServiceCore& core_,
+ const std::string path_,
+ int pos,
+ const std::string group,
+ xmlNodePtr node_):
+ core(core_), path(path_), position(pos), doc(NULL), node(node_),
+ link_doc(NULL), link_node(NULL), name_node(NULL),
+ presence("unknown"), status(_("Click to fetch"))
+{
+ groups.insert (group);
+
+ for (xmlNodePtr child = node->children; child != NULL; child = child->next) {
+
+
+ if (child->type == XML_ELEMENT_NODE
+ && child->name != NULL
+ && xmlStrEqual (BAD_CAST "display-name", child->name)) {
+
+ name_node = child;
+ }
+ }
+}
+
+RL::EntryRef::~EntryRef ()
+{
+ if (doc != NULL)
+ xmlFreeDoc (doc);
+}
+
+bool
+RL::EntryRef::is_positional () const
+{
+ return true; // FIXME
+}
+
+const std::string
+RL::EntryRef::get_uri () const
+{
+ std::string result;
+ xmlChar* str = xmlGetProp (node, BAD_CAST "uri");
+
+ if (str != NULL) {
+
+ result = ((const char*)str);
+ xmlFree (str);
+ }
+
+ return result;
+}
+
+
+void
+RL::EntryRef::set_presence (const std::string presence_)
+{
+ presence = presence_;
+ updated.emit ();
+}
+
+void
+RL::EntryRef::set_status (const std::string status_)
+{
+ status = status_;
+ updated.emit ();
+}
+
+const std::string
+RL::EntryRef::get_name () const
+{
+ std::string result;
+
+ if (link_node != NULL) {
+
+ xmlChar* str = xmlNodeGetContent (node);
+
+ if (str != NULL) {
+
+ result = ((const char*)str);
+ xmlFree (str);
+ }
+ } else
+ result = _("Distant contact");
+
+ return result;
+}
+
+bool
+RL::EntryRef::populate_menu (Ekiga::MenuBuilder& builder)
+{
+ bool populated = false;
+ Ekiga::PresenceCore* presence_core
+ = dynamic_cast<Ekiga::PresenceCore*>(core.get ("presence-core"));
+ std::string uri(get_uri ());
+
+ builder.add_action ("refresh", _("_Refresh"),
+ sigc::mem_fun (this, &RL::EntryRef::refresh));
+
+ if ( !uri.empty ())
+ populated =
+ presence_core->populate_presentity_menu (*this, uri, builder)
+ || populated;
+
+ return populated;
+}
+
+void
+RL::EntryRef::refresh ()
+{
+ std::cout << "FIXME: should refresh on " << path << std::endl;
+}
Copied: trunk/lib/engine/components/resource-list/rl-entry-ref.h (from r7220, /trunk/lib/engine/components/resource-list/rl-presentity.h)
==============================================================================
--- /trunk/lib/engine/components/resource-list/rl-presentity.h (original)
+++ trunk/lib/engine/components/resource-list/rl-entry-ref.h Wed Oct 15 12:48:01 2008
@@ -1,4 +1,5 @@
+
/* Ekiga -- A VoIP and Video-Conferencing application
* Copyright (C) 2000-2008 Damien Sandras
*
@@ -27,36 +28,55 @@
/*
- * rl-presentity.h - description
+ * rl-entry-ref.h - description
* ------------------------------------------
* begin : written in 2008 by Julien Puydt
* copyright : (c) 2008 by Julien Puydt
- * description : resource-list presentity interface
+ * description : resource-list entry-ref class
*
*/
-#ifndef __RL_PRESENTITY_H__
-#define __RL_PRESENTITY_H__
+#ifndef __RL_ENTRY_REF_H__
+#define __RL_ENTRY_REF_H__
+
+#include "gmref.h"
#include "services.h"
#include "presentity.h"
+#include <libxml/tree.h>
+
namespace RL {
- class Presentity: public Ekiga::Presentity
+ class EntryRef:
+ public GmRefCounted,
+ public Ekiga::Presentity
{
public:
- Presentity (Ekiga::ServiceCore& core_,
- std::string name_,
- std::string uri_);
+ EntryRef (Ekiga::ServiceCore& core_,
+ const std::string path_,
+ int pos,
+ const std::string group,
+ xmlNodePtr node_);
+
+ ~EntryRef ();
+
+ /* the part of the interface which helps the list manage this element */
+
+ bool is_positional () const;
- ~Presentity ();
+ /* needed so presence can be pushed into this presentity */
+
+ const std::string get_uri () const;
+
+ void set_presence (const std::string presence_);
+
+ void set_status (const std::string status_);
- void add_group (std::string group);
+ /* Ekiga::Presentity interface */
- const std::string get_name () const
- { return name; }
+ const std::string get_name () const;
const std::string get_presence () const
{ return presence; }
@@ -72,21 +92,25 @@
bool populate_menu (Ekiga::MenuBuilder& builder);
- const std::string get_uri () const
- { return uri; }
+ private:
+ Ekiga::ServiceCore& core;
- void set_presence (const std::string presence_);
+ std::string path;
+ int position;
- void set_status (const std::string status_);
+ std::set<std::string> groups;
- private:
- Ekiga::ServiceCore& core;
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ xmlDocPtr link_doc;
+ xmlNodePtr link_node;
+ xmlNodePtr name_node;
- std::string name;
- std::string uri;
std::string presence;
std::string status;
- std::set<std::string> groups;
+
+ void refresh ();
};
};
Added: trunk/lib/engine/components/resource-list/rl-entry.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/components/resource-list/rl-entry.cpp Wed Oct 15 12:48:01 2008
@@ -0,0 +1,162 @@
+
+/* 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-entry.cpp - description
+ * ------------------------------------------
+ * begin : written in 2008 by Julien Puydt
+ * copyright : (c) 2008 by Julien Puydt
+ * description : resource-list entry class
+ *
+ */
+
+
+#include <libxml/debugXML.h>
+
+#include "config.h"
+
+#include "rl-entry.h"
+
+#include "presence-core.h"
+
+RL::Entry::Entry (Ekiga::ServiceCore& core_,
+ const std::string path_,
+ int pos,
+ const std::string group,
+ xmlNodePtr node_):
+ core(core_), path(path_), position(pos), doc(NULL),
+ node(node_), name_node(NULL),
+ presence("unknown"), status("")
+{
+ groups.insert (group);
+
+ refresh ();
+}
+
+RL::Entry::~Entry ()
+{
+ if (doc != NULL)
+ xmlFreeDoc (doc);
+}
+
+bool
+RL::Entry::is_positional () const
+{
+ return get_uri ().empty ();
+}
+
+const std::string
+RL::Entry::get_uri () const
+{
+ std::string result;
+ xmlChar* str = xmlGetProp (node, (const xmlChar*) "uri");
+
+ if (str != NULL) {
+
+ result = ((const char*)str);
+ xmlFree (str);
+ }
+
+ return result;
+}
+
+
+void
+RL::Entry::set_presence (const std::string presence_)
+{
+ presence = presence_;
+ updated.emit ();
+}
+
+void
+RL::Entry::set_status (const std::string status_)
+{
+ status = status_;
+ updated.emit ();
+}
+
+const std::string
+RL::Entry::get_name () const
+{
+ std::string result;
+ xmlChar* str = xmlNodeGetContent (name_node);
+
+ if (str != NULL) {
+
+ result = ((const char*)str);
+ xmlFree (str);
+ }
+
+ return result;
+}
+
+bool
+RL::Entry::populate_menu (Ekiga::MenuBuilder& builder)
+{
+ bool populated = false;
+ Ekiga::PresenceCore* presence_core
+ = dynamic_cast<Ekiga::PresenceCore*>(core.get ("presence-core"));
+ std::string uri(get_uri ());
+
+ builder.add_action ("refresh", _("_Refresh"),
+ sigc::mem_fun (this, &RL::Entry::refresh));
+
+ if ( !uri.empty ())
+ populated =
+ presence_core->populate_presentity_menu (*this, uri, builder)
+ || populated;
+
+ return populated;
+}
+
+void
+RL::Entry::refresh ()
+{
+ if (node != NULL)
+ parse ();
+ else {
+
+ /* FIXME: here we should fetch the document, then parse it
+ */
+ }
+}
+
+void
+RL::Entry::parse ()
+{
+ for (xmlNodePtr child = node->children; child != NULL; child = child->next) {
+
+
+ if (child->type == XML_ELEMENT_NODE
+ && child->name != NULL
+ && xmlStrEqual (BAD_CAST "display-name", child->name)) {
+
+ name_node = child;
+ }
+ }
+}
Copied: trunk/lib/engine/components/resource-list/rl-entry.h (from r7220, /trunk/lib/engine/components/resource-list/rl-presentity.h)
==============================================================================
--- /trunk/lib/engine/components/resource-list/rl-presentity.h (original)
+++ trunk/lib/engine/components/resource-list/rl-entry.h Wed Oct 15 12:48:01 2008
@@ -27,36 +27,55 @@
/*
- * rl-presentity.h - description
+ * rl-entry.h - description
* ------------------------------------------
* begin : written in 2008 by Julien Puydt
* copyright : (c) 2008 by Julien Puydt
- * description : resource-list presentity interface
+ * description : resource-list entry class
*
*/
-#ifndef __RL_PRESENTITY_H__
-#define __RL_PRESENTITY_H__
+#ifndef __RL_ENTRY_H__
+#define __RL_ENTRY_H__
+
+#include "gmref.h"
#include "services.h"
#include "presentity.h"
+#include <libxml/tree.h>
+
namespace RL {
- class Presentity: public Ekiga::Presentity
+ class Entry:
+ public GmRefCounted,
+ public Ekiga::Presentity
{
public:
- Presentity (Ekiga::ServiceCore& core_,
- std::string name_,
- std::string uri_);
+ Entry (Ekiga::ServiceCore& core_,
+ const std::string path_,
+ int pos,
+ const std::string group,
+ xmlNodePtr node_);
+
+ ~Entry ();
+
+ /* the part of the interface which helps the list manage this element */
+
+ bool is_positional () const;
- ~Presentity ();
+ /* needed so presence can be pushed into this presentity */
+
+ const std::string get_uri () const;
+
+ void set_presence (const std::string presence_);
+
+ void set_status (const std::string status_);
- void add_group (std::string group);
+ /* Ekiga::Presentity interface */
- const std::string get_name () const
- { return name; }
+ const std::string get_name () const;
const std::string get_presence () const
{ return presence; }
@@ -72,21 +91,23 @@
bool populate_menu (Ekiga::MenuBuilder& builder);
- const std::string get_uri () const
- { return uri; }
+ private:
+ Ekiga::ServiceCore& core;
- void set_presence (const std::string presence_);
+ std::string path;
+ int position;
- void set_status (const std::string status_);
+ std::set<std::string> groups;
- private:
- Ekiga::ServiceCore& core;
+ xmlDocPtr doc;
+ xmlNodePtr node;
+ xmlNodePtr name_node;
- std::string name;
- std::string uri;
std::string presence;
std::string status;
- std::set<std::string> groups;
+
+ void refresh ();
+ void parse ();
};
};
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 Wed Oct 15 12:48:01 2008
@@ -37,7 +37,7 @@
#include "config.h"
-#include <iostream>
+#include <glib.h>
#include "robust-xml.h"
@@ -46,7 +46,7 @@
RL::Heap::Heap (Ekiga::ServiceCore& core_,
xmlNodePtr node_):
core(core_), node(node_), uri(NULL),
- username(NULL), password(NULL), name(NULL)
+ username(NULL), password(NULL), name(NULL), doc(NULL)
{
for (xmlNodePtr child = node->children; child != NULL; child = child->next) {
@@ -75,7 +75,7 @@
if (password == NULL)
password = xmlNewChild (node, NULL, BAD_CAST "password", BAD_CAST "");
- update ();
+ refresh ();
}
RL::Heap::Heap (Ekiga::ServiceCore& core_,
@@ -108,11 +108,13 @@
BAD_CAST "name",
BAD_CAST robust_xmlEscape (node->doc,
_("Unnamed")).c_str ());
- update ();
+ refresh ();
}
RL::Heap::~Heap ()
{
+ if (doc != NULL)
+ xmlFreeDoc (doc);
}
const std::string
@@ -121,7 +123,7 @@
std::string result;
xmlChar* str = xmlNodeGetContent (name);
if (str != NULL)
- result = (const gchar*)str;
+ result = (const char*)str;
else
result = _("Unnamed");
@@ -136,7 +138,7 @@
std::string result;
xmlChar* str = xmlNodeGetContent (uri);
if (str != NULL)
- result = (const gchar*)str;
+ result = (const char*)str;
else
result = "";
@@ -145,6 +147,16 @@
return result;
}
+void
+RL::Heap::visit_presentities (sigc::slot<bool, Ekiga::Presentity&> visitor)
+{
+ bool go_on = true;
+
+ for (std::list<gmref_ptr<List> >::iterator iter = lists.begin ();
+ go_on && iter != lists.end ();
+ ++iter)
+ go_on = (*iter)->visit_presentities (visitor);
+}
bool
RL::Heap::populate_menu (Ekiga::MenuBuilder& /*builder*/)
@@ -166,27 +178,38 @@
}
void
-RL::Heap::update ()
+RL::Heap::refresh ()
{
XCAP::Core* xcap
= dynamic_cast<XCAP::Core*>(core.get ("xcap-core"));
+
+ for (std::list<gmref_ptr<List> >::iterator iter = lists.begin ();
+ iter != lists.end ();
+ ++iter)
+ (*iter)->flush ();
+ lists.clear ();
+
+ if (doc)
+ xmlFreeDoc (doc);
+ doc = NULL;
+
xcap->read (get_uri (),
sigc::mem_fun (this, &RL::Heap::on_document_received));
}
void
RL::Heap::on_document_received (XCAP::Core::ResultType result,
- std::string doc)
+ std::string value)
{
switch (result) {
case XCAP::Core::SUCCESS:
- parse_doc (doc);
+ parse_doc (value);
break;
case XCAP::Core::ERROR:
- std::cout << "Error: " << doc << std::endl;
+ // FIXME: do something
break;
default:
// shouldn't happen
@@ -197,136 +220,69 @@
void
RL::Heap::parse_doc (std::string raw)
{
- xmlDocPtr doc = xmlRecoverMemory (raw.c_str (), raw.length ());
+ doc = xmlRecoverMemory (raw.c_str (), raw.length ());
+
xmlNodePtr root = xmlDocGetRootElement (doc);
if (root == NULL) {
// FIXME: warn the user somehow?
+ xmlFreeDoc (doc);
+ doc = NULL;
} else {
+ int pos = 1;
for (xmlNodePtr child = root->children; child != NULL; child = child->next)
if (child->type == XML_ELEMENT_NODE
&& child->name != NULL
&& xmlStrEqual (BAD_CAST ("list"), child->name)) {
- parse_list (child, NULL);
+ gmref_ptr<List> list(new List (core, get_uri (), 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));
+ list->publish ();
+ lists.push_back (list);
+ pos++;
+ continue;
}
}
- xmlFreeDoc (doc);
}
void
-RL::Heap::parse_list (xmlNodePtr list,
- const gchar* base_name)
+RL::Heap::push_presence (const std::string uri_,
+ const std::string presence)
{
- gchar* display_name = NULL;
- gchar* unnamed = NULL;
-
- if (base_name == NULL)
- unnamed = g_strdup (_("Unnamed"));
- else
- unnamed = g_strdup_printf ("%s / %s",
- base_name, _("Unnamed"));
-
- for (xmlNodePtr child = list->children;
- child != NULL;
- child = child->next) {
-
- if (child->type == XML_ELEMENT_NODE
- && child->name != NULL) {
-
- if (xmlStrEqual (BAD_CAST ("display-name"), child->name)) {
-
- xmlChar* xml_str = xmlNodeGetContent (child);
- if (xml_str != NULL && display_name == NULL) {
-
- if (base_name == NULL)
- display_name = g_strdup ((const gchar*)xml_str);
- else
- display_name = g_strdup_printf ("%s / %s",
- base_name, (const gchar*)xml_str);
- }
- xmlFree (xml_str);
- }
-
- if (xmlStrEqual (BAD_CAST ("list"), child->name)) {
-
- if (display_name != NULL)
- parse_list (child, display_name);
- else
- parse_list (child, unnamed);
- }
- if (xmlStrEqual (BAD_CAST ("entry"), child->name)) {
-
- if (display_name != NULL)
- parse_entry (child, display_name);
- else
- parse_entry (child, unnamed);
- }
- }
- }
-
- g_free (unnamed);
- g_free (display_name);
+ for (std::list<gmref_ptr<List> >::iterator iter = lists.begin ();
+ iter != lists.end ();
+ ++iter)
+ (*iter)->push_presence (uri_, presence);
}
void
-RL::Heap::parse_entry (xmlNodePtr entry,
- const gchar* group_name)
+RL::Heap::push_status (const std::string uri_,
+ const std::string status)
{
- gchar* entry_uri = NULL;
- std::string display_name = _("Unnamed");
- Presentity* presentity = NULL;
-
- {
- xmlChar* str = xmlGetProp (entry, BAD_CAST "uri");
- if (str != NULL) {
-
- entry_uri = g_strdup ((const gchar*)str);
- xmlFree (str);
- }
- }
-
- for (xmlNodePtr child = entry->children; child != NULL; child = child->next)
- if (child->type == XML_ELEMENT_NODE
- && child->name != NULL
- && xmlStrEqual (BAD_CAST ("display-name"), child->name)) {
-
- xmlChar* xml_str = xmlNodeGetContent (child);
- if (xml_str != NULL)
- display_name = (const gchar*)xml_str;
- xmlFree (xml_str);
- }
-
- if (entry_uri != NULL) {
+ for (std::list<gmref_ptr<List> >::iterator iter = lists.begin ();
+ iter != lists.end ();
+ ++iter)
+ (*iter)->push_status (uri_, status);
+}
- presentity = new Presentity (core, display_name, entry_uri);
- if (group_name != NULL)
- presentity->add_group (group_name);
- add_presentity (*presentity);
- g_free (entry_uri);
- }
+void
+RL::Heap::on_entry_added (gmref_ptr<Entry> entry)
+{
+ presentity_added.emit (*entry);
}
void
-RL::Heap::push_presence (const std::string uri_,
- const std::string presence)
+RL::Heap::on_entry_updated (gmref_ptr<Entry> entry)
{
- for (iterator iter = begin ();
- iter != end ();
- ++iter)
- if (iter->get_uri () == uri_)
- iter->set_presence (presence);
+ presentity_updated.emit (*entry);
}
void
-RL::Heap::push_status (const std::string uri_,
- const std::string status)
+RL::Heap::on_entry_removed (gmref_ptr<Entry> entry)
{
- for (iterator iter = begin ();
- iter != end ();
- ++iter)
- if (iter->get_uri () == uri_)
- iter->set_status (status);
+ presentity_removed.emit (*entry);
}
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 Wed Oct 15 12:48:01 2008
@@ -38,17 +38,18 @@
#ifndef __RL_HEAP_H__
#define __RL_HEAP_H__
-#include "rl-presentity.h"
+#include "gmref.h"
-#include "heap-impl.h"
+#include "heap.h"
#include "xcap.h"
-#include <glib.h>
#include <libxml/tree.h>
+#include "rl-list.h"
+
namespace RL {
- class Heap: public Ekiga::HeapImpl<Presentity>
+ class Heap: public Ekiga::Heap
{
public:
@@ -65,6 +66,8 @@
const std::string get_name () const;
+ void visit_presentities (sigc::slot<bool, Ekiga::Presentity&> visitor);
+
bool populate_menu (Ekiga::MenuBuilder& builder);
bool populate_menu_for_group (std::string group,
@@ -90,20 +93,22 @@
xmlNodePtr password;
xmlNodePtr name;
+ xmlDocPtr doc;
+
+ std::list<gmref_ptr<List> > lists;
+
const std::string get_uri () const;
- void update ();
+ void refresh ();
void on_document_received (XCAP::Core::ResultType result,
std::string doc);
void parse_doc (std::string doc);
- void parse_list (xmlNodePtr list,
- const gchar* base_name);
-
- void parse_entry (xmlNodePtr entry,
- const gchar* group_name);
+ void on_entry_added (gmref_ptr<Entry> entry);
+ void on_entry_updated (gmref_ptr<Entry> entry);
+ void on_entry_removed (gmref_ptr<Entry> entry);
};
};
Added: trunk/lib/engine/components/resource-list/rl-list.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/components/resource-list/rl-list.cpp Wed Oct 15 12:48:01 2008
@@ -0,0 +1,434 @@
+
+/* 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-list.cpp - description
+ * ------------------------------------------
+ * begin : written in 2008 by Julien Puydt
+ * copyright : (c) 2008 by Julien Puydt
+ * description : resource-list list class
+ *
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <iostream>
+
+#include "rl-list.h"
+
+class RL::ListImpl
+{
+public: // no need to make anything private
+
+ ListImpl (Ekiga::ServiceCore& core_,
+ const std::string path_,
+ int pos,
+ const std::string group_,
+ xmlNodePtr node_);
+
+ ~ListImpl ();
+
+ bool is_positional () const;
+
+ bool has_name (const std::string name) const;
+
+ void push_presence (const std::string uri_,
+ const std::string presence);
+
+ void push_status (const std::string uri_,
+ const std::string status);
+
+ void publish ();
+
+ std::string compute_path () const;
+
+ void flush ();
+
+ void refresh ();
+
+ void parse ();
+
+ /* data for itself */
+
+ Ekiga::ServiceCore& core;
+
+ std::string path;
+ int position;
+
+ std::string group;
+
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ xmlNodePtr name_node;
+ std::string position_name;
+ std::string display_name;
+
+ /* make the world know what we have */
+ bool visit_presentities (sigc::slot<bool, Ekiga::Presentity&> visitor);
+
+ sigc::signal<void, gmref_ptr<Entry> > entry_added;
+ sigc::signal<void, gmref_ptr<Entry> > entry_updated;
+ sigc::signal<void, gmref_ptr<Entry> > entry_removed;
+
+
+ /* data for its children */
+ typedef enum { LIST, ENTRY } ChildType;
+
+ std::list<ChildType> ordering;
+ std::list<gmref_ptr<List> > lists;
+ std::list<std::pair<gmref_ptr<Entry>, std::list<sigc::connection> > > entries;
+};
+
+
+/* implementation of the List class */
+
+RL::List::List (Ekiga::ServiceCore& core_,
+ const std::string path_,
+ int pos,
+ const std::string group_,
+ xmlNodePtr node_)
+{
+ impl = new ListImpl (core_, path_, pos, group_, node_);
+ impl->entry_added.connect (entry_added.make_slot ());
+ impl->entry_updated.connect (entry_updated.make_slot ());
+ impl->entry_removed.connect (entry_removed.make_slot ());
+}
+
+RL::List::~List ()
+{
+ delete impl;
+}
+
+void
+RL::List::flush ()
+{
+ return impl->flush ();
+}
+
+void
+RL::List::publish ()
+{
+ return impl->publish ();
+}
+
+bool
+RL::List::is_positional () const
+{
+ return impl->is_positional ();
+}
+
+bool
+RL::List::has_name (const std::string name) const
+{
+ return impl->has_name (name);
+}
+
+void
+RL::List::push_presence (const std::string uri_,
+ const std::string presence)
+{
+ impl->push_presence (uri_, presence);
+}
+
+void
+RL::List::push_status (const std::string uri_,
+ const std::string status)
+{
+ impl->push_status (uri_, status);
+}
+
+bool
+RL::List::visit_presentities (sigc::slot<bool, Ekiga::Presentity&> visitor)
+{
+ return impl->visit_presentities (visitor);
+}
+
+/* implementation of the ListImpl class */
+
+RL::ListImpl::ListImpl (Ekiga::ServiceCore& core_,
+ const std::string path_,
+ int pos,
+ const std::string group_,
+ xmlNodePtr node_):
+ core(core_), path(path_), position(pos), group(group_), doc(NULL), node(node_)
+{
+ {
+ gchar* raw = NULL;
+
+ if ( !group_.empty ()) {
+
+ raw = g_strdup_printf (_("%s / List #%d"),
+ group_.c_str (), position);
+ } else {
+
+ raw = g_strdup_printf (_("List #%d"), position);
+ }
+ position_name = raw;
+ g_free (raw);
+
+ }
+
+ display_name = position_name; // refresh will set better
+
+ refresh ();
+}
+
+RL::ListImpl::~ListImpl ()
+{
+ if (doc != NULL)
+ xmlFreeDoc (doc);
+}
+
+bool
+RL::ListImpl::is_positional () const
+{
+ bool result = true;
+ xmlChar* str = xmlGetProp (node, BAD_CAST "name");
+
+ if (str != NULL) {
+
+ result = false;
+ xmlFree (str);
+ }
+
+ return result;
+}
+
+bool
+RL::ListImpl::has_name (const std::string name) const
+{
+ return (name == position_name) || (name == display_name);
+}
+
+void
+RL::ListImpl::flush ()
+{
+ ordering.clear ();
+
+ for (std::list<gmref_ptr<List> >::iterator iter = lists.begin ();
+ iter != lists.end ();
+ ++iter)
+ (*iter)->flush ();
+ lists.clear ();
+
+ for (std::list<std::pair<gmref_ptr<Entry>, std::list<sigc::connection> > >::iterator iter = entries.begin ();
+ iter != entries.end ();
+ ++iter) {
+
+ iter->first->removed.emit ();
+ for (std::list<sigc::connection>::iterator conn_iter
+ = iter->second.begin ();
+ conn_iter != iter->second.end ();
+ ++conn_iter)
+ conn_iter->disconnect ();
+ }
+ entries.clear ();
+}
+
+void
+RL::ListImpl::publish ()
+{
+ std::list<gmref_ptr<List> >::const_iterator list_iter = lists.begin ();
+ std::list<std::pair<gmref_ptr<Entry>, std::list<sigc::connection> > >::const_iterator entry_iter = entries.begin ();
+
+ for (std::list<ChildType>::const_iterator iter = ordering.begin ();
+ iter != ordering.end ();
+ ++iter) {
+
+ switch (*iter) {
+
+ case LIST:
+ (*list_iter)->publish ();
+ ++list_iter;
+ break;
+
+ case ENTRY:
+ entry_added.emit (entry_iter->first);
+ ++entry_iter;
+ break;
+
+ default:
+ break;// nothing
+ }
+ }
+}
+
+void
+RL::ListImpl::refresh ()
+{
+ flush ();
+
+ if (node)
+ parse ();
+ else {
+
+ /* FIXME:
+ * - fetch the document
+ * - call parse
+ */
+ }
+}
+
+void
+RL::ListImpl::parse ()
+{
+ std::string my_path = compute_path ();
+ int list_pos = 1;
+ int entry_pos = 1;
+
+ for (xmlNodePtr child = node->children; child != NULL; child = child->next) {
+
+
+ if (child->type == XML_ELEMENT_NODE
+ && child->name != NULL
+ && xmlStrEqual (BAD_CAST "display-name", child->name)) {
+
+ xmlChar* str = xmlNodeGetContent (child);
+ name_node = child;
+ if (str != NULL) {
+
+ if ( !group.empty ())
+ display_name = group + " / " + (const char*) str;
+ else
+ display_name = (const char*) str;
+ xmlFree (str);
+ }
+ continue;
+ }
+
+ if (child->type == XML_ELEMENT_NODE
+ && child->name != NULL
+ && xmlStrEqual (BAD_CAST "list", child->name)) {
+
+ gmref_ptr<List> list = new List (core, my_path,
+ list_pos, display_name, child);
+ list->entry_added.connect (entry_added.make_slot ());
+ lists.push_back (list);
+ ordering.push_back (LIST);
+ list_pos++;
+ continue;
+ }
+
+ if (child->type == XML_ELEMENT_NODE
+ && child->name != NULL
+ && xmlStrEqual (BAD_CAST "entry", child->name)) {
+
+ gmref_ptr<Entry> entry = new Entry (core, my_path,
+ entry_pos, display_name, child);
+ std::list<sigc::connection> conns;
+ conns.push_back (entry->updated.connect (sigc::bind (entry_updated.make_slot (), entry)));
+ conns.push_back (entry->removed.connect (sigc::bind (entry_removed.make_slot (), entry)));
+ entries.push_back (std::pair<gmref_ptr<Entry>, std::list<sigc::connection> > (entry, conns));
+ ordering.push_back (ENTRY);
+ entry_pos++;
+ continue;
+ }
+ }
+}
+
+std::string
+RL::ListImpl::compute_path () const
+{
+ std::string result;
+ gchar* raw = NULL;
+ xmlChar* str = xmlGetProp (node, BAD_CAST "name");
+
+ if (str != NULL) {
+
+ raw = g_strdup_printf ("%s/list[ name=\"%s\"]",
+ path.c_str (), str);
+ xmlFree (str);
+ } else {
+
+ raw = g_strdup_printf ("%s/list[%d]", path.c_str (), position);
+ }
+
+ result = raw;
+
+ g_free (raw);
+
+ return result;
+}
+
+void
+RL::ListImpl::push_presence (const std::string uri_,
+ const std::string presence)
+{
+ for (std::list<gmref_ptr<List> >::const_iterator iter = lists.begin ();
+ iter != lists.end ();
+ ++iter)
+ (*iter)->push_presence (uri_, presence);
+
+ for (std::list<std::pair<gmref_ptr<Entry>, std::list<sigc::connection> > >::const_iterator iter = entries.begin ();
+ iter != entries.end ();
+ ++iter) {
+
+ if (iter->first->get_uri () == uri_)
+ iter->first->set_presence (presence);
+ }
+}
+
+void
+RL::ListImpl::push_status (const std::string uri_,
+ const std::string status)
+{
+ for (std::list<gmref_ptr<List> >::const_iterator iter = lists.begin ();
+ iter != lists.end ();
+ ++iter)
+ (*iter)->push_status (uri_, status);
+
+ for (std::list<std::pair<gmref_ptr<Entry>, std::list<sigc::connection> > >::const_iterator iter = entries.begin ();
+ iter != entries.end ();
+ ++iter) {
+
+ if (iter->first->get_uri () == uri_)
+ iter->first->set_status (status);
+ }
+}
+
+bool
+RL::ListImpl::visit_presentities (sigc::slot<bool, Ekiga::Presentity&> visitor)
+{
+ bool go_on = true;
+
+ for (std::list<gmref_ptr<List> >::const_iterator iter = lists.begin ();
+ go_on && iter != lists.end ();
+ ++iter)
+ go_on = (*iter)->visit_presentities (visitor);
+
+ for (std::list<std::pair<gmref_ptr<Entry>, std::list<sigc::connection> > >::const_iterator iter = entries.begin ();
+ go_on && iter != entries.end ();
+ ++iter) {
+
+ go_on = visitor (*(iter->first));
+ }
+
+ return go_on;
+}
Copied: trunk/lib/engine/components/resource-list/rl-list.h (from r7220, /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-list.h Wed Oct 15 12:48:01 2008
@@ -1,4 +1,5 @@
+
/* Ekiga -- A VoIP and Video-Conferencing application
* Copyright (C) 2000-2008 Damien Sandras
*
@@ -27,83 +28,76 @@
/*
- * rl-heap.h - description
+ * rl-list.h - description
* ------------------------------------------
* begin : written in 2008 by Julien Puydt
* copyright : (c) 2008 by Julien Puydt
- * description : resource-list heap declaration
+ * description : resource-list list class
*
*/
-#ifndef __RL_HEAP_H__
-#define __RL_HEAP_H__
+#ifndef __RL_LIST_H__
+#define __RL_LIST_H__
-#include "rl-presentity.h"
+#include "gmref.h"
-#include "heap-impl.h"
-#include "xcap.h"
+#include "services.h"
-#include <glib.h>
#include <libxml/tree.h>
-namespace RL {
+#include "rl-entry.h"
+
+namespace RL
+{
+ class ListImpl; // pimpling : both it and external need to know each other
- class Heap: public Ekiga::HeapImpl<Presentity>
+ class List: public GmRefCounted
{
public:
- Heap (Ekiga::ServiceCore& core_,
- xmlNodePtr node);
+ List (Ekiga::ServiceCore& core_,
+ const std::string path_,
+ int pos,
+ const std::string group_,
+ xmlNodePtr node_);
- Heap (Ekiga::ServiceCore& core_,
- const std::string name_,
- const std::string uri_,
- const std::string username_,
- const std::string password_);
+ ~List ();
- ~Heap ();
- const std::string get_name () const;
+ /* the part of the interface which helps the list manage this element */
- bool populate_menu (Ekiga::MenuBuilder& builder);
+ bool is_positional () const;
- bool populate_menu_for_group (std::string group,
- Ekiga::MenuBuilder& builder);
+ bool has_name (const std::string name) const;
- xmlNodePtr get_node () const;
+ /* we need to push presence&status down */
- void push_presence (const std::string uri,
+ void push_presence (const std::string uri_,
const std::string presence);
- void push_status (const std::string uri,
+ void push_status (const std::string uri_,
const std::string status);
- sigc::signal<void> trigger_saving;
-
- private:
-
- Ekiga::ServiceCore& core;
+ /* make the world know what we have */
+ bool visit_presentities (sigc::slot<bool, Ekiga::Presentity&> visitor);
- xmlNodePtr node;
- xmlNodePtr uri;
- xmlNodePtr username;
- xmlNodePtr password;
- xmlNodePtr name;
+ sigc::signal<void, gmref_ptr<Entry> > entry_added;
+ sigc::signal<void, gmref_ptr<Entry> > entry_updated;
+ sigc::signal<void, gmref_ptr<Entry> > entry_removed;
+
+ /* this method orders the list to get rid of all its children */
+ void flush ();
+
+ /* this method makes the list publish what it has
+ * (it needs a method to be done, because we fetch on creation,
+ * which means the owner may not have had the time to connect to
+ * our signals yet)
+ */
+ void publish ();
- const std::string get_uri () const;
-
- void update ();
-
- void on_document_received (XCAP::Core::ResultType result,
- std::string doc);
-
- void parse_doc (std::string doc);
-
- void parse_list (xmlNodePtr list,
- const gchar* base_name);
+ private:
- void parse_entry (xmlNodePtr entry,
- const gchar* group_name);
+ ListImpl *impl;
};
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]