Code

whiteboard working prototype
authordaleharvey <daleharvey@users.sourceforge.net>
Mon, 4 Sep 2006 13:08:27 +0000 (13:08 +0000)
committerdaleharvey <daleharvey@users.sourceforge.net>
Mon, 4 Sep 2006 13:08:27 +0000 (13:08 +0000)
src/jabber_whiteboard/defines.cpp
src/jabber_whiteboard/defines.h
src/jabber_whiteboard/inkboard-document.cpp
src/jabber_whiteboard/inkboard-document.h
src/jabber_whiteboard/inkboard-node.cpp
src/jabber_whiteboard/inkboard-session.cpp
src/jabber_whiteboard/keynode.cpp
src/jabber_whiteboard/keynode.h
src/jabber_whiteboard/node-tracker.h
src/jabber_whiteboard/session-manager.h

index b1dac9913e609e6b09ea2c56715c759c9fb3e01e..ad064126016c92b30d942f7984813115746b2619 100644 (file)
@@ -49,7 +49,7 @@ namespace Vars {
         "<%1><%2 /></%1>");
 
     const std::string NEW_MESSAGE(
-        "<new parent=\"%1\" id=\"%2\" index=\"%3\">%4</new>");
+        "<new parent=\"%1\" id=\"%2\" index=\"%3\" version=\"%4\">%5</new>");
 
     const std::string CONFIGURE_MESSAGE(
         "<configure target=\"%1\" version=\"%2\" attribute=\"%3\" value=\"%4\" />");
index 8b3c563540f325cdfe77781a5047d9239268669b..a9bc80ca6b1072193d6fa60bfe98fe921551867b 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef __INKSCAPE_WHITEBOARD_DEFINES_H__
 #define __INKSCAPE_WHITEBOARD_DEFINES_H__
 
+#include "xml/node.h"
 #include "jabber_whiteboard/message-tags.h"
 
 #include <algorithm>
@@ -26,8 +27,6 @@
 #include <glibmm.h>
 #include <sigc++/sigc++.h>
 
-#include "jabber_whiteboard/keynode.h"
-
 #include "gc-alloc.h"
 
 // Various specializations of std::less for XMLNodeTracker maps.
@@ -42,10 +41,10 @@ using Inkscape::XML::Node;
 template<>
 struct less< Node* > : public binary_function < Node*, Node*, bool >
 {
-       bool operator()(Node* _x, Node* _y) const
-       {
-               return _x < _y;
-       }
+    bool operator()(Node* _x, Node* _y) const
+    {
+        return _x < _y;
+    }
 
 };
 
@@ -133,10 +132,10 @@ namespace Dialog {
 
 }
 
-// message types
-// explicitly numbered to aid protocol description later on
-
+class KeyNodePair;
+class KeyNodeTable;
 
+typedef std::pair<Glib::ustring, Glib::ustring> Configure;
 
 // Message handler modes
 enum HandlerMode {
index 3c063a382d6c3b86f597ddeed792bdb63d89caa3..a8b3567da2a170e2fe72ca9391ac51d018ee1fc1 100644 (file)
@@ -38,6 +38,7 @@ InkboardDocument::_initBindings()
 {
     this->sm = &SessionManager::instance();
     this->state = State::INITIAL;
+    this->tracker = new KeyNodeTable();
     _bindDocument(*this);
     _bindLogger(*(new InkboardSession(this)));
 }
@@ -106,7 +107,6 @@ InkboardDocument::recieve(Message::Wrapper &wrapper, Pedro::Element* data)
                 this->send(getRecipient(),Message::PROTOCOL, Message::DOCUMENT_BEGIN);
 
                 // Send Document
-                this->tracker = new KeyNodeTable();
                 this->sendDocument(this->root());
 
                 this->send(getRecipient(),Message::PROTOCOL, Message::DOCUMENT_END);
@@ -270,16 +270,29 @@ InkboardDocument::handleChange(Message::Wrapper &wrapper, Pedro::Element* data)
 
     }else if(wrapper == Message::CONFIGURE)
     {
-        Glib::ustring target =      data->getTagAttribute("configure","target");
-        Glib::ustring attribute =   data->getTagAttribute("configure","attribute");
-        Glib::ustring value =       data->getTagAttribute("configure","value");
+        if(data->exists("text"))
+        {
+            Glib::ustring text =    data->getFirstChild()->getValue();
+            Glib::ustring target =  data->getTagAttribute("configure","target");
+
+            unsigned int version = atoi
+                (data->getTagAttribute("configure","version").c_str());
 
-        signed int version = atoi
-            (data->getTagAttribute("configure","version").c_str());
+            if(text.size() > 0 && target.size() > 0)
+                this->changeConfigureText(target,version,text);
 
-        if(target.size() > 0 && attribute.size() > 0 && value.size() > 0)
-            this->changeConfigure(target,version,attribute,value);
+        }else 
+        {
+            Glib::ustring target =      data->getTagAttribute("configure","target");
+            Glib::ustring attribute =   data->getTagAttribute("configure","attribute");
+            Glib::ustring value =       data->getTagAttribute("configure","value");
 
+            unsigned int version = atoi
+                (data->getTagAttribute("configure","version").c_str());
+
+            if(target.size() > 0 && attribute.size() > 0 && value.size() > 0)
+                this->changeConfigure(target,version,attribute,value);
+        }
     }else if(wrapper == Message::MOVE)
     {
     }else if(wrapper == Message::REMOVE) 
index 510f47c6e5d11c0e69e2c11e98a7a9957cf4cdb1..5eaeffca8e65ee8434f5707f77fe8003acc63d2a 100644 (file)
@@ -66,12 +66,15 @@ public:
     Glib::ustring addNodeToTracker(Inkscape::XML::Node* node);
     Message::Message composeNewMessage(Inkscape::XML::Node *node);
 
-    void changeConfigure(Glib::ustring target, signed int target,
+    void changeConfigure(Glib::ustring target, unsigned int version,
             Glib::ustring attribute, Glib::ustring value);
 
     void changeNew(Glib::ustring target, Glib::ustring, 
             signed int index, Pedro::Element* data);
 
+    void changeConfigureText(Glib::ustring target, unsigned int version,
+            Glib::ustring text);
+
 
 protected:
        /**
index bcb6cd981af3f522a4f23fb43842cac7b43a5138..5f40e38088991561d984766643860713939b305f 100644 (file)
 
 #include "util/ucompose.hpp"
 
+#include "pedro/pedrodom.h"
+
+#include "xml/attribute-record.h"
+#include "xml/element-node.h"
+#include "xml/text-node.h"
+
 #include "jabber_whiteboard/message-utilities.h"
 #include "jabber_whiteboard/defines.h"
 #include "jabber_whiteboard/inkboard-document.h"
@@ -26,7 +32,8 @@ namespace Whiteboard {
 Glib::ustring
 InkboardDocument::addNodeToTracker(Inkscape::XML::Node *node)
 {
-    Glib::ustring key = this->tracker->generateKey(this->getRecipient());
+    Glib::ustring rec = this->getRecipient();
+    Glib::ustring key = this->tracker->generateKey(rec);
     this->tracker->put(key,node);
     return key;
 }
@@ -47,27 +54,77 @@ InkboardDocument::composeNewMessage(Inkscape::XML::Node *node)
     unsigned int index = parent->_childPosition(*node);
 
     Message::Message nodeMessage = MessageUtilities::objectToString(node);
-    Message::Message message = String::ucompose(Vars::NEW_MESSAGE,parentKey,key,index,nodeMessage);
+    Message::Message message = String::ucompose(Vars::NEW_MESSAGE,parentKey,key,index,0,nodeMessage);
 
     return message;
 }
 
 void
-InkboardDocument::changeConfigure(Glib::ustring target, signed int version, 
+InkboardDocument::changeConfigureText(Glib::ustring target, unsigned int version,
+        Glib::ustring text)
+{
+    XML::Node *node = this->tracker->get(target);
+    unsigned int elementVersion = this->tracker->getVersion(node);
+
+    if(node && version == (elementVersion + 1))
+    {
+        this->tracker->incrementVersion(node);
+        this->tracker->addHistory(node, "text", text);
+        node->setContent(text.c_str());
+    }
+}
+
+void
+InkboardDocument::changeConfigure(Glib::ustring target, unsigned int version, 
         Glib::ustring attribute, Glib::ustring value)
 {
+    XML::Node *node = this->tracker->get(target);
+    unsigned int elementVersion = this->tracker->getVersion(node);
+
+    if(node && version == (elementVersion + 1))
+    {
+        this->tracker->incrementVersion(node);
+        this->tracker->addHistory(node, attribute, node->attribute(attribute.c_str()));
+        node->setAttribute(attribute.c_str(),value.c_str());
+    }
 }
 
 void 
-InkboardDocument::changeNew(Glib::ustring target, Glib::ustring
+InkboardDocument::changeNew(Glib::ustring parentid, Glib::ustring id
         signed int index, Pedro::Element* data)
 {
-    Glib::ustring name = data->getName();
+
+    Glib::ustring name(data->getName());
 
     if(name == "text")
     { 
-        //XML::Node* parent = this->tracker->get(target);
-        //parent->setContent(date->getValue());
+        XML::Node *parent = this->tracker->get(parentid);
+        XML::Node *node = new XML::TextNode(Util::share_string(data->getValue().c_str()));
+
+        if(parent && node)
+        {
+            this->tracker->put(id,node);
+            parent->appendChild(node);
+        }
+    }else
+    {
+        XML::Node *node = new XML::ElementNode(g_quark_from_string(name.c_str()));
+        this->tracker->put(id,node);
+
+        XML::Node *parent = (parentid != "ROOT") 
+            ? this->tracker->get(parentid.c_str()) : this->root();
+
+        std::vector<Pedro::Attribute> attributes = data->getAttributes();
+
+        for (unsigned int i=0; i<attributes.size(); i++) 
+        {
+            node->setAttribute(
+                (attributes[i].getName()).c_str(),
+                (attributes[i].getValue()).c_str());
+        }
+
+        if(parent != NULL)
+            parent->appendChild(node);
     }
 
 }
index 6601d5d879b43ffe762eb346e79bbc8907f7d852..b52b9bd44303f205feec37a6dea8d08b2f943cce 100644 (file)
@@ -88,10 +88,13 @@ void InkboardSession::notifyChildAdded(Node &parent,
 
         XML::Node *node = (XML::Node *)&child;
 
-        this->doc->addNodeToTracker(node);
-        Message::Message message = this->doc->composeNewMessage(node);
+        if(this->doc->tracker->get(node) == "")
+        {
+            this->doc->addNodeToTracker(node);
+            Message::Message message = this->doc->composeNewMessage(node);
 
-        this->doc->send(this->doc->getRecipient(),Message::NEW,message);
+            this->doc->send(this->doc->getRecipient(),Message::NEW,message);
+        }
     }
 }
 
@@ -139,8 +142,10 @@ void InkboardSession::notifyContentChanged(Node &node,
 
         if(new_content.pointer())
         {
+            unsigned int version = this->doc->tracker->incrementVersion(element);
+
             Message::Message message = String::ucompose(Vars::CONFIGURE_TEXT_MESSAGE,
-                this->doc->tracker->get(element),"0",new_content.pointer());
+                this->doc->tracker->get(element),version,new_content.pointer());
 
             this->doc->send(this->doc->getRecipient(),Message::CONFIGURE,message);
         }
@@ -156,10 +161,20 @@ void InkboardSession::notifyAttributeChanged(Node &node,
     {
         XML::Node *element = (XML::Node *)&node;
 
+        Glib::ustring value(new_value.pointer());
+        Glib::ustring attribute(g_quark_to_string(name));
+
+        Configure change = this->doc->tracker->getLastHistory(element);
+
+        if(change.first == attribute && change.second == value)
+            return;
+
         if(name && new_value.pointer())
         {
+            unsigned int version = this->doc->tracker->incrementVersion(element);
+
             Message::Message message = String::ucompose(Vars::CONFIGURE_MESSAGE,
-                this->doc->tracker->get(element),"0",g_quark_to_string(name),new_value.pointer());
+                this->doc->tracker->get(element),version,attribute.c_str(),value.c_str());
 
             this->doc->send(this->doc->getRecipient(),Message::CONFIGURE,message);
         }
index 6f0a5226ff9841afa75fbdc23bed7cea8bb9df8c..af2c0762edfaa739726141a92321b2743d3ab6f6 100644 (file)
@@ -89,6 +89,51 @@ Glib::ustring KeyNodeTable::get(XML::Node *node) const
     return "";
 }
 
+unsigned int KeyNodeTable::incrementVersion(XML::Node *node)
+{
+    std::vector<KeyNodePair>::iterator iter;
+    for (iter = items.begin() ; iter != items.end() ; iter++)
+    {
+        if (node == iter->node)
+            break;
+    }
+    return ++iter->version;
+}
+
+unsigned int KeyNodeTable::getVersion(XML::Node *node)
+{
+    std::vector<KeyNodePair>::iterator iter;
+    for (iter = items.begin() ; iter != items.end() ; iter++)
+    {
+        if (node == iter->node)
+            break;
+    }
+    return iter->version;
+}
+
+void KeyNodeTable::addHistory(XML::Node *node, Glib::ustring attribute, Glib::ustring value)
+{
+    std::vector<KeyNodePair>::iterator iter;
+    for (iter = items.begin() ; iter != items.end() ; iter++)
+    {
+        if (node == iter->node)
+        {
+            Configure pair(attribute, value);
+            iter->history.push_back(pair);
+        }
+    }
+}
+
+Configure& KeyNodeTable::getLastHistory(XML::Node *node)
+{
+    std::vector<KeyNodePair>::iterator iter;
+    for (iter = items.begin() ; iter != items.end() ; iter++)
+    {
+        if (node == iter->node)
+            break;
+    }
+    return iter->history.back();
+}
 
 void KeyNodeTable::remove(XML::Node *node)
 {
index f727219d5c249b54ed68d5d9642a39ccfeddb09d..df7557fd1e0c38c837ef905d6c25b59bb479c916 100644 (file)
 #include <vector>
 
 #include "xml/node.h"
-
+#include "jabber_whiteboard/defines.h"
 
 namespace Inkscape
 {
 namespace Whiteboard
 {
 
-
 class KeyNodePair
 {
 public:
-   KeyNodePair(const Glib::ustring &keyArg, const XML::Node *nodeArg)
-       {
-       key  = keyArg; 
-       node = (XML::Node *)nodeArg;
-       }
-   KeyNodePair(const KeyNodePair &other)
-       {
-       key  = other.key; 
-       node = other.node;
-       }
-   virtual ~KeyNodePair()
-       {}
-   Glib::ustring key;
-   XML::Node *node;
+
+    KeyNodePair(const Glib::ustring &keyArg, const XML::Node *nodeArg)
+    {
+        key  = keyArg; 
+        node = (XML::Node *)nodeArg;
+        version = 0;
+        index = 0;
+    }
+
+    KeyNodePair(const Glib::ustring &keyArg, const XML::Node *nodeArg,
+        unsigned int version, signed int index)
+    {
+        key  = keyArg; 
+        node = (XML::Node *)nodeArg;
+        this->version = version;
+        this->index = index;
+    }
+
+    KeyNodePair(const KeyNodePair &other)
+    {
+        key  = other.key; 
+        node = other.node;
+        version = other.version;
+        index = other.index;
+        history = other.history;
+    }
+
+    virtual ~KeyNodePair() {}
+
+    Glib::ustring key;
+    XML::Node *node;
+    unsigned int version;
+    signed int index;
+    std::list< Configure > history;
 };
 
 class KeyNodeTable
@@ -80,6 +99,14 @@ public:
 
     virtual Glib::ustring generateKey(Glib::ustring);
 
+    virtual unsigned int getVersion(XML::Node *node);
+
+    virtual unsigned int incrementVersion(XML::Node *node);
+
+    virtual void addHistory(XML::Node *node, Glib::ustring attribute, Glib::ustring value);
+
+    virtual Configure& getLastHistory(XML::Node *node);
+
 private:
 
     std::vector<KeyNodePair> items;
index 2bb61f5a533f253d4ba4f6db51c93c09764e3b78..75852e98e284496175c96c6e1e1f0d9326d1d342 100644 (file)
@@ -199,14 +199,14 @@ public:
 private:
         //common code called by constructors
         void init();
-        
+
        void createSpecialNodeTables();
        void _clear();
        
        unsigned int _counter;
        SessionManager* _sm;
-        
-        KeyNodeTable keyNodeTable;
+
+        //KeyNodeTable keyNodeTable;
 
        std::map< char const*, char const*, strcmpless > _specialnodes;
 
index 1ba6266852c99318f7f74d6bc3774f66bdb89e13..ed1b5edf6287570d97e94fc728a535252006a4c0 100644 (file)
@@ -53,7 +53,6 @@ public:
 
     virtual ~SessionManager();
 
-
     static void             showClient();
     static SessionManager&  instance();
 
@@ -119,7 +118,9 @@ private:
 
 };
 
-SPDocument* makeInkboardDocument(int code, gchar const* rootname, State::SessionType type, Glib::ustring const& to);
+SPDocument* makeInkboardDocument(int code, gchar const* rootname, 
+    State::SessionType type, Glib::ustring const& to);
+
 SPDesktop*  makeInkboardDesktop(SPDocument* doc);
 
 }  // namespace Whiteboard