Code

make subtree monitoring part of XML::Node's interface
authormental <mental@users.sourceforge.net>
Wed, 4 Jul 2007 23:27:58 +0000 (23:27 +0000)
committermental <mental@users.sourceforge.net>
Wed, 4 Jul 2007 23:27:58 +0000 (23:27 +0000)
src/xml/node.h
src/xml/simple-node.cpp
src/xml/simple-node.h
src/xml/subtree.cpp
src/xml/subtree.h

index 0b22b169ed5cb9bb888631577dc0a5119eb929db..997f3ccda563d80029282e11ce023c4a19ca319d 100644 (file)
@@ -97,10 +97,14 @@ public:
     virtual void removeObserver(NodeObserver &observer)=0;
     virtual void removeListenerByData(void *data)=0;
 
+    virtual void addSubtreeObserver(NodeObserver &observer)=0;
+    virtual void removeSubtreeObserver(NodeObserver &observer)=0;
+
 protected:
     Node(Node const &) : Anchored() {}
 
 public: // ideally these should be protected too somehow...
+    virtual NodeObserver &_subtreeObservers()=0;
     virtual void _setParent(Node *parent)=0;
     virtual void _setNext(Node *next)=0;
     virtual void _bindDocument(Document &document)=0;
index c8b0828c45d1e5c2a64fe2e48ce2d387cce8d3e8..554752941fbca4c34fc735a66cfb54a2996a02ea 100644 (file)
@@ -165,6 +165,8 @@ SimpleNode::SimpleNode(int code)
     this->_document = NULL;
     this->_parent = this->_next = NULL;
     this->_first_child = this->_last_child = NULL;
+
+    _observers.add(_subtree_observers);
 }
 
 SimpleNode::SimpleNode(SimpleNode const &node)
@@ -199,6 +201,8 @@ SimpleNode::SimpleNode(SimpleNode const &node)
     {
         _attributes = cons(*iter, _attributes);
     }
+
+    _observers.add(_subtree_observers);
 }
 
 gchar const *SimpleNode::name() const {
@@ -267,6 +271,16 @@ bool SimpleNode::matchAttributeName(gchar const *partial_name) const {
     return false;
 }
 
+void SimpleNode::_setParent(Node *parent) {
+   if (_parent) {
+        _subtree_observers.remove(_parent->_subtreeObservers());
+    }
+    _parent = parent;
+    if (parent) {
+        _subtree_observers.add(parent->_subtreeObservers());
+    }
+}
+
 void SimpleNode::setContent(gchar const *content) {
     ptr_shared<char> old_content=_content;
     ptr_shared<char> new_content = ( content ? share_string(content) : ptr_shared<char>() );
index c843dadc5c87eb126ef7e601e288a0c2fa5758c2..b4439e289bfcf5b6fdeec881be68cb1ad3a176c0 100644 (file)
@@ -103,6 +103,13 @@ public:
         _observers.remove(observer);
     }
 
+    void addSubtreeObserver(NodeObserver &observer) {
+        _subtree_observers.add(observer);
+    }
+    void removeSubtreeObserver(NodeObserver &observer) {
+        _subtree_observers.remove(observer);
+    }
+
 protected:
     SimpleNode(int code);
     SimpleNode(SimpleNode const &repr);
@@ -110,7 +117,8 @@ protected:
     virtual SimpleNode *_duplicate(Document *doc) const=0;
 
 public: // ideally these should be protected somehow...
-    void _setParent(Node *parent) { _parent = parent; }
+    NodeObserver &_subtreeObservers() { return _subtree_observers; }
+    void _setParent(Node *parent);
     void _setNext(Node *next) { _next = next; }
     void _bindDocument(Document &document);
 
@@ -140,6 +148,7 @@ private:
     Node *_last_child;
 
     CompositeNodeObserver _observers;
+    CompositeNodeObserver _subtree_observers;
 };
 
 }
index f19bf055afb401db67e85d3248ec6888f4037cae..c608efd64e49408d74671b77e68c5a570b625d2e 100644 (file)
 namespace Inkscape {
 namespace XML {
 
-namespace {
-
-void recursively(void (Node::*m)(NodeObserver &observer),
-                 Node &node, NodeObserver &observer)
-{
-    (node.*m)(observer);
-    for ( NodeSiblingIterator iter = node.firstChild() ; iter ; ++iter ) {
-        recursively(m, *iter, observer);
-    }
+Subtree::Subtree(Node &root) : _root(root) {
+    _root.addSubtreeObserver(_observers);
 }
 
+Subtree::~Subtree() {
+    _root.removeSubtreeObserver(_observers);
 }
 
-Subtree::Subtree(Node &root) : _root(root) {
-    recursively(&Node::addObserver, _root, *this);
+namespace {
+
+void synthesize_events_recursive(Node &node, NodeObserver &observer) {
+    node.synthesizeEvents(observer);
+    for ( NodeSiblingIterator iter = node.firstChild() ; iter ; ++iter ) {
+        synthesize_events_recursive(*iter, observer);
+    }
 }
 
-Subtree::~Subtree() {
-    recursively(&Node::removeObserver, _root, *this);
 }
 
 void Subtree::synthesizeEvents(NodeObserver &observer) {
-    recursively(&Node::synthesizeEvents, _root, *this);
+    synthesize_events_recursive(_root, observer);
 }
 
 void Subtree::addObserver(NodeObserver &observer) {
@@ -52,36 +50,6 @@ void Subtree::removeObserver(NodeObserver &observer) {
     _observers.remove(observer); 
 }
 
-void Subtree::notifyChildAdded(Node &node, Node &child, Node *prev) {
-    recursively(&Node::addObserver, child, *this);
-    _observers.notifyChildAdded(node, child, prev);
-}
-
-void Subtree::notifyChildRemoved(Node &node, Node &child, Node *prev) {
-    recursively(&Node::removeObserver, child, *this);
-    _observers.notifyChildRemoved(node, child, prev);
-}
-
-void Subtree::notifyChildOrderChanged(Node &node, Node &child,
-                                      Node *old_prev, Node *new_prev)
-{
-    _observers.notifyChildOrderChanged(node, child, old_prev, new_prev);
-}
-
-void Subtree::notifyContentChanged(Node &node,
-                                   Util::ptr_shared<char> old_content,
-                                   Util::ptr_shared<char> new_content)
-{
-    _observers.notifyContentChanged(node, old_content, new_content);
-}
-
-void Subtree::notifyAttributeChanged(Node &node, GQuark name,
-                                     Util::ptr_shared<char> old_value,
-                                     Util::ptr_shared<char> new_value)
-{
-    _observers.notifyAttributeChanged(node, name, old_value, new_value);
-}
-
 }
 }
 
index a70598fca6cc07343920c29a8da1c3774133614f..9e2512e83786a294cb2e47171d0fcc171047bbfd 100644 (file)
@@ -24,9 +24,7 @@ namespace XML {
 
 class Node;
 
-class Subtree : public GC::Managed<GC::SCANNED, GC::MANUAL>,
-                private NodeObserver
-{
+class Subtree : public GC::Managed<GC::SCANNED, GC::MANUAL> {
 public:
     Subtree(Node &root);
     ~Subtree();
@@ -36,21 +34,6 @@ public:
     void removeObserver(NodeObserver &observer);
 
 private:
-    void notifyChildAdded(Node &node, Node &child, Node *prev);
-
-    void notifyChildRemoved(Node &node, Node &child, Node *prev);
-
-    void notifyChildOrderChanged(Node &node, Node &child,
-                                 Node *old_prev, Node *new_prev);
-
-    void notifyContentChanged(Node &node,
-                              Util::ptr_shared<char> old_content,
-                              Util::ptr_shared<char> new_content);
-
-    void notifyAttributeChanged(Node &node, GQuark name,
-                                Util::ptr_shared<char> old_value,
-                                Util::ptr_shared<char> new_value);
-
     Node &_root;
     CompositeNodeObserver _observers;
 };