Code

plumb XML::Document parameter into duplication, courtesy of bryce
[inkscape.git] / src / jabber_whiteboard / inkboard-document.cpp
index 644db8e2a3b1ca7d7f63a48e7cabbdee0b16eff6..9f3d8ce4293dac6fb59862965dec2df0ad85de0a 100644 (file)
 
 #include "jabber_whiteboard/inkboard-document.h"
 
-
 #include "util/ucompose.hpp"
 
-#include "xml/simple-session.h"
-#include "jabber_whiteboard/inkboard-session.h"
+#include "jabber_whiteboard/message-utilities.h"
 #include "jabber_whiteboard/defines.h"
 #include "jabber_whiteboard/session-manager.h"
 #include "jabber_whiteboard/node-tracker.h"
 
+#include <glibmm.h>
+#include <glib/gmessages.h>
+#include <glib/gquark.h>
+
+#include "jabber_whiteboard/inkboard-document.h"
+#include "jabber_whiteboard/defines.h"
+
+#include "xml/node.h"
+#include "xml/event.h"
+#include "xml/element-node.h"
+#include "xml/text-node.h"
+#include "xml/comment-node.h"
+
+#include "util/share.h"
+#include "util/ucompose.hpp"
+
 namespace Inkscape {
 
 namespace Whiteboard {
 
-InkboardDocument::InkboardDocument(int code, State::SessionType sessionType, Glib::ustring const& to) :
-       XML::SimpleNode(code), sessionType(sessionType), recipient(to)
+InkboardDocument::InkboardDocument(int code, State::SessionType sessionType,
+                                   Glib::ustring const& to)
+: XML::SimpleNode(code), sessionType(sessionType), recipient(to),
+  _in_transaction(false)
 {
     _initBindings();
 }
@@ -38,8 +54,8 @@ InkboardDocument::_initBindings()
 {
     this->sm = &SessionManager::instance();
     this->state = State::INITIAL;
+    this->tracker = new KeyNodeTable();
     _bindDocument(*this);
-    _bindLogger(*(new XML::SimpleSession()));
 }
 
 void
@@ -106,8 +122,7 @@ 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->sendDocument(this->root());
 
                 this->send(getRecipient(),Message::PROTOCOL, Message::DOCUMENT_END);
 
@@ -115,6 +130,10 @@ InkboardDocument::recieve(Message::Wrapper &wrapper, Pedro::Element* data)
             {
                 this->sm->terminateSession(this->getSessionId());
             }
+        }else if(wrapper == Message::NEW || wrapper == Message::CONFIGURE
+                    || wrapper == Message::MOVE || wrapper == Message::REMOVE )
+        {
+            handleChange(wrapper,data->getFirstChild()->getFirstChild());
         }
     }else{
         g_warning("Recieved Message in invalid state = %d", this->state);
@@ -133,11 +152,11 @@ InkboardDocument::send(const Glib::ustring &destJid, Message::Wrapper &wrapper,
         else
             mes = message;
 
-        char *finalmessage = const_cast<char* >(String::ucompose(Vars::WHITEBOARD_MESSAGE,
-            this->sessionType,this->sm->getClient().getJid(),destJid,
-            Vars::INKBOARD_XMLNS,this->getSessionId(),mes).c_str());
+        char *finalmessage = const_cast<char* >(String::ucompose(
+            Vars::WHITEBOARD_MESSAGE, this->sessionType, this->sm->getClient().getJid(),
+            destJid, Vars::INKBOARD_XMLNS, this->getSessionId(), mes).c_str());
 
-        if (!this->sm->getClient().write(finalmessage)) 
+        if (!this->sm->getClient().write("%s",finalmessage)) 
             { return false; }
         else 
             { return true; }
@@ -150,9 +169,27 @@ InkboardDocument::send(const Glib::ustring &destJid, Message::Wrapper &wrapper,
 }
 
 void
-InkboardDocument::sendDocument()
+InkboardDocument::sendDocument(Inkscape::XML::Node* root)
 {
+    for(Inkscape::XML::Node *child = root->firstChild();child!=NULL;child=child->next())
+    {
+        Glib::ustring name(child->name());
+
+        if(name != "svg:metadata" && name != "svg:defs" && name != "sodipodi:namedview")
+        {
+            Glib::ustring parentKey,tempParentKey,key;
+
+            this->addNodeToTracker(child);
+            Message::Message message = this->composeNewMessage(child);
+
+            this->send(this->getRecipient(),Message::NEW,message);
 
+            if(child->childCount() != 0)
+            {
+                sendDocument(child);
+            }
+        }
+    }
 }
 
 bool
@@ -230,17 +267,210 @@ InkboardDocument::handleState(State::SessionState expectedState, State::SessionS
 }
 
 
-} // namespace Whiteboard
-} // namespace Inkscape
+void
+InkboardDocument::handleChange(Message::Wrapper &wrapper, Pedro::Element* data)
+{
+    if(wrapper == Message::NEW)
+    {
+        Glib::ustring parent =  data->getTagAttribute("new","parent");
+        Glib::ustring id =      data->getTagAttribute("new","id");
+
+        signed int index = atoi
+            (data->getTagAttribute("new","index").c_str());
+
+        Pedro::Element* element = data->getFirstChild();
+
+        if(parent.size() > 0 && id.size() > 0)
+            this->changeNew(parent,id,index,element);
+
+    }else if(wrapper == Message::CONFIGURE)
+    {
+        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());
+
+            if(text.size() > 0 && target.size() > 0)
+                this->changeConfigureText(target,version,text);
+
+        }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) 
+    {
+    }
+}
+
+void
+InkboardDocument::beginTransaction()
+{
+    g_assert(!_in_transaction);
+    _in_transaction = true;
+}
+
+void
+InkboardDocument::rollback()
+{
+    g_assert(_in_transaction);
+    _in_transaction = false;
+}
+
+void 
+InkboardDocument::commit()
+{
+    g_assert(_in_transaction);
+    _in_transaction = false;
+}
+
+XML::Event*
+InkboardDocument::commitUndoable()
+{
+    g_assert(_in_transaction);
+    _in_transaction = false;
+    return NULL;
+}
+
+XML::Node*
+InkboardDocument::createElement(char const* name)
+{
+    return new XML::ElementNode(g_quark_from_string(name));
+}
+
+XML::Node*
+InkboardDocument::createTextNode(char const* content)
+{
+    return new XML::TextNode(Util::share_string(content));
+}
+
+XML::Node*
+InkboardDocument::createComment(char const* content)
+{
+    return new XML::CommentNode(Util::share_string(content));
+}
+
+
+void InkboardDocument::notifyChildAdded(XML::Node &parent,
+                                        XML::Node &child,
+                                        XML::Node *prev)
+{
+    if (_in_transaction && state == State::IN_WHITEBOARD) {
 
+        XML::Node *node = (XML::Node *)&child;
 
-/*
-  Local Variables:
-  mode:c++
-  c-file-style:"stroustrup"
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
-  indent-tabs-mode:nil
-  fill-column:99
-  End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+        if(tracker->get(node) == "")
+        {
+            addNodeToTracker(node);
+            Message::Message message = composeNewMessage(node);
+
+            send(getRecipient(),Message::NEW,message);
+        }
+    }
+}
+
+void InkboardDocument::notifyChildRemoved(XML::Node &parent,
+                                          XML::Node &child,
+                                          XML::Node *prev)
+{
+    if (_in_transaction && state == State::IN_WHITEBOARD) 
+    {
+        XML::Node *element = (XML::Node *)&child;
+
+        Message::Message message = String::ucompose(Vars::REMOVE_MESSAGE,
+            tracker->get(element));
+
+        send(getRecipient(),Message::REMOVE,message);
+   }
+}
+
+void InkboardDocument::notifyChildOrderChanged(XML::Node &parent,
+                                               XML::Node &child,
+                                               XML::Node *old_prev,
+                                               XML::Node *new_prev)
+{
+    if (_in_transaction && state == State::IN_WHITEBOARD) 
+    {
+        XML::Node *element = (XML::Node *)&child;
+        XML::Node *parentElement = (XML::Node *)&parent;
+
+        unsigned int index = parentElement->_childPosition(*element);
+
+        Message::Message message = String::ucompose(Vars::MOVE_MESSAGE,
+                tracker->get(element),index);
+
+        send(getRecipient(),Message::MOVE,message);
+    }
+}
+
+void InkboardDocument::notifyContentChanged(XML::Node &node,
+                                            Util::ptr_shared<char> old_content,
+                                            Util::ptr_shared<char> new_content)
+{
+    if (_in_transaction && state == State::IN_WHITEBOARD) 
+    {
+        XML::Node *element = (XML::Node *)&node;
+
+        Glib::ustring value(new_content.pointer());
+
+        Glib::ustring change = tracker->getLastHistory(element,"text");
+
+        if(change.size() > 0 && change == value)
+            return;
+
+        if(new_content.pointer())
+        {
+            unsigned int version = tracker->incrementVersion(element);
+
+            Message::Message message = String::ucompose(Vars::CONFIGURE_TEXT_MESSAGE,
+                tracker->get(element),version,new_content.pointer());
+
+            send(getRecipient(),Message::CONFIGURE,message);
+        }
+    }
+}
+
+void InkboardDocument::notifyAttributeChanged(XML::Node &node,
+                                              GQuark name,
+                                              Util::ptr_shared<char> old_value,
+                                              Util::ptr_shared<char> new_value)
+{
+    if (_in_transaction && state == State::IN_WHITEBOARD) 
+    {
+        XML::Node *element = (XML::Node *)&node;
+
+        Glib::ustring value(new_value.pointer());
+        Glib::ustring attribute(g_quark_to_string(name));
+
+        Glib::ustring change = tracker->getLastHistory(element,attribute);
+
+        if(change.size() > 0 && change == value)
+            return;
+
+        if(attribute.size() > 0 && value.size() > 0)
+        {
+            unsigned int version = tracker->incrementVersion(element);
+
+            Message::Message message = String::ucompose(Vars::CONFIGURE_MESSAGE,
+                tracker->get(element),version,attribute.c_str(),value.c_str());
+
+            send(getRecipient(),Message::CONFIGURE,message);
+        }
+    }
+}
+
+}
+
+}