summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp4
-rw-r--r--Swift/Controllers/Chat/ChatController.h1
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp14
-rw-r--r--Swift/Controllers/Chat/ChatsManager.h5
-rw-r--r--Swift/Controllers/MainController.cpp2
-rw-r--r--Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h24
-rw-r--r--Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h24
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h2
-rw-r--r--Swift/Controllers/WhiteboardManager.cpp48
-rw-r--r--Swift/Controllers/WhiteboardManager.h6
-rw-r--r--Swift/QtUI/QtChatWindow.cpp34
-rw-r--r--Swift/QtUI/QtChatWindow.h4
-rw-r--r--Swiften/Elements/WhiteboardPayload.h15
-rw-r--r--Swiften/Parser/PayloadParsers/WhiteboardParser.cpp11
-rw-r--r--Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h3
-rw-r--r--Swiften/Whiteboard/WhiteboardResponder.cpp25
-rw-r--r--Swiften/Whiteboard/WhiteboardResponder.h2
-rw-r--r--Swiften/Whiteboard/WhiteboardSession.cpp17
-rw-r--r--Swiften/Whiteboard/WhiteboardSession.h6
-rw-r--r--Swiften/Whiteboard/WhiteboardSessionManager.cpp36
-rw-r--r--Swiften/Whiteboard/WhiteboardSessionManager.h12
21 files changed, 266 insertions, 29 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index 2fa4559..12d3814 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -255,6 +255,10 @@ void ChatController::handleNewFileTransferController(FileTransferController* ftc
ftControllers[ftID] = ftc;
}
+void ChatController::handleIncomingWhiteboardSession() {
+ chatWindow_->addWhiteboardRequest(toJID_);
+}
+
void ChatController::handleFileTransferCancel(std::string id) {
SWIFT_LOG(debug) << "handleFileTransferCancel(" << id << ")" << std::endl;
if (ftControllers.find(id) != ftControllers.end()) {
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index 7043231..561bbf4 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -29,6 +29,7 @@ namespace Swift {
virtual void setToJID(const JID& jid);
virtual void setOnline(bool online);
virtual void handleNewFileTransferController(FileTransferController* ftc);
+ virtual void handleIncomingWhiteboardSession();
virtual void setContactIsReceivingPresence(bool /*isReceivingPresence*/);
protected:
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index da96603..380b3ae 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -42,6 +42,7 @@
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swiften/Client/StanzaChannel.h>
+#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
namespace Swift {
@@ -71,7 +72,8 @@ ChatsManager::ChatsManager(
FileTransferOverview* ftOverview,
XMPPRoster* roster,
bool eagleMode,
- SettingsProvider* settings) :
+ SettingsProvider* settings,
+ WhiteboardSessionManager* whiteboardSessionManager) :
jid_(jid),
joinMUCWindowFactory_(joinMUCWindowFactory),
useDelayForLatency_(useDelayForLatency),
@@ -81,7 +83,8 @@ ChatsManager::ChatsManager(
ftOverview_(ftOverview),
roster_(roster),
eagleMode_(eagleMode),
- settings_(settings) {
+ settings_(settings),
+ whiteboardSessionManager_(whiteboardSessionManager) {
timerFactory_ = timerFactory;
eventController_ = eventController;
stanzaChannel_ = stanzaChannel;
@@ -107,6 +110,7 @@ ChatsManager::ChatsManager(
mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, profileSettings_);
mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1));
ftOverview_->onNewFileTransferController.connect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1));
+ whiteboardSessionManager_->onRequestReceived.connect(boost::bind(&ChatsManager::handleIncomingWhiteboardSession, this, _1));
roster_->onJIDAdded.connect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1));
roster_->onJIDRemoved.connect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1));
roster_->onJIDUpdated.connect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1));
@@ -655,6 +659,12 @@ void ChatsManager::handleNewFileTransferController(FileTransferController* ftc)
chatController->activateChatWindow();
}
+void ChatsManager::handleIncomingWhiteboardSession(const JID& from) {
+ ChatController* chatController = getChatControllerOrCreate(from);
+ chatController->handleIncomingWhiteboardSession();
+ chatController->activateChatWindow();
+}
+
void ChatsManager::handleRecentActivated(const ChatListWindow::Chat& chat) {
if (chat.isMUC) {
/* FIXME: This means that recents requiring passwords will just flat-out not work */
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index a8c69c4..3fcd3fb 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -47,10 +47,11 @@ namespace Swift {
class FileTransferController;
class XMPPRoster;
class SettingsProvider;
+ class WhiteboardSessionManager;
class ChatsManager {
public:
- ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings);
+ ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, WhiteboardSessionManager* whiteboardSessionManager);
virtual ~ChatsManager();
void setAvatarManager(AvatarManager* avatarManager);
void setOnline(bool enabled);
@@ -72,6 +73,7 @@ namespace Swift {
void handleBookmarksReady();
void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC);
void handleNewFileTransferController(FileTransferController*);
+ void handleIncomingWhiteboardSession(const JID& from);
void appendRecent(const ChatListWindow::Chat& chat);
void prependRecent(const ChatListWindow::Chat& chat);
void setupBookmarks();
@@ -129,5 +131,6 @@ namespace Swift {
bool eagleMode_;
bool userWantsReceipts_;
SettingsProvider* settings_;
+ WhiteboardSessionManager* whiteboardSessionManager_;
};
}
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index bcced6d..e866102 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -293,7 +293,7 @@ void MainController::handleConnected() {
contactEditController_ = new ContactEditController(rosterController_, client_->getVCardManager(), uiFactory_, uiEventStream_);
- chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_);
+ chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, client_->getWhiteboardSessionManager());
client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
chatsManager_->setAvatarManager(client_->getAvatarManager());
diff --git a/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h b/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h
new file mode 100644
index 0000000..93cad03
--- /dev/null
+++ b/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 Mateusz Piękos
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+namespace Swift {
+ class AcceptWhiteboardSessionUIEvent : public UIEvent {
+ typedef boost::shared_ptr<AcceptWhiteboardSessionUIEvent> ref;
+ public:
+ AcceptWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {}
+ const JID& getContact() const {return jid_;}
+ private:
+ JID jid_;
+ };
+}
diff --git a/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h b/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h
new file mode 100644
index 0000000..f5c3b0e
--- /dev/null
+++ b/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 Mateusz Piękos
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+namespace Swift {
+ class CancelWhiteboardSessionUIEvent : public UIEvent {
+ typedef boost::shared_ptr<CancelWhiteboardSessionUIEvent> ref;
+ public:
+ CancelWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {}
+ const JID& getContact() const {return jid_;}
+ private:
+ JID jid_;
+ };
+}
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index b5b1604..66cc8c3 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -59,6 +59,8 @@ namespace Swift {
virtual void setFileTransferStatus(std::string, const FileTransferState state, const std::string& msg = "") = 0;
virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true) = 0;
+ virtual void addWhiteboardRequest(const JID& from) = 0;
+
// message receipts
virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) = 0;
diff --git a/Swift/Controllers/WhiteboardManager.cpp b/Swift/Controllers/WhiteboardManager.cpp
index 25a661c..37c3263 100644
--- a/Swift/Controllers/WhiteboardManager.cpp
+++ b/Swift/Controllers/WhiteboardManager.cpp
@@ -10,6 +10,8 @@
#include <Swiften/Base/foreach.h>
#include <Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h>
+#include <Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h>
+#include <Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
@@ -18,6 +20,7 @@ namespace Swift {
WhiteboardManager::WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, WhiteboardSessionManager* whiteboardSessionManager) : whiteboardWindowFactory_(whiteboardWindowFactory), uiEventStream_(uiEventStream), whiteboardSessionManager_(whiteboardSessionManager) {
uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&WhiteboardManager::handleUIEvent, this, _1));
+ whiteboardSessionManager_->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleAcceptedRequest, this, _1, _2));
}
WhiteboardManager::~WhiteboardManager() {
@@ -26,25 +29,48 @@ namespace Swift {
}
}
- WhiteboardWindow* WhiteboardManager::getWhiteboardWindowOrCreate(const JID& contact) {
- if (whiteboardWindows_.find(contact) == whiteboardWindows_.end()) {
- return createNewWhiteboardWindow(contact);
- }
- return whiteboardWindows_[contact];
- }
-
- WhiteboardWindow* WhiteboardManager::createNewWhiteboardWindow(const JID& contact) {
- WhiteboardSession* session = whiteboardSessionManager_->createSession(contact);
+ WhiteboardWindow* WhiteboardManager::createNewWhiteboardWindow(const JID& contact, WhiteboardSession* session) {
WhiteboardWindow *window = whiteboardWindowFactory_->createWhiteboardWindow(session);
whiteboardWindows_[contact] = window;
return window;
}
+ WhiteboardWindow* WhiteboardManager::findWhiteboardWindow(const JID& contact) {
+ if (whiteboardWindows_.find(contact) == whiteboardWindows_.end()) {
+ return NULL;
+ }
+ return whiteboardWindows_[contact];
+ }
+
void WhiteboardManager::handleUIEvent(boost::shared_ptr<UIEvent> event) {
boost::shared_ptr<RequestWhiteboardUIEvent> whiteboardEvent = boost::dynamic_pointer_cast<RequestWhiteboardUIEvent>(event);
if (whiteboardEvent) {
- WhiteboardWindow* window = getWhiteboardWindowOrCreate(whiteboardEvent->getContact());
- window->show();
+ whiteboardSessionManager_->requestSession(whiteboardEvent->getContact());
+ }
+ boost::shared_ptr<AcceptWhiteboardSessionUIEvent> sessionAcceptEvent = boost::dynamic_pointer_cast<AcceptWhiteboardSessionUIEvent>(event);
+ if (sessionAcceptEvent) {
+ acceptSession(sessionAcceptEvent->getContact());
+ }
+ boost::shared_ptr<CancelWhiteboardSessionUIEvent> sessionCancelEvent = boost::dynamic_pointer_cast<CancelWhiteboardSessionUIEvent>(event);
+ if (sessionCancelEvent) {
+ whiteboardSessionManager_->cancelSession(sessionCancelEvent->getContact());
+ }
+ }
+
+ void WhiteboardManager::acceptSession(const JID& from) {
+ WhiteboardSession* session = whiteboardSessionManager_->acceptSession(from);
+ WhiteboardWindow* window = findWhiteboardWindow(from);
+ if (window == NULL) {
+ window = createNewWhiteboardWindow(from, session);
+ }
+ window->show();
+ }
+
+ void WhiteboardManager::handleAcceptedRequest(const JID& from, WhiteboardSession* session) {
+ WhiteboardWindow* window = findWhiteboardWindow(from);
+ if (window == NULL) {
+ window = createNewWhiteboardWindow(from, session);
}
+ window->show();
}
}
diff --git a/Swift/Controllers/WhiteboardManager.h b/Swift/Controllers/WhiteboardManager.h
index 8257f73..2690f36 100644
--- a/Swift/Controllers/WhiteboardManager.h
+++ b/Swift/Controllers/WhiteboardManager.h
@@ -25,11 +25,13 @@ namespace Swift {
WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, WhiteboardSessionManager* whiteboardSessionManager);
~WhiteboardManager();
- WhiteboardWindow* getWhiteboardWindowOrCreate(const JID& contact);
- WhiteboardWindow* createNewWhiteboardWindow(const JID& contact);
+ WhiteboardWindow* createNewWhiteboardWindow(const JID& contact, WhiteboardSession* session);
private:
void handleUIEvent(boost::shared_ptr<UIEvent> event);
+ void acceptSession(const JID& from);
+ void handleAcceptedRequest(const JID& from, WhiteboardSession* session);
+ WhiteboardWindow* findWhiteboardWindow(const JID& contact);
private:
std::map<JID, WhiteboardWindow*> whiteboardWindows_;
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 52ce701..b1ee3a8 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -23,6 +23,8 @@
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h>
+#include <Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h>
#include "QtChatWindowJSBridge.h"
#include <boost/cstdint.hpp>
@@ -52,6 +54,8 @@
namespace Swift {
+const QString QtChatWindow::ButtonWhiteboardSessionCancel = QString("whiteboard-cancel");
+const QString QtChatWindow::ButtonWhiteboardSessionAcceptRequest = QString("whiteboard-acceptrequest");
const QString QtChatWindow::ButtonFileTransferCancel = QString("filetransfer-cancel");
const QString QtChatWindow::ButtonFileTransferSetDescription = QString("filetransfer-setdescription");
const QString QtChatWindow::ButtonFileTransferSendRequest = QString("filetransfer-sendrequest");
@@ -593,6 +597,28 @@ void QtChatWindow::setFileTransferStatus(std::string id, const FileTransferState
messageLog_->setFileTransferStatus(QString::fromStdString(id), state, QString::fromStdString(msg));
}
+void QtChatWindow::addWhiteboardRequest(const JID& from) {
+ QString id = QString("wb%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
+ QString htmlString = Qt::escape(contact_) + tr(" would like to start whiteboard session") + ": <br/>" +
+ "<div id='" + id + "'>" +
+ buildChatWindowButton(tr("Cancel"), ButtonWhiteboardSessionCancel, P2QSTRING(from.toString())) +
+ buildChatWindowButton(tr("Accept"), ButtonWhiteboardSessionAcceptRequest, P2QSTRING(from.toString())) +
+ "</div>";
+
+ if (lastLineTracker_.getShouldMoveLastLine()) {
+ /* should this be queued? */
+ messageLog_->addLastSeenLine();
+ /* if the line is added we should break the snippet */
+// appendToPrevious = false;
+ }
+ QString qAvatarPath = "qrc:/icons/avatar.png";
+
+ messageLog_->addMessage(boost::shared_ptr<ChatSnippet>(new MessageSnippet(htmlString, Qt::escape(contact_), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, false, false, theme_, id)));
+
+ previousMessageWasSelf_ = false;
+ previousSenderName_ = contact_;
+}
+
void QtChatWindow::handleHTMLButtonClicked(QString id, QString encodedArgument1, QString encodedArgument2, QString encodedArgument3) {
QString arg1 = decodeButtonArgument(encodedArgument1);
QString arg2 = decodeButtonArgument(encodedArgument2);
@@ -625,6 +651,14 @@ void QtChatWindow::handleHTMLButtonClicked(QString id, QString encodedArgument1,
onFileTransferAccept(Q2PSTRING(ft_id), Q2PSTRING(path));
}
}
+ else if (id.startsWith(ButtonWhiteboardSessionAcceptRequest)) {
+ QString fromJID = arg1;
+ eventStream_->send(boost::make_shared<AcceptWhiteboardSessionUIEvent>(Q2PSTRING(fromJID)));
+ }
+ else if (id.startsWith(ButtonWhiteboardSessionCancel)) {
+ QString fromJID = arg1;
+ eventStream_->send(boost::make_shared<CancelWhiteboardSessionUIEvent>(Q2PSTRING(fromJID)));
+ }
else if (id.startsWith(ButtonMUCInvite)) {
QString roomJID = arg1;
QString password = arg2;
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index 4b888eb..bf30078 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -39,6 +39,8 @@ namespace Swift {
Q_OBJECT
public:
+ static const QString ButtonWhiteboardSessionCancel;
+ static const QString ButtonWhiteboardSessionAcceptRequest;
static const QString ButtonFileTransferCancel;
static const QString ButtonFileTransferSetDescription;
static const QString ButtonFileTransferSendRequest;
@@ -60,6 +62,8 @@ namespace Swift {
void setFileTransferProgress(std::string id, const int percentageDone);
void setFileTransferStatus(std::string id, const FileTransferState state, const std::string& msg);
+ void addWhiteboardRequest(const JID& from);
+
void show();
void activate();
void setUnreadMessageCount(int count);
diff --git a/Swiften/Elements/WhiteboardPayload.h b/Swiften/Elements/WhiteboardPayload.h
index 8d40d9d..db261ca 100644
--- a/Swiften/Elements/WhiteboardPayload.h
+++ b/Swiften/Elements/WhiteboardPayload.h
@@ -13,7 +13,11 @@
namespace Swift {
class WhiteboardPayload : public Payload {
public:
- WhiteboardPayload() {
+ typedef boost::shared_ptr<WhiteboardPayload> ref;
+
+ enum Type {Data, SessionRequest};
+
+ WhiteboardPayload(Type type = WhiteboardPayload::Data) : type_(type) {
}
void setData(const std::string &data) {
@@ -24,7 +28,16 @@ namespace Swift {
return data_;
}
+ Type getType() const {
+ return type_;
+ }
+
+ void setType(Type type) {
+ type_ = type;
+ }
+
private:
std::string data_;
+ Type type_;
};
}
diff --git a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
index 77e5c2c..94b67e5 100644
--- a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
+++ b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
@@ -10,12 +10,21 @@ namespace Swift {
WhiteboardParser::WhiteboardParser() : level_(0) {
}
void WhiteboardParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) {
+ if (level_ == 0) {
+ std::string type = attributes.getAttribute("type");
+ if (type.empty()) {
+ getPayloadInternal()->setType(WhiteboardPayload::Data);
+ }
+ else if (type == "request") {
+ getPayloadInternal()->setType(WhiteboardPayload::SessionRequest);
+ }
+ }
++level_;
}
void WhiteboardParser::handleEndElement(const std::string& element, const std::string&) {
--level_;
- if(level_ == 0) {
+ if (level_ == 0) {
getPayloadInternal()->setData(data_);
}
}
diff --git a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
index a7d04f1..9b7f905 100644
--- a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
+++ b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
@@ -15,6 +15,9 @@ namespace Swift {
std::string serializePayload(boost::shared_ptr<WhiteboardPayload> payload) const {
XMLElement element("wb");
element.addNode(XMLTextNode::ref(new XMLTextNode(payload->getData())));
+ if (payload->getType() == WhiteboardPayload::SessionRequest) {
+ element.setAttribute("type", "request");
+ }
return element.serialize();
}
};
diff --git a/Swiften/Whiteboard/WhiteboardResponder.cpp b/Swiften/Whiteboard/WhiteboardResponder.cpp
index 2e4905a..8a1b290 100644
--- a/Swiften/Whiteboard/WhiteboardResponder.cpp
+++ b/Swiften/Whiteboard/WhiteboardResponder.cpp
@@ -15,11 +15,28 @@ namespace Swift {
}
bool WhiteboardResponder::handleSetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<WhiteboardPayload> payload) {
- sendResponse(from, id, boost::shared_ptr<WhiteboardPayload>());
- WhiteboardSession* session = sessionManager_->getSession(from.toBare());
- if (session != NULL) {
- session->handleIncomingAction(payload);
+ if (payload->getType() == WhiteboardPayload::SessionRequest) {
+ sessionManager_->onRequestReceived(from);
+ sessionRequests_[from] = id;
+ } else {
+ sendResponse(from, id, boost::shared_ptr<WhiteboardPayload>());
+ WhiteboardSession* session = sessionManager_->getSession(from.toBare());
+ if (session != NULL) {
+ session->handleIncomingAction(payload);
+ }
}
return true;
}
+
+ void WhiteboardResponder::sendRequestResponse(const JID& contact, bool accepted) {
+ if (sessionRequests_.find(contact) == sessionRequests_.end()) {
+ return;
+ }
+ if (accepted ) {
+ sendResponse(contact, sessionRequests_[contact], boost::shared_ptr<WhiteboardPayload>());
+ } else {
+ sendError(contact, sessionRequests_[contact], ErrorPayload::Conflict, ErrorPayload::Cancel);
+ }
+ sessionRequests_.erase(contact);
+ }
}
diff --git a/Swiften/Whiteboard/WhiteboardResponder.h b/Swiften/Whiteboard/WhiteboardResponder.h
index b171ef3..d1b712d 100644
--- a/Swiften/Whiteboard/WhiteboardResponder.h
+++ b/Swiften/Whiteboard/WhiteboardResponder.h
@@ -17,8 +17,10 @@ namespace Swift {
public:
WhiteboardResponder(WhiteboardSessionManager* sessionManager, IQRouter* router);
bool handleSetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<WhiteboardPayload> payload);
+ void sendRequestResponse(const JID& contact, bool accepted);
private:
+ std::map<JID, std::string> sessionRequests_;
WhiteboardSessionManager* sessionManager_;
IQRouter* router_;
};
diff --git a/Swiften/Whiteboard/WhiteboardSession.cpp b/Swiften/Whiteboard/WhiteboardSession.cpp
index 7d95af0..859f2cd 100644
--- a/Swiften/Whiteboard/WhiteboardSession.cpp
+++ b/Swiften/Whiteboard/WhiteboardSession.cpp
@@ -6,9 +6,10 @@
#include <Swiften/Whiteboard/WhiteboardSession.h>
+#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Elements/WhiteboardPayload.h>
-#include <Swiften/Queries/GenericRequest.h>
+#include <Swiften/Elements/ErrorPayload.h>
#include <iostream>
@@ -26,4 +27,18 @@ namespace Swift {
boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_);
request->send();
}
+
+ void WhiteboardSession::sendSessionRequest() {
+ boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(WhiteboardPayload::SessionRequest);
+ sessionRequest = new GenericRequest<WhiteboardPayload>(IQ::Set, toJID_, payload, router_);
+ sessionRequest->onResponse.connect(boost::bind(&WhiteboardSession::handleSessionRequestResponse, this, _1, _2));
+ sessionRequest->send();
+ }
+
+ void WhiteboardSession::handleSessionRequestResponse(boost::shared_ptr<WhiteboardPayload> whiteboardPayload, boost::shared_ptr<ErrorPayload> errorPayload) {
+ if (errorPayload.get() == 0) {
+ onRequestAccepted(toJID_, this);
+ }
+ delete sessionRequest;
+ }
}
diff --git a/Swiften/Whiteboard/WhiteboardSession.h b/Swiften/Whiteboard/WhiteboardSession.h
index c36e729..14d6778 100644
--- a/Swiften/Whiteboard/WhiteboardSession.h
+++ b/Swiften/Whiteboard/WhiteboardSession.h
@@ -10,9 +10,11 @@
#include <Swiften/JID/JID.h>
#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Queries/GenericRequest.h>
namespace Swift {
class IQRouter;
+ class ErrorPayload;
class WhiteboardPayload;
class WhiteboardSession {
@@ -20,12 +22,16 @@ namespace Swift {
WhiteboardSession(const JID& jid, IQRouter* router);
void handleIncomingAction(boost::shared_ptr<WhiteboardPayload> payload);
void sendData(const std::string& data);
+ void sendSessionRequest();
+ void handleSessionRequestResponse(boost::shared_ptr<WhiteboardPayload> whiteboardPayload, boost::shared_ptr<ErrorPayload> errorPayload);
public:
boost::signal< void(const std::string& data)> onDataReceived;
+ boost::signal< void(const JID& contact, WhiteboardSession* session)> onRequestAccepted;
private:
JID toJID_;
IQRouter* router_;
+ GenericRequest<WhiteboardPayload>* sessionRequest;
};
}
diff --git a/Swiften/Whiteboard/WhiteboardSessionManager.cpp b/Swiften/Whiteboard/WhiteboardSessionManager.cpp
index 3b82cda..ccbc4d7 100644
--- a/Swiften/Whiteboard/WhiteboardSessionManager.cpp
+++ b/Swiften/Whiteboard/WhiteboardSessionManager.cpp
@@ -7,6 +7,7 @@
#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
+#include <boost/bind.hpp>
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/Whiteboard/WhiteboardSession.h>
#include <Swiften/Whiteboard/WhiteboardResponder.h>
@@ -24,18 +25,45 @@ namespace Swift {
}
WhiteboardSession* WhiteboardSessionManager::getSession(const JID& to) {
- if (sessions_.find(to) == sessions_.end()) {
+ if (sessions_.find(to.toBare()) == sessions_.end()) {
return NULL;
}
- return sessions_[to];
+ return sessions_[to.toBare()];
}
WhiteboardSession* WhiteboardSessionManager::createSession(const JID& to) {
- WhiteboardSession* session = new WhiteboardSession(getFullJID(to), router_);
- sessions_[to] = session;
+ JID fullJID = to;
+ if (fullJID.isBare()) {
+ fullJID = getFullJID(fullJID);
+ }
+ WhiteboardSession* session = new WhiteboardSession(fullJID, router_);
+ sessions_[to.toBare()] = session;
+ return session;
+ }
+
+ WhiteboardSession* WhiteboardSessionManager::acceptSession(const JID& to) {
+ responder->sendRequestResponse(to, true);
+ WhiteboardSession* session = getSession(to);
+ if (session == NULL) {
+ return createSession(to);
+ }
return session;
}
+ void WhiteboardSessionManager::requestSession(const JID& to) {
+ WhiteboardSession* session = createSession(to);
+ session->onRequestAccepted.connect(boost::bind(&WhiteboardSessionManager::handleRequestAccepted, this, _1, _2));
+ session->sendSessionRequest();
+ }
+
+ void WhiteboardSessionManager::cancelSession(const JID& to) {
+ responder->sendRequestResponse(to, false);
+ }
+
+ void WhiteboardSessionManager::handleRequestAccepted(const JID& contact, WhiteboardSession* session) {
+ onRequestAccepted(contact, session);
+ }
+
JID WhiteboardSessionManager::getFullJID(const JID& bareJID) {
std::vector<Presence::ref> presences = presenceOracle_->getAllPresence(bareJID);
return presences[0]->getFrom();
diff --git a/Swiften/Whiteboard/WhiteboardSessionManager.h b/Swiften/Whiteboard/WhiteboardSessionManager.h
index 93d2f19..3cd3aab 100644
--- a/Swiften/Whiteboard/WhiteboardSessionManager.h
+++ b/Swiften/Whiteboard/WhiteboardSessionManager.h
@@ -10,6 +10,7 @@
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/JID/JID.h>
+#include <Swiften/Base/boost_bsignals.h>
namespace Swift {
class IQRouter;
@@ -23,9 +24,18 @@ namespace Swift {
~WhiteboardSessionManager();
WhiteboardSession* getSession(const JID& to);
- WhiteboardSession* createSession(const JID& to);
+ WhiteboardSession* acceptSession(const JID& to);
+ void requestSession(const JID& to);
+ void cancelSession(const JID& to);
+ void handleRequestAccepted(const JID& contact, WhiteboardSession* session);
+
+ public:
+ boost::signal< void (const JID&)> onRequestReceived;
+ boost::signal< void (const JID&, WhiteboardSession*)> onRequestAccepted;
+
private:
JID getFullJID(const JID& bareJID);
+ WhiteboardSession* createSession(const JID& to);
private:
std::map<JID, WhiteboardSession*> sessions_;