Code

inkboard-session now sends all changes to the document
[inkscape.git] / src / jabber_whiteboard / inkboard-document.cpp
1 /**
2  * Inkscape::Whiteboard::InkboardDocument - Inkboard document implementation
3  *
4  * Authors:
5  * David Yip <yipdw@rose-hulman.edu>
6  *
7  * Copyright (c) 2005 Authors
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #include <glib.h>
13 #include <glibmm.h>
15 #include "jabber_whiteboard/inkboard-document.h"
17 #include "util/ucompose.hpp"
19 #include "xml/simple-session.h"
20 #include "jabber_whiteboard/inkboard-session.h"
21 #include "jabber_whiteboard/message-utilities.h"
22 #include "jabber_whiteboard/defines.h"
23 #include "jabber_whiteboard/session-manager.h"
24 #include "jabber_whiteboard/node-tracker.h"
26 namespace Inkscape {
28 namespace Whiteboard {
30 InkboardDocument::InkboardDocument(int code, State::SessionType sessionType, Glib::ustring const& to) :
31         XML::SimpleNode(code), sessionType(sessionType), recipient(to)
32 {
33     _initBindings();
34 }
36 void
37 InkboardDocument::_initBindings()
38 {
39     this->sm = &SessionManager::instance();
40     this->state = State::INITIAL;
41     _bindDocument(*this);
42     _bindLogger(*(new InkboardSession(this)));
43 }
45 void
46 InkboardDocument::setRecipient(Glib::ustring const& val)
47 {
48     this->recipient = val;
49 }
51 Glib::ustring 
52 InkboardDocument::getRecipient() const
53 {
54     return this->recipient;
55 }
57 void
58 InkboardDocument::setSessionId(Glib::ustring const& val)
59 {
60     this->sessionId = val;
61 }
63 Glib::ustring 
64 InkboardDocument::getSessionId() const
65 {
66     return this->sessionId;
67 }
69 void
70 InkboardDocument::startSessionNegotiation()
71 {
72     if(this->sessionType == State::WHITEBOARD_PEER)
73         this->send(recipient, Message::PROTOCOL,Message::CONNECT_REQUEST);
75     else if(this->sessionType == State::WHITEBOARD_MUC)
76     {
77         // Check that the MUC room is whiteboard enabled, if not no need to send 
78         // anything, just set the room to be whiteboard enabled
79     }
80 }
82 void
83 InkboardDocument::terminateSession()
84 {
86 }
88 void
89 InkboardDocument::recieve(Message::Wrapper &wrapper, Pedro::Element* data)
90 {
91     if(this->handleIncomingState(wrapper,data))
92     {
93         if(wrapper == Message::PROTOCOL)
94         {
95             Glib::ustring message = data->getFirstChild()->getFirstChild()->getFirstChild()->getName();
97             if(message == Message::CONNECT_REQUEST)
98             {
99                 // An MUC member requesting document
101             }else if(message == Message::ACCEPT_INVITATION)
102             {
103                 // TODO : Would be nice to create the desktop here
105                 this->send(getRecipient(),Message::PROTOCOL, Message::CONNECTED);
106                 this->send(getRecipient(),Message::PROTOCOL, Message::DOCUMENT_BEGIN);
108                 // Send Document
109                 this->tracker = new KeyNodeTable();
110                 this->sendDocument(this->root());
112                 this->send(getRecipient(),Message::PROTOCOL, Message::DOCUMENT_END);
114             }else if(message == Message::DECLINE_INVITATION)
115             {
116                 this->sm->terminateSession(this->getSessionId());
117             }
118         }
119     }else{
120         g_warning("Recieved Message in invalid state = %d", this->state);
121         data->print();
122     }
125 bool
126 InkboardDocument::send(const Glib::ustring &destJid, Message::Wrapper &wrapper, Message::Message &message)
128     if(this->handleOutgoingState(wrapper,message))
129     {
130         Glib::ustring mes;
131         if(wrapper == Message::PROTOCOL)
132             mes = String::ucompose(Vars::PROTOCOL_MESSAGE,wrapper,message);
133         else
134             mes = message;
136         char *finalmessage = const_cast<char* >(String::ucompose(Vars::WHITEBOARD_MESSAGE,
137             this->sessionType,this->sm->getClient().getJid(),destJid,
138             Vars::INKBOARD_XMLNS,this->getSessionId(),mes).c_str());
140         if (!this->sm->getClient().write(finalmessage)) 
141             { return false; }
142         else 
143             { return true; }
145     }else 
146     { 
147         g_warning("Sending Message in invalid state message=%s , state=%d",message.c_str(),this->state);
148         return false; 
149     }
152 void
153 InkboardDocument::sendDocument(Inkscape::XML::Node* root)
155     for(Inkscape::XML::Node *child = root->firstChild();child!=NULL;child=child->next())
156     {
157         Glib::ustring parentKey,tempParentKey,key;
159         this->addNodeToTracker(child);
160         Message::Message message = this->composeNewMessage(child);
162         this->send(this->getRecipient(),Message::NEW,message);
164         if(child->childCount() != 0)
165         {
166             sendDocument(child);
167         }
168     }
171 bool
172 InkboardDocument::handleOutgoingState(Message::Wrapper &wrapper, Glib::ustring const& message)
174     if(wrapper == Message::PROTOCOL) 
175     {
176         if(message == Message::CONNECT_REQUEST) 
177             return this->handleState(State::INITIAL,State::AWAITING_INVITATION_REPLY);
179         else if(message == Message::ACCEPT_INVITATION)
180             return this->handleState(State::CONNECTING,State::AWAITING_CONNECTED);
182         else if(message == Message::CONNECTED)
183             return this->handleState(State::INVITATION_RECIEVED,State::CONNECTED);
185         else if(message == Message::DOCUMENT_BEGIN)
186             return this->handleState(State::CONNECTED,State::SYNCHRONISING);
188         else if(message == Message::DOCUMENT_END) { 
189             return this->handleState(State::SYNCHRONISING,State::IN_WHITEBOARD);
190         }
192         else 
193             return false;
195     } else 
196         if(this->state == State::SYNCHRONISING && wrapper == Message::NEW)
197             return true;
199     return this->state == State::IN_WHITEBOARD;
202 bool
203 InkboardDocument::handleIncomingState(Message::Wrapper &wrapper, Pedro::Element* data)
205     if(wrapper == Message::PROTOCOL) 
206     {
207         Glib::ustring message = data->getFirstChild()->getFirstChild()->getFirstChild()->getName();
209         if(message == Message::CONNECT_REQUEST)
210             return this->handleState(State::INITIAL,State::CONNECTING);
211         if(message == Message::ACCEPT_INVITATION)
212             return this->handleState(State::AWAITING_INVITATION_REPLY,State::INVITATION_RECIEVED);
214         else if(message == Message::CONNECTED)
215             return this->handleState(State::AWAITING_CONNECTED,State::AWAITING_DOCUMENT_BEGIN);
217         else if(message == Message::DOCUMENT_BEGIN)
218             return this->handleState(State::AWAITING_DOCUMENT_BEGIN,State::SYNCHRONISING);
220         else if(message == Message::DOCUMENT_END)
221             return this->handleState(State::SYNCHRONISING,State::IN_WHITEBOARD);
223         else 
224             return false;
226     } else 
227         if(this->state == State::SYNCHRONISING && wrapper == Message::NEW)
228             return true;
230     return this->state == State::IN_WHITEBOARD;
233 bool 
234 InkboardDocument::handleState(State::SessionState expectedState, State::SessionState newState)
236     if(this->state == expectedState)
237     {
238         this->state = newState;
239         return true;
240     }
242     return false;
245 } // namespace Whiteboard
246 } // namespace Inkscape
249 /*
250   Local Variables:
251   mode:c++
252   c-file-style:"stroustrup"
253   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
254   indent-tabs-mode:nil
255   fill-column:99
256   End:
257 */
258 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :