diff options
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_; | 
 Swift
 Swift