summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d1b2a91)
raw | patch | inline | side by side (parent: d1b2a91)
author | daleharvey <daleharvey@users.sourceforge.net> | |
Wed, 2 Aug 2006 18:36:41 +0000 (18:36 +0000) | ||
committer | daleharvey <daleharvey@users.sourceforge.net> | |
Wed, 2 Aug 2006 18:36:41 +0000 (18:36 +0000) |
index 1f2d2667163549de71a5d84ddfcb58227dc1b659..bea89e80378812ae59e48b43446ca40f12f3f92e 100644 (file)
jabber_whiteboard/message-tags.h \
jabber_whiteboard/message-utilities.cpp \
jabber_whiteboard/message-utilities.h \
- jabber_whiteboard/new-inkboard-document.cpp \
- jabber_whiteboard/new-inkboard-document.h \
jabber_whiteboard/inkboard-document.cpp \
jabber_whiteboard/inkboard-document.h \
jabber_whiteboard/invitation-confirm-dialog.cpp \
jabber_whiteboard/invitation-confirm-dialog.h \
- jabber_whiteboard/invitation-handlers.cpp \
jabber_whiteboard/session-file-selector.cpp \
jabber_whiteboard/session-file-selector.h \
jabber_whiteboard/session-manager.cpp \
index 3e3895ea04207e71e77e02e48e039ef0eadba4e2..43a75cb7c21ce3a5a4ccd262a8c9d34fed6e206a 100644 (file)
Wrapper CONFIGURE = "configure";
Wrapper MOVE = "move";
- Message CONNECT_REQUEST = "<connect-request />";
- Message CONNECTED = "<connected />";
- Message ACCEPT_INVITATION = "<accept-invitation />";
- Message DECLINE_INVITATION = "<decline-invitation />";
- Message DOCUMENT_BEGIN = "<document-begin />";
- Message DOCUMENT_END = "<document-end />";
+ Message CONNECT_REQUEST = "connect-request";
+ Message CONNECTED = "connected";
+ Message ACCEPT_INVITATION = "accept-invitation";
+ Message DECLINE_INVITATION = "decline-invitation";
+ Message DOCUMENT_BEGIN = "document-begin";
+ Message DOCUMENT_END = "document-end";
}
namespace Vars {
index a5d2d2ce6a7ec867c66c1d9bc7f577740b083485..e08d876a680de0ec5f126fec65f6529b3205f5a3 100644 (file)
typedef char const* SessionState;
}
+namespace Dialog {
+
+enum DialogReply {
+
+ ACCEPT_INVITATION = 0,
+ DECLINE_INVITATION = 1
+};
+
+}
+
// message types
// explicitly numbered to aid protocol description later on
-// Responses to whiteboard invitations
-enum InvitationResponses {
- ACCEPT_INVITATION,
- DECLINE_INVITATION,
- PEER_ALREADY_IN_SESSION,
- UNSUPPORTED_PROTOCOL
-};
// Message handler modes
enum HandlerMode {
// Message serialization
typedef std::list< Glib::ustring > SerializedEventList;
+
+ //typedef std::pair< Glib::ustring, InvitationResponses > Invitation_response_type;
+ //typedef std::list< Invitation_response_type > Invitation_responses_type;
// Error handling -- someday
// TODO: finish and integrate this
//typedef boost::function< LmHandlerResult (unsigned int code) > ErrorHandlerFunctor;
diff --git a/src/jabber_whiteboard/inkboard-document.cpp b/src/jabber_whiteboard/inkboard-document.cpp
index 5f0d27e89bc4fb875c9b4c30e4b888f31021e255..bf72d3c2af445b6a30f8f1b06b0f48082e540753 100644 (file)
}
void
-InkboardDocument::processInkboardEvent(Message::Wrapper mtype, unsigned int seqnum, Glib::ustring const& data)
+InkboardDocument::processInkboardEvent(Message::Wrapper mtype, Glib::ustring const& data)
{
- g_log(NULL, G_LOG_LEVEL_DEBUG, "Processing Inkboard event: mtype=%s seqnum=%d data=%s\n", mtype, seqnum, data.c_str());
+ g_log(NULL, G_LOG_LEVEL_DEBUG, "Processing Inkboard event: mtype=%s data=%s\n",mtype,data.c_str());
}
bool
"<message type='%s' from='%s' to='%s'>"
"<wb xmlns='%s' session='%s'>"
"<%s>"
- "%s"
+ "<%s />"
"</%s>"
"</wb>"
"<body> </body>"
index 0b0e5baed2790b2dad9d6e59b41674a452b533e9..71de75e19c05b24dcd9bb4b1224a964e19bdcfd4 100644 (file)
#include "xml/document.h"
#include "xml/simple-node.h"
-
+#include "jabber_whiteboard/defines.h"
#include "jabber_whiteboard/keynode.h"
#include "jabber_whiteboard/session-manager.h"
namespace Whiteboard {
+
class InkboardDocument : public XML::SimpleNode, public XML::Document {
public:
void startSessionNegotiation();
void terminateSession();
- void processInkboardEvent(Message::Wrapper mtype, unsigned int seqnum, Glib::ustring const& data);
+ void processInkboardEvent(Message::Wrapper mtype, Glib::ustring const& data);
bool sendProtocol(const Glib::ustring &destJid, Message::Wrapper mwrapper,
Message::Message message);
diff --git a/src/jabber_whiteboard/invitation-handlers.cpp b/src/jabber_whiteboard/invitation-handlers.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * Whiteboard session manager - invitation handling methods
- *
- * Authors:
- * David Yip <yipdw@rose-hulman.edu>
- * Bob Jamison (Pedro port)
- *
- * Copyright (c) 2005 Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <gtkmm.h>
-#include <glibmm/i18n.h>
-
-#include "util/ucompose.hpp"
-
-#include "document.h"
-#include "desktop-handles.h"
-
-#include "jabber_whiteboard/inkboard-document.h"
-#include "jabber_whiteboard/session-manager.h"
-#include "jabber_whiteboard/invitation-confirm-dialog.h"
-#include "jabber_whiteboard/defines.h"
-
-namespace Inkscape {
-
-namespace Whiteboard {
-
-bool
-SessionManager::_checkInvitationQueue()
-{
- int x, y;
- Gdk::ModifierType mt;
- Gdk::Display::get_default()->get_pointer(x, y, mt);
- if (mt & GDK_BUTTON1_MASK) {
- // The user is currently busy with an action. Defer invitation processing
- // until the user is free.
- return true;
- }
-
- if (_pending_invitations.size() > 0) {
- // There's an invitation to process; process it.
- Glib::ustring from = _pending_invitations.front();
-
- Glib::ustring primary = "<span weight=\"bold\" size=\"larger\">" + String::ucompose(_("<b>%1</b> has invited you to a whiteboard session."), from) + "</span>\n\n";
- primary += String::ucompose(_("Do you wish to accept <b>%1</b>'s whiteboard session invitation?"), from);
-
- InvitationConfirmDialog dialog(primary);
-
- dialog.add_button(_("Accept invitation"), ACCEPT_INVITATION);
- dialog.add_button(_("Decline invitation"), DECLINE_INVITATION);
-
- InvitationResponses resp = static_cast< InvitationResponses >(dialog.run());
-
- switch (resp) {
- case ACCEPT_INVITATION:
- {
- SPDesktop* dt = createInkboardDesktop(from, State::WHITEBOARD_PEER);
- InkboardDocument* idoc = dynamic_cast< InkboardDocument* >(sp_desktop_document(dt)->rdoc);
- //sendProtocol(from, Message::PROTOCOL, " ");
- break;
- }
- case DECLINE_INVITATION:
- {
- break;
- }
- default:
- //sendProtocol(from, Message::PROTOCOL, " ");
- break;
- }
-
- _pending_invitations.pop_front();
- }
-
- return true;
-}
-
-
-bool
-SessionManager::_checkInvitationResponseQueue()
-{
- int x, y;
- Gdk::ModifierType mt;
- Gdk::Display::get_default()->get_pointer(x, y, mt);
- if (mt & GDK_BUTTON1_MASK) {
- // The user is currently busy with an action. Defer invitation response processing
- // until the user is free.
- return true;
- }
-
- if (_invitation_responses.size() > 0) {
- Invitation_response_type response = _invitation_responses.front();
-
- switch (response.second) {
- case ACCEPT_INVITATION:
- {
- break;
- }
- case DECLINE_INVITATION:
- {
- Glib::ustring primary = String::ucompose(_("<span weight=\"bold\" size=\"larger\">The user <b>%1</b> has refused your whiteboard invitation.</span>\n\n"), response.first);
-
- // TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity.
- Glib::ustring secondary = String::ucompose(_("You are still connected to a Jabber server as <b>%2</b>, and may send an invitation to <b>%1</b> again, or you may send an invitation to a different user."), response.first, this->getClient().getJid());
-
- Gtk::MessageDialog dialog(primary + secondary, true, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, false);
- dialog.run();
- terminateInkboardSession(response.first);
- break;
- }
- case PEER_ALREADY_IN_SESSION:
- break;
-
- case UNSUPPORTED_PROTOCOL:
- {
- Glib::ustring primary = String::ucompose(_("<span weight=\"bold\" size=\"larger\">The user <b>%1</b> is using an incompatible version of Inkboard.</span>\n\n"), response.first);
-
- // TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity.
- Glib::ustring secondary = String::ucompose(_("Inkscape cannot connect to <b>%1</b>.\n\nYou are still connected to a Jabber server as <b>%2</b>."), response.first, this->getClient().getJid());
-
- Gtk::MessageDialog dialog(primary + secondary, true, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, false);
- dialog.run();
- terminateInkboardSession(response.first);
- break;
- }
- default:
- break;
- }
-
- _invitation_responses.pop_front();
- }
-
- return true;
-}
-
-}
-
-}
-
-/*
- 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 :
diff --git a/src/jabber_whiteboard/new-inkboard-document.cpp b/src/jabber_whiteboard/new-inkboard-document.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * new-inkboard-document.h
- * Functions to create new Inkboard documents, based off of sp_document_new /
- * sp_file_new
- *
- * Authors:
- * David Yip <yipdw@rose-hulman.edu>
- *
- * Copyright (c) 2006 Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <glib.h>
-#include <glibmm.h>
-#include <glibmm/i18n.h>
-
-#include "document.h"
-#include "document-private.h"
-#include "desktop.h"
-#include "desktop-handles.h"
-#include "interface.h"
-#include "sp-namedview.h"
-#include "desktop-handles.h"
-
-#include "gc-anchored.h"
-
-#include "ui/view/view-widget.h"
-
-#include "application/application.h"
-#include "application/editor.h"
-
-#include "util/ucompose.hpp"
-
-#include "xml/node.h"
-#include "xml/repr.h"
-
-#include "jabber_whiteboard/inkboard-document.h"
-#include "jabber_whiteboard/new-inkboard-document.h"
-
-namespace Inkscape {
-
-namespace Whiteboard {
-
-SPDocument*
-makeInkboardDocument(int code, gchar const* rootname, State::SessionType type, Glib::ustring const& to)
-{
- SPDocument* doc;
- InkboardDocument* rdoc = new InkboardDocument(g_quark_from_static_string("xml"), type, to);
- rdoc->setAttribute("version", "1.0");
- rdoc->setAttribute("standalone", "no");
- XML::Node *comment = sp_repr_new_comment(" Created with Inkscape (http://www.inkscape.org/) ");
- rdoc->appendChild(comment);
- GC::release(comment);
-
- XML::Node* root = sp_repr_new(rootname);
- rdoc->appendChild(root);
- GC::release(root);
-
- Glib::ustring name = String::ucompose(_("Inkboard session (%1 to %2)"), SessionManager::instance().getClient().getJid(), to);
-
- doc = sp_document_create(rdoc, NULL, NULL, name.c_str(), TRUE);
- return doc;
-}
-
-// TODO: When the switchover to the new GUI is complete, this function should go away
-// and be replaced with a call to Inkscape::NSApplication::Editor::createDesktop.
-// It currently only exists to correctly mimic the desktop creation functionality
-// in file.cpp.
-//
-// \see sp_file_new
-SPDesktop*
-makeInkboardDesktop(SPDocument* doc)
-{
- SPDesktop* dt;
-
- if (NSApplication::Application::getNewGui()) {
- dt = NSApplication::Editor::createDesktop(doc);
- } else {
- SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL));
- g_return_val_if_fail(dtw != NULL, NULL);
- sp_document_unref(doc);
-
- sp_create_window(dtw, TRUE);
- dt = static_cast<SPDesktop*>(dtw->view);
- sp_namedview_window_from_document(dt);
- }
-
- return dt;
-}
-
-}
-
-}
diff --git a/src/jabber_whiteboard/new-inkboard-document.h b/src/jabber_whiteboard/new-inkboard-document.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * new-inkboard-document.h
- * Functions to create new Inkboard documents, based off of sp_document_new /
- * sp_file_new
- *
- * Authors:
- * David Yip <yipdw@rose-hulman.edu>
- *
- * Copyright (c) 2006 Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifndef __INKSCAPE_WHITEBOARD_NEW_DOCUMENT_H__
-#define __INKSCAPE_WHITEBOARD_NEW_DOCUMENT_H__
-
-#include <glibmm.h>
-
-class SPDocument;
-class SPDesktop;
-
-namespace Inkscape {
-
-namespace Whiteboard {
-
-SPDocument* makeInkboardDocument(int code, gchar const* rootname, State::SessionType type, Glib::ustring const& to);
-SPDesktop* makeInkboardDesktop(SPDocument* doc);
-
-}
-
-}
-
-#endif
index fc58dc349b19ecaa57d2144109c0f10f3085a3b8..64578f9af0a1919d860cc6219158e2302ae338ee 100644 (file)
{
Inkscape::Whiteboard::SessionManager& sm =
Inkscape::Whiteboard::SessionManager::instance();
- sm.doShare(jid, Inkscape::Whiteboard::State::WHITEBOARD_PEER);
+ sm.initialiseSession(jid, Inkscape::Whiteboard::State::WHITEBOARD_PEER);
}
void PedroGui::doGroupShare(const DOMString &groupJid)
{
Inkscape::Whiteboard::SessionManager& sm =
Inkscape::Whiteboard::SessionManager::instance();
- sm.doShare(groupJid, Inkscape::Whiteboard::State::WHITEBOARD_MUC);
+ sm.initialiseSession(groupJid, Inkscape::Whiteboard::State::WHITEBOARD_MUC);
}
//##################
index 856db5fe79bce3ec4ead8a47811a757d0a79dbdb..dd392c845b4d18940f2bb274504eec50a6ff6d19 100644 (file)
#include <gtkmm.h>
#include <glibmm/i18n.h>
+#include "xml/node.h"
+#include "xml/repr.h"
+
+#include "util/ucompose.hpp"
+
#include "xml/node-observer.h"
#include "pedro/pedrodom.h"
+#include "ui/view/view-widget.h"
+
+#include "application/application.h"
+#include "application/editor.h"
+
+#include "document-private.h"
+#include "interface.h"
+#include "sp-namedview.h"
#include "document.h"
#include "desktop.h"
#include "desktop-handles.h"
+#include "jabber_whiteboard/invitation-confirm-dialog.h"
#include "jabber_whiteboard/message-verifier.h"
#include "jabber_whiteboard/session-manager.h"
#include "jabber_whiteboard/inkboard-document.h"
-#include "jabber_whiteboard/new-inkboard-document.h"
#include "jabber_whiteboard/defines.h"
#include "jabber_whiteboard/dialog/choose-desktop.h"
SessionManager::SessionManager()
{
- sequenceNumber = 0L;
getClient().addXmppEventListener(*this);
- this->_check_pending_invitations = Glib::signal_timeout().connect(sigc::mem_fun(*this, &SessionManager::_checkInvitationQueue), 50);
- this->_check_invitation_responses = Glib::signal_timeout().connect(sigc::mem_fun(*this, &SessionManager::_checkInvitationResponseQueue), 50);
+ this->CheckPendingInvitations =
+ Glib::signal_timeout().connect(sigc::mem_fun(
+ *this, &SessionManager::checkInvitationQueue), 50);
}
SessionManager::~SessionManager()
{
break;
}
+ case Pedro::XmppEvent::EVENT_MUC_MESSAGE:
case Pedro::XmppEvent::EVENT_MESSAGE:
{
g_warning("## SM message:%s\n", event.getFrom().c_str());
Pedro::Element *root = event.getDOM();
- if (root)
- {
- if (root->getTagAttribute("inkboard", "xmlns") == Vars::INKBOARD_XMLNS)
- {
- _processInkboardEvent(event);
- }
- }
+ if (root && root->getTagAttribute("wb", "xmlns") == Vars::INKBOARD_XMLNS)
+ processWhiteboardEvent(event);
+
break;
}
case Pedro::XmppEvent::EVENT_PRESENCE:
{
break;
}
- case Pedro::XmppEvent::EVENT_MUC_MESSAGE:
- {
- g_warning("## SM MUC message:%s\n", event.getFrom().c_str());
- Pedro::Element *root = event.getDOM();
-
- if (root)
- {
- if (root->getTagAttribute("inkboard", "xmlns") == Vars::INKBOARD_XMLNS)
- {
- _processInkboardEvent(event);
- }
- }
- break;
- }
case Pedro::XmppEvent::EVENT_MUC_JOIN:
{
break;
* \param type Type of the session; i.e. private message or group chat.
*/
void
-SessionManager::doShare(Glib::ustring const& to, State::SessionType type)
+SessionManager::initialiseSession(Glib::ustring const& to, State::SessionType type)
{
- SPDocument* doc = makeInkboardDocument(g_quark_from_static_string("xml"), "svg:svg", type, to);
- if(doc == NULL) return;
+ SPDocument* doc = makeInkboardDocument(g_quark_from_static_string("xml"), "svg:svg", type, to);
InkboardDocument* inkdoc = dynamic_cast< InkboardDocument* >(doc->rdoc);
- if (inkdoc == NULL) return;
-
+ if(inkdoc == NULL) return;
if(type == State::WHITEBOARD_PEER)
{
sp_desktop_document(desktop)->rdoc;
inkdoc->root()->mergeFrom(old_doc->root(),"id");
}
- }
- }else{ return; }
+ }else { return; }
+ }
- // Create a random session identifier
- char * randomString = (char*) malloc (11);
- for (int n=0; n<11; n++)
- randomString[n]=rand()%26+'a';
- randomString[11]='\0';
+ char * sessionId = createSessionId(10);
- inkdoc->setSessionIdent(randomString);
+ inkdoc->setSessionIdent(sessionId);
- _inkboards.push_back(Inkboard_record_type(randomString, inkdoc));
+ addSession(WhiteboardRecord(sessionId, inkdoc));
inkdoc->startSessionNegotiation();
- /*
- InkboardDocument* doc;
- SPDesktop* dt;
-
- // Just create a new blank canvas for MUC sessions
- if(type == State::WHITEBOARD_MUC)
- {
- dt = createInkboardDesktop(to, type);
-
- if (dt != NULL)
- {
- doc = dynamic_cast< InkboardDocument* >(sp_desktop_document(dt)->rdoc);
-
- if (doc != NULL)
- {
- doc->startSessionNegotiation();
- }
- }
-
-
- // Let the user pick the document which to start a peer ro peer session
- // with, or a blank one, then create a blank document, copy over the contents
- // and initialise session
- } else if (type== State::WHITEBOARD_PEER) {
- ChooseDesktop dialog;
- int result = dialog.run();
-
- if(result == Gtk::RESPONSE_OK)
- {
- SPDesktop *desktop = dialog.getDesktop();
- dt = createInkboardDesktop(to, type);
-
- if (dt != NULL)
- {
- doc = dynamic_cast< InkboardDocument* >(sp_desktop_document(dt)->rdoc);
-
- if (doc != NULL)
- {
- if(desktop != NULL)
- {
- Inkscape::XML::Document *old_doc =
- sp_desktop_document(desktop)->rdoc;
- doc->root()->mergeFrom(old_doc->root(),"id");
- }
-
- doc->startSessionNegotiation();
- }
- }
- }
- }
- */
-}
-
-/**
- * Clone of sp_file_new and all related subroutines and functions,
- * with appropriate modifications to use the Inkboard document class.
- *
- * \param to The JID to which this Inkboard document will be connected.
- * \return A pointer to the created desktop, or NULL if a new desktop could not be created.
- */
-SPDesktop*
-SessionManager::createInkboardDesktop(Glib::ustring const& to, State::SessionType type)
-{
-// Create document (sp_repr_document_new clone)
- SPDocument* doc = makeInkboardDocument(g_quark_from_static_string("xml"), "svg:svg", type, to);
- g_return_val_if_fail(doc != NULL, NULL);
-
- InkboardDocument* inkdoc = dynamic_cast< InkboardDocument* >(doc->rdoc);
- if (inkdoc == NULL) { // this shouldn't ever happen...
- return NULL;
- }
-
-// Create desktop and attach document
- SPDesktop *dt = makeInkboardDesktop(doc);
- _inkboards.push_back(Inkboard_record_type(to, inkdoc));
- return dt;
}
void
-SessionManager::terminateInkboardSession(Glib::ustring const& to)
+SessionManager::terminateSession(Glib::ustring const& sessionId)
{
- std::cout << "Terminating Inkboard session to " << to << std::endl;
- Inkboards_type::iterator i = _inkboards.begin();
- for(; i != _inkboards.end(); ++i) {
- if ((*i).first == to) {
+ WhiteboardList::iterator i = whiteboards.begin();
+ for(; i != whiteboards.end(); ++i) {
+ if ((*i).first == sessionId)
break;
- }
}
- if (i != _inkboards.end()) {
- std::cout << "Erasing Inkboard session to " << to << std::endl;
+ if (i != whiteboards.end()) {
(*i).second->terminateSession();
- _inkboards.erase(i);
+ whiteboards.erase(i);
}
}
+void
+SessionManager::addSession(WhiteboardRecord whiteboard)
+{
+ whiteboards.push_back(whiteboard);
+}
+
InkboardDocument*
-SessionManager::getInkboardSession(Glib::ustring const& to)
+SessionManager::getInkboardSession(Glib::ustring const& sessionId)
{
- Inkboards_type::iterator i = _inkboards.begin();
- for(; i != _inkboards.end(); ++i) {
- if ((*i).first == to) {
+ WhiteboardList::iterator i = whiteboards.begin();
+ for(; i != whiteboards.end(); ++i) {
+ if ((*i).first == sessionId) {
return (*i).second;
}
}
return NULL;
}
+
+/**
+ * Handles all incoming messages from pedro within a valid namespace, CONNECT_REQUEST messages
+ * are handled here, as they have no InkboardDocument to be handled from, all other messages
+ * are passed to their appropriate Inkboard document, which is identified by the 'session'
+ * attribute of the 'wb' element
+ *
+ */
void
-SessionManager::_processInkboardEvent(Pedro::XmppEvent const& event)
+SessionManager::processWhiteboardEvent(Pedro::XmppEvent const& event)
{
Pedro::Element* root = event.getDOM();
+ if (root == NULL) {
+ g_warning("Received null DOM; ignoring message.");
+ return;
+ }
- if (root == NULL) {
- g_warning("Received null DOM; ignoring message.");
- return;
- }
-
- Pedro::DOMString type = root->getTagAttribute("inkboard", "type");
- Pedro::DOMString seq = root->getTagAttribute("inkboard", "seq");
- Pedro::DOMString protover = root->getTagAttribute("inkboard", "protocol");
+ Pedro::DOMString session = root->getTagAttribute("wb", "session");
+ Pedro::DOMString domwrapper = root->getFirstChild()->getFirstChild()->getFirstChild()->getName();
- if (type.empty() || seq.empty() || protover.empty()) {
- g_warning("Received incomplete Inkboard message (missing type, protocol, or sequence number); ignoring message.");
+ if (session.empty()) {
+ g_warning("Received incomplete Whiteboard message, missing session identifier; ignoring message.");
return;
}
- MessageType mtype = static_cast< MessageType >(atoi(type.c_str()));
-
- // Messages that deal with the creation and destruction of sessions should be handled
- // here in the SessionManager.
- //
- // These events are listed below, along with rationale.
- //
- // - CONNECT_REQUEST_USER: when we begin to process this message, we will not have an
- // Inkboard session available to send the message to. Therefore, this message needs
- // to be handled by the SessionManager.
- //
- // - CONNECT_REQUEST_REFUSED_BY_PEER: this message means that the recipient of a
- // private invitation refused the invitation. In this case, we need to destroy the
- // Inkboard desktop, document, and session associated with that invitation.
- // Destruction of these components seems to be more naturally done in the SessionManager
- // than in the Inkboard document itself (especially since the document may be associated
- // with multiple desktops).
- //
- // - UNSUPPORTED_PROTOCOL_VERSION: this message means that the recipient of an invitation
- // does not support the version of the Inkboard protocol we are using. In this case,
- // we have to destroy the Inkboard desktop, document, and session associated with that
- // invitation. The rationale for doing it in the SessionManager is the same as that
- // given above.
- //
- // - ALREADY_IN_SESSION: similar rationale to above.
- //
- // - DISCONNECTED_FROM_USER_SIGNAL: similar rationale to above.
- //
- //
- // All other events can be handled inside an Inkboard session.
-
- // The message we are handling will have come from some Jabber ID. We need to verify
- // that the Inkboard session associated with that JID is in the correct state for the
- // incoming message (or, in some cases, that the session correctly exists / does not
- // exist).
- InkboardDocument* doc = getInkboardSession(event.getFrom());
-
-// NOTE: This line refers to a class that hasn't been written yet
-// MessageValidityTestResult res = MessageVerifier::verifyMessageValidity(event, mtype, doc);
-
- MessageValidityTestResult res = RESULT_INVALID;
- /*
- switch (res) {
- case RESULT_VALID:
- {
- switch (mtype) {
- case CONNECT_REQUEST:
- default:
- if (doc != NULL) {
- unsigned int seqnum = atoi(seq.c_str());
- doc->processInkboardEvent(mtype, seqnum, event.getData());
- }
- break;
- }
- break;
- }
- case RESULT_INVALID:
- default:
- // FIXME: better warning message
- g_warning("Received message in invalid context.");
- break;
- }
- */
+ if(root->exists(Message::CONNECT_REQUEST))
+ handleIncomingInvitation(Invitation(event.getFrom(),session));
+
+ else
+ {
+ Message::Wrapper wrapper = domwrapper.c_str();
+ InkboardDocument* doc = getInkboardSession(session);
+ doc->processInkboardEvent(wrapper, event.getData());
+ }
}
-void
-SessionManager::_handleSessionEvent(Message::Wrapper mtype, Pedro::XmppEvent const& event)
+char*
+SessionManager::createSessionId(int size)
{
- /*
- switch (mtype) {
- case CONNECT_REQUEST:
- _handleIncomingInvitation(event.getFrom());
- break;
- case INVITATION_DECLINE:
- _handleInvitationResponse(event.getFrom(), DECLINE_INVITATION);
- break;
- default:
- break;
- }
- */
+ // Create a random session identifier
+ char * randomString = (char*) malloc (size);
+ for (int n=0; n<size; n++)
+ randomString[n]=rand()%26+'a';
+ randomString[size+1]='\0';
+
+ return randomString;
}
+/**
+ * Adds an invitation to a queue to be executed in SessionManager::_checkInvitationQueue()
+ * as when this method is called, we're still executing in Pedro's context, which causes
+ * issues when we run a dialog main loop.
+ *
+ */
void
-SessionManager::_handleIncomingInvitation(Glib::ustring const& from)
+SessionManager::handleIncomingInvitation(Invitation invitation)
{
- // don't insert duplicate invitations
- if (std::find(_pending_invitations.begin(), _pending_invitations.end(), from) != _pending_invitations.end()) {
- return;
- }
-
- // We need to do the invitation confirm/deny dialog elsewhere --
- // when this method is called, we're still executing in Pedro's context,
- // which causes issues when we run a dialog main loop.
- //
- // The invitation handling is done in a poller timeout that executes approximately
- // every 50ms. It calls _checkInvitationQueue.
- _pending_invitations.push_back(from);
+ // don't insert duplicate invitations
+ if (std::find(invitations.begin(),invitations.end(),invitation) != invitations.end())
+ return;
+
+ invitations.push_back(invitation);
}
-void
-SessionManager::_handleInvitationResponse(Glib::ustring const& from, InvitationResponses resp)
+bool
+SessionManager::checkInvitationQueue()
+{
+ // The user is currently busy with an action. Defer invitation processing
+ // until the user is free.
+ int x, y;
+ Gdk::ModifierType mt;
+ Gdk::Display::get_default()->get_pointer(x, y, mt);
+ if (mt & GDK_BUTTON1_MASK)
+ return true;
+
+ if (invitations.size() > 0)
+ {
+ // There's an invitation to process; process it.
+ Invitation invitation = invitations.front();
+ Glib::ustring from = invitation.first;
+ Glib::ustring sessionId = invitation.second;
+
+ Glib::ustring primary =
+ "<span weight=\"bold\" size=\"larger\">" +
+ String::ucompose(_("<b>%1</b> has invited you to a whiteboard session."), from) +
+ "</span>\n\n" +
+ String::ucompose(_("Do you wish to accept <b>%1</b>'s whiteboard session invitation?"), from);
+
+ InvitationConfirmDialog dialog(primary);
+
+ dialog.add_button(_("Accept invitation"), Dialog::ACCEPT_INVITATION);
+ dialog.add_button(_("Decline invitation"), Dialog::DECLINE_INVITATION);
+
+ Dialog::DialogReply reply = static_cast< Dialog::DialogReply >(dialog.run());
+
+
+ SPDocument* doc = makeInkboardDocument(g_quark_from_static_string("xml"), "svg:svg", State::WHITEBOARD_PEER, from);
+ InkboardDocument* inkdoc = dynamic_cast< InkboardDocument* >(doc->rdoc);
+ if(inkdoc == NULL) return true;
+
+ addSession(WhiteboardRecord(sessionId, inkdoc));
+
+ switch (reply) {
+
+ case Dialog::ACCEPT_INVITATION:{
+ inkdoc->sendProtocol(from, Message::PROTOCOL,Message::ACCEPT_INVITATION);
+ makeInkboardDesktop(doc);
+ break; }
+
+ case Dialog::DECLINE_INVITATION: default: {
+ inkdoc->sendProtocol(from, Message::PROTOCOL,Message::DECLINE_INVITATION);
+ terminateSession(sessionId);
+ break; }
+ }
+
+ invitations.pop_front();
+
+ }
+
+ return true;
+}
+
+//#########################################################################
+//# HELPER FUNCTIONS
+//#########################################################################
+
+SPDocument*
+makeInkboardDocument(int code, gchar const* rootname, State::SessionType type, Glib::ustring const& to)
{
- // only handle one response per invitation sender
- //
- // TODO: this could have one huge bug: say that Alice sends an invite to Bob, but
- // Bob is doing something else at the moment and doesn't want to get in an Inkboard
- // session. Eve intercepts Bob's "reject invitation" message and passes a
- // "accept invitation" message to Alice that comes before Bob's "reject invitation"
- // message.
- //
- // Does XMPP prevent this sort of attack? Need to investigate that.
- if (std::find_if(_invitation_responses.begin(), _invitation_responses.end(), CheckInvitationSender(from)) != _invitation_responses.end()) {
- return;
- }
-
- // We need to do the invitation confirm/deny dialog elsewhere --
- // when this method is called, we're still executing in Pedro's context,
- // which causes issues when we run a dialog main loop.
- //
- // The invitation handling is done in a poller timeout that executes approximately
- // every 50ms. It calls _checkInvitationResponseQueue.
- _invitation_responses.push_back(Invitation_response_type(from, resp));
+ SPDocument* doc;
+
+ InkboardDocument* rdoc = new InkboardDocument(g_quark_from_static_string("xml"), type, to);
+ rdoc->setAttribute("version", "1.0");
+ rdoc->setAttribute("standalone", "no");
+ XML::Node *comment = sp_repr_new_comment(" Created with Inkscape (http://www.inkscape.org/) ");
+ rdoc->appendChild(comment);
+ GC::release(comment);
+
+ XML::Node* root = sp_repr_new(rootname);
+ rdoc->appendChild(root);
+ GC::release(root);
+
+ Glib::ustring name = String::ucompose(
+ _("Inkboard session (%1 to %2)"), SessionManager::instance().getClient().getJid(), to);
+ doc = sp_document_create(rdoc, NULL, NULL, name.c_str(), TRUE);
+ g_return_val_if_fail(doc != NULL, NULL);
+
+ return doc;
+}
+
+// TODO: When the switchover to the new GUI is complete, this function should go away
+// and be replaced with a call to Inkscape::NSApplication::Editor::createDesktop.
+// It currently only exists to correctly mimic the desktop creation functionality
+// in file.cpp.
+//
+// \see sp_file_new
+SPDesktop*
+makeInkboardDesktop(SPDocument* doc)
+{
+ SPDesktop* dt;
+
+ if (NSApplication::Application::getNewGui())
+ dt = NSApplication::Editor::createDesktop(doc);
+
+ else
+ {
+ SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL));
+ g_return_val_if_fail(dtw != NULL, NULL);
+ sp_document_unref(doc);
+
+ sp_create_window(dtw, TRUE);
+ dt = static_cast<SPDesktop*>(dtw->view);
+ sp_namedview_window_from_document(dt);
+ }
+
+ return dt;
}
} // namespace Whiteboard
index 18f6239bbf03acb3dc4e27a1676770a17f3ca922..1ba6266852c99318f7f74d6bc3774f66bdb89e13 100644 (file)
#include <list>
#include <bitset>
+#include "desktop.h"
+
#include "jabber_whiteboard/pedrogui.h"
#include "jabber_whiteboard/message-queue.h"
#include "jabber_whiteboard/defines.h"
#include "gc-alloc.h"
+class SPDocument;
class SPDesktop;
+
namespace Inkscape {
namespace Whiteboard {
-enum SessionType {
- INKBOARD_PRIVATE,
- INKBOARD_MUC
-};
-
-class SessionManager;
class InkboardDocument;
-class SessionManager : public Pedro::XmppEventListener {
+typedef Glib::ustring from,sessionId;
+typedef std::pair< Glib::ustring, InkboardDocument* > WhiteboardRecord;
+typedef std::vector< WhiteboardRecord, GC::Alloc< WhiteboardRecord, GC::MANUAL > > WhiteboardList;
+
+typedef std::pair< from, sessionId > Invitation;
+typedef std::list< Invitation > InvitationList;
+
+class SessionManager : public Pedro::XmppEventListener
+{
+
public:
- /**
- *
- */
SessionManager();
- /**
- *
- */
virtual ~SessionManager();
- static void showClient();
- static SessionManager& instance();
+ static void showClient();
+ static SessionManager& instance();
- /**
- *
- */
virtual Pedro::XmppClient &getClient()
{ return gui.client; }
/**
- *
+ * Handles all incoming XMPP events associated with this document
+ * apart from CONNECT_REQUEST, which is handled in SessionManager
*/
virtual void processXmppEvent(const Pedro::XmppEvent &event);
- /**
- * The session handling has been broken out into a subclass of XML::Session. See
- * Whiteboard::InkboardSession and Whiteboard::InkboardDocument, both of which
- * are still under heavy construction. Don't expect them to work just yet.
- *
- * This (should) allow us to substitute an InkboardDocument for an
- * XML::SimpleDocument (InkboardDocument uses InkboardSession), which, I think, should
- * lead to a very clean way of integrating Inkboard. It should also
- * give us a cleaner way of handling node tracking. Finally,
- * it'll let us experiment with data models that may be more appropriate for Inkboard.
- *
- * SessionManager still manages sessions insofar as it receives XMPP data from Pedro and
- * sends it off to the correct InkboardSession. I'd like to have it still manage
- * user sessions, which is what the user sees; however, that can be confusing from
- * a programmer's standpoint. This class might therefore need to be renamed
- * or something.
- *
- * Creation of an Inkboard session should be handled in some fashion similar
- * to this:
- *
- * (1) The user chooses a chat room or user with which she wants to share a whiteboard.
- *
- * (2) This invokes the appropriate doShare() method in Pedro's GUI.
- *
- * (3) doShare() invokes code to create a new Inkscape desktop with a blank document.
- * This desktop will use InkboardDocument (and hence InkboardSession) for transaction
- * management.
- *
- * (4) Inkboard setup and operation proceeds as it did in the Loudmouth-based code.
- *
- * (3) and (4) will probably need tweaking (for example, it's probably a bad idea to
- * open up a new desktop if an invitation is refused). Actually, really, nothing
- * here is set in stone. Feel free to modify. -- dwyip 2005-11-21
- *
- */
/**
* Initiates a shared session with a user or conference room.
* \param to The recipient to which this desktop will be linked, specified as a JID.
* \param type Type of the session; i.e. private message or group chat.
*/
- virtual void doShare(Glib::ustring const& to, State::SessionType type);
+ virtual void initialiseSession(Glib::ustring const& to, State::SessionType type);
/**
- * Creates a new desktop with an InkboardDocument.
- *
- * An InkboardDocument (and hence desktop)
- * is identified by the recipient of the document, be it a
- * conference room or another user. If an existing document is found, it will be
- * returned.
+ * Terminates an Inkboard session to a given recipient. If the session to be
+ * terminated does not exist, does nothing.
*
- * \param to The recipient to which this desktop will be linked, specified as a JID.
- * \param type Type of the session; i.e. private message or group chat.
- * \return A pointer to the created SPDesktop.
+ * \param sessionId The session identifier to be terminated.
*/
- virtual SPDesktop* createInkboardDesktop(Glib::ustring const& to, State::SessionType type);
+ virtual void terminateSession(Glib::ustring const& sessionId);
/**
- * Terminates an Inkboard session to a given recipient. If the session to be
- * terminated does not exist, does nothing.
+ * Adds a session to whiteboard
*
- * \param to The recipient JID identifying the session to be terminated.
+ * \param sessionId The session identifier to be terminated.
*/
- virtual void terminateInkboardSession(Glib::ustring const& to);
+ virtual void addSession(WhiteboardRecord whiteboard);
/**
* Locates an Inkboard session by recipient JID.
*/
InkboardDocument* getInkboardSession(Glib::ustring const& to);
- void operator=(XmppEventListener const& other) {
- }
+ void operator=(XmppEventListener const& other) {}
+
private:
-
- // types
- typedef std::pair< Glib::ustring, InkboardDocument* > Inkboard_record_type;
- typedef std::vector< Inkboard_record_type, GC::Alloc< Inkboard_record_type, GC::MANUAL > > Inkboards_type;
-
- typedef std::list< Glib::ustring > Pending_invitations_type;
-
- typedef std::pair< Glib::ustring, InvitationResponses > Invitation_response_type;
- typedef std::list< Invitation_response_type > Invitation_responses_type;
-
- // functors
- struct CheckInvitationSender {
- public:
- CheckInvitationSender(Glib::ustring const& x) : x(x) { }
- ~CheckInvitationSender() { }
-
- bool operator()(SessionManager::Invitation_response_type const& y) const {
- return (x == y.first);
- }
- private:
- Glib::ustring const& x;
- };
-
- // objects
- Pedro::PedroGui gui;
- SendMessageQueue sendMessageQueue;
- ReceiveMessageQueue receiveMessageQueue;
-
- // members
- unsigned long sequenceNumber;
- Inkboards_type _inkboards;
- Pending_invitations_type _pending_invitations;
- Invitation_responses_type _invitation_responses;
-
- sigc::connection _check_pending_invitations;
- sigc::connection _check_invitation_responses;
-
- // methods
- void _processInkboardEvent(Pedro::XmppEvent const& event);
- void _handleSessionEvent(Message::Wrapper mtype, Pedro::XmppEvent const& event);
- void _handleIncomingInvitation(Glib::ustring const& from);
- void _handleInvitationResponse(Glib::ustring const& from, InvitationResponses resp);
-
- // methods handled externally
- bool _checkInvitationQueue();
- bool _checkInvitationResponseQueue();
+
+ Pedro::PedroGui gui;
+ WhiteboardList whiteboards;
+ InvitationList invitations;
+ sigc::connection CheckPendingInvitations;
+
+ void processWhiteboardEvent(Pedro::XmppEvent const& event);
+
+ void handleIncomingInvitation(Invitation invitation);
+
+ bool checkInvitationQueue();
+
+ char* createSessionId(int size);
+
};
+SPDocument* makeInkboardDocument(int code, gchar const* rootname, State::SessionType type, Glib::ustring const& to);
+SPDesktop* makeInkboardDesktop(SPDocument* doc);
+
} // namespace Whiteboard
} // namespace Inkscape