diff options
author | Mateusz Piekos <mateuszpiekos@gmail.com> | 2012-06-08 13:37:12 (GMT) |
---|---|---|
committer | Mateusz Piekos <mateuszpiekos@gmail.com> | 2012-06-08 13:37:12 (GMT) |
commit | 6e9fb4e4a3aeee8c40617a4dda6e5e0892ceebad (patch) | |
tree | fd2c0a48c6f5d033fe742790fb2e640d7e13ba91 | |
parent | 13ededd86bfb5dc5115af69d79810122313273b5 (diff) | |
download | swift-contrib-6e9fb4e4a3aeee8c40617a4dda6e5e0892ceebad.zip swift-contrib-6e9fb4e4a3aeee8c40617a4dda6e5e0892ceebad.tar.bz2 |
Added handling of whiteboard session requests
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_; |