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 }
123 }
125 bool
126 InkboardDocument::send(const Glib::ustring &destJid, Message::Wrapper &wrapper, Message::Message &message)
127 {
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 }
150 }
152 void
153 InkboardDocument::sendDocument(Inkscape::XML::Node* root)
154 {
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 }
169 }
171 bool
172 InkboardDocument::handleOutgoingState(Message::Wrapper &wrapper, Glib::ustring const& message)
173 {
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;
200 }
202 bool
203 InkboardDocument::handleIncomingState(Message::Wrapper &wrapper, Pedro::Element* data)
204 {
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;
231 }
233 bool
234 InkboardDocument::handleState(State::SessionState expectedState, State::SessionState newState)
235 {
236 if(this->state == expectedState)
237 {
238 this->state = newState;
239 return true;
240 }
242 return false;
243 }
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 :