From 90eab2990dc087ebe2b91181f14ca452e5b31697 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Mon, 5 Apr 2010 20:15:02 +0100
Subject: Allow opening chats to MUC occupants.

Resolves: #275

diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 8311726..8c49cd6 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -167,7 +167,7 @@ void ChatsManager::handleJoinMUCRequest(const JID &muc, const String &nick) {
 	if (it != mucControllers_.end()) {
 		//FIXME: What's correct behaviour here?
 	} else {
-		MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, presenceSender_, iqRouter_, chatWindowFactory_, treeWidgetFactory_, presenceOracle_, avatarManager_);
+		MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, presenceSender_, iqRouter_, chatWindowFactory_, treeWidgetFactory_, presenceOracle_, avatarManager_, uiEventStream_);
 		mucControllers_[muc] = controller;
 		controller->setAvailableServerFeatures(serverDiscoInfo_);
 		controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller));
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 0ec8c28..a1ca9cc 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -5,10 +5,13 @@
 #include "Swiften/Base/foreach.h"
 #include "Swift/Controllers/UIInterfaces/ChatWindow.h"
 #include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
+#include "Swift/Controllers/UIEvents/UIEventStream.h"
+#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
 #include "Swiften/Avatars/AvatarManager.h"
 #include "Swiften/MUC/MUC.h"
 #include "Swiften/Client/StanzaChannel.h"
 #include "Swiften/Roster/Roster.h"
+#include "Swiften/Roster/OpenChatRosterAction.h"
 #include "Swiften/Roster/SetAvatar.h"
 #include "Swiften/Roster/SetPresence.h"
 #include "Swiften/Roster/TreeWidgetFactory.h"
@@ -28,13 +31,16 @@ MUCController::MUCController (
 		ChatWindowFactory* chatWindowFactory, 
 		TreeWidgetFactory *treeWidgetFactory,
 		PresenceOracle* presenceOracle,
-		AvatarManager* avatarManager) : 
+		AvatarManager* avatarManager,
+		UIEventStream* uiEventStream) :
 			ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc, presenceOracle, avatarManager),
 			muc_(new MUC(stanzaChannel, presenceSender, muc)), 
 			nick_(nick), 
 			treeWidgetFactory_(treeWidgetFactory) { 
 	parting_ = false;
+	events_ = uiEventStream;
 	roster_ = new Roster(chatWindow_->getTreeWidget(), treeWidgetFactory_);
+	roster_->onUserAction.connect(boost::bind(&MUCController::handleUserAction, this, _1));
 	chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this));
 	muc_->joinAs(nick);
 	muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1));
@@ -52,6 +58,16 @@ MUCController::~MUCController() {
 	delete roster_;
 }
 
+void MUCController::handleUserAction(boost::shared_ptr<UserRosterAction> action) {
+	boost::shared_ptr<OpenChatRosterAction> chatAction = boost::dynamic_pointer_cast<OpenChatRosterAction>(action);
+	if (chatAction.get() != NULL) {
+		ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(chatAction->getRosterItem());
+		assert(contactItem);
+		events_->send(boost::shared_ptr<RequestChatUIEvent>(new RequestChatUIEvent(contactItem->getJID())));
+		return;
+	}
+}
+
 void MUCController::handleAvatarChanged(const JID& jid, const String&) {
 	if (parting_) {
 		return;
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index aae2150..3ad6b57 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -9,6 +9,7 @@
 #include "Swift/Controllers/Chat/ChatControllerBase.h"
 #include "Swiften/Elements/Message.h"
 #include "Swiften/Elements/DiscoInfo.h"
+#include "Swiften/Roster/UserRosterAction.h"
 #include "Swiften/JID/JID.h"
 #include "Swiften/MUC/MUC.h"
 #include "Swiften/MUC/MUCOccupant.h"
@@ -21,10 +22,11 @@ namespace Swift {
 	class Roster;
 	class TreeWidgetFactory;
 	class AvatarManager;
+	class UIEventStream;
 
 	class MUCController : public ChatControllerBase {
 		public:
-			MUCController(const JID& self, const JID &muc, const String &nick, StanzaChannel* stanzaChannel, PresenceSender* presenceSender, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory *treeWidgetFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager);
+			MUCController(const JID& self, const JID &muc, const String &nick, StanzaChannel* stanzaChannel, PresenceSender* presenceSender, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory *treeWidgetFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events);
 			~MUCController();
 			boost::signal<void ()> onUserLeft;
 		
@@ -39,12 +41,14 @@ namespace Swift {
 			void handleOccupantJoined(const MUCOccupant& occupant);
 			void handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const String& reason);
 			void handleOccupantPresenceChange(boost::shared_ptr<Presence> presence);
+			void handleUserAction(boost::shared_ptr<UserRosterAction> action);
 
 		private:
-			MUC *muc_;
+			MUC* muc_;
+			UIEventStream* events_;
 			String nick_;
-			TreeWidgetFactory *treeWidgetFactory_;
-			Roster *roster_;
+			TreeWidgetFactory* treeWidgetFactory_;
+			Roster* roster_;
 			bool parting_;
 			boost::bsignals::scoped_connection avatarChangedConnection_;
 	};
diff --git a/Swift/Controllers/UIEvents/RequestChatUIEvent.h b/Swift/Controllers/UIEvents/RequestChatUIEvent.h
index 529f498..322dd78 100644
--- a/Swift/Controllers/UIEvents/RequestChatUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestChatUIEvent.h
@@ -1,17 +1,15 @@
-//Not used yet.
-
 #pragma once
 
-#include "Swiften/Base/String.h"
+#include "Swiften/JID/JID.h"
 
 #include "Swift/Controllers/UIEvents/UIEvent.h"
 
 namespace Swift {
 	class RequestChatUIEvent : public UIEvent {
 		public:
-			RequestChatUIEvent(const String& contact) : contact_(contact) {};
-			String getContact() {return contact_;}
+			RequestChatUIEvent(const JID& contact) : contact_(contact) {};
+			JID getContact() {return contact_;}
 		private:
-			String contact_;
+			JID contact_;
 	};
 }
-- 
cgit v0.10.2-6-g49f6