diff options
Diffstat (limited to 'Swift/Controllers/Chat')
| -rw-r--r-- | Swift/Controllers/Chat/ChatController.cpp | 35 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/ChatController.h | 1 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/ChatControllerBase.cpp | 10 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/ChatControllerBase.h | 6 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 2 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 24 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.h | 3 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp | 6 | 
8 files changed, 70 insertions, 17 deletions
| diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index 513b446..f4aa745 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -12,16 +12,16 @@  #include <Swift/Controllers/Intl.h>  #include <Swiften/Base/format.h>  #include <Swiften/Base/Algorithm.h> -#include "Swiften/Avatars/AvatarManager.h" -#include "Swiften/Chat/ChatStateNotifier.h" -#include "Swiften/Chat/ChatStateTracker.h" -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Disco/EntityCapsProvider.h" -#include "Swift/Controllers/UIInterfaces/ChatWindow.h" -#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h" -#include "Swiften/Client/NickResolver.h" -#include "Swift/Controllers/XMPPEvents/EventController.h" +#include <Swiften/Avatars/AvatarManager.h> +#include <Swiften/Chat/ChatStateNotifier.h> +#include <Swiften/Chat/ChatStateTracker.h> +#include <Swiften/Client/StanzaChannel.h> +#include <Swift/Controllers/UIInterfaces/ChatWindow.h> +#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h> +#include <Swiften/Client/NickResolver.h> +#include <Swift/Controllers/XMPPEvents/EventController.h>  #include <Swift/Controllers/StatusUtil.h> +#include <Swiften/Disco/EntityCapsProvider.h>  namespace Swift { @@ -29,7 +29,7 @@ namespace Swift {   * The controller does not gain ownership of the stanzaChannel, nor the factory.   */  ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider) -	: ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory) { +	: ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider) {  	isInMUC_ = isInMUC;  	lastWasPresence_ = false;  	chatStateNotifier_ = new ChatStateNotifier(stanzaChannel, contact, entityCapsProvider); @@ -60,6 +60,7 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ  	chatWindow_->addSystemMessage(startMessage);  	chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));  	chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); +	handleBareJIDCapsChanged(toJID_);  } @@ -75,6 +76,19 @@ ChatController::~ChatController() {  	delete chatStateTracker_;  } +void ChatController::handleBareJIDCapsChanged(const JID& /*jid*/) { +	DiscoInfo::ref disco = entityCapsProvider_->getCaps(toJID_); +	if (disco) { +		if (disco->hasFeature(DiscoInfo::MessageCorrectionFeature)) { +			chatWindow_->setCorrectionEnabled(ChatWindow::Yes); +		} else { +			chatWindow_->setCorrectionEnabled(ChatWindow::No); +		} +	} else { +		chatWindow_->setCorrectionEnabled(ChatWindow::Maybe); +	} +} +  void ChatController::setToJID(const JID& jid) {  	chatStateNotifier_->setContact(jid);  	ChatControllerBase::setToJID(jid); @@ -85,6 +99,7 @@ void ChatController::setToJID(const JID& jid) {  		presence = jid.isBare() ? presenceOracle_->getHighestPriorityPresence(jid.toBare()) : presenceOracle_->getLastPresence(jid);  	}  	chatStateNotifier_->setContactIsOnline(presence && presence->getType() == Presence::Available); +	handleBareJIDCapsChanged(toJID_);  }  bool ChatController::isIncomingMessageFromMe(boost::shared_ptr<Message>) { diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h index 4fafb44..f6b8763 100644 --- a/Swift/Controllers/Chat/ChatController.h +++ b/Swift/Controllers/Chat/ChatController.h @@ -35,6 +35,7 @@ namespace Swift {  			void handleStanzaAcked(boost::shared_ptr<Stanza> stanza);  			void dayTicked() {lastWasPresence_ = false;}  			void handleContactNickChanged(const JID& jid, const std::string& /*oldNick*/); +			void handleBareJIDCapsChanged(const JID& jid);  		private:  			NickResolver* nickResolver_; diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index 5e3c45f..802a7cb 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -21,6 +21,7 @@  #include "Swiften/Elements/Delay.h"  #include "Swiften/Base/foreach.h"  #include "Swift/Controllers/XMPPEvents/EventController.h" +#include "Swiften/Disco/EntityCapsProvider.h"  #include "Swift/Controllers/UIInterfaces/ChatWindow.h"  #include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"  #include "Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h" @@ -28,10 +29,11 @@  namespace Swift { -ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency), eventController_(eventController), timerFactory_(timerFactory) { +ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency), eventController_(eventController), timerFactory_(timerFactory), entityCapsProvider_(entityCapsProvider) {  	chatWindow_ = chatWindowFactory_->createChatWindow(toJID, eventStream);  	chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));  	chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1, _2)); +	entityCapsProvider_->onCapsChanged.connect(boost::bind(&ChatControllerBase::handleCapsChanged, this, _1));  	setOnline(stanzaChannel->isAvailable() && iqRouter->isAvailable());  	createDayChangeTimer();  } @@ -40,6 +42,12 @@ ChatControllerBase::~ChatControllerBase() {  	delete chatWindow_;  } +void ChatControllerBase::handleCapsChanged(const JID& jid) { +	if (jid.compare(toJID_, JID::WithoutResource) == 0) { +		handleBareJIDCapsChanged(jid); +	} +} +  void ChatControllerBase::createDayChangeTimer() {  	if (timerFactory_) {  		boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h index 86c1ef2..79d376c 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.h +++ b/Swift/Controllers/Chat/ChatControllerBase.h @@ -35,6 +35,7 @@ namespace Swift {  	class AvatarManager;  	class UIEventStream;  	class EventController; +	class EntityCapsProvider;  	class ChatControllerBase : public boost::bsignals::trackable {  		public: @@ -52,8 +53,9 @@ namespace Swift {  			boost::signal<void ()> onUnreadCountChanged;  			int getUnreadCount();  			const JID& getToJID() {return toJID_;} +			void handleCapsChanged(const JID& jid);  		protected: -			ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory); +			ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider);  			/**  			 * Pass the Message appended, and the stanza used to send it. @@ -67,6 +69,7 @@ namespace Swift {  			virtual bool isFromContact(const JID& from);  			virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const = 0;  			virtual void dayTicked() {}; +			virtual void handleBareJIDCapsChanged(const JID& jid) = 0;  		private:  			IDGenerator idGenerator_; @@ -94,5 +97,6 @@ namespace Swift {  			EventController* eventController_;  			boost::shared_ptr<Timer> dateChangeTimer_;  			TimerFactory* timerFactory_; +			EntityCapsProvider* entityCapsProvider_;  	};  } diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index 8b8b993..56f7a4c 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -480,7 +480,7 @@ void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional  	} else {  		std::string nick = nickMaybe ? nickMaybe.get() : jid_.getNode();  		MUC::ref muc = mucManager->createMUC(mucJID); -		MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_); +		MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_);  		mucControllers_[mucJID] = 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 93ceb13..aa0a1e7 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -30,6 +30,7 @@  #include <Swift/Controllers/Roster/Roster.h>  #include <Swift/Controllers/Roster/SetAvatar.h>  #include <Swift/Controllers/Roster/SetPresence.h> +#include <Swiften/Disco/EntityCapsProvider.h>  #define MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS 60000 @@ -51,8 +52,9 @@ MUCController::MUCController (  		UIEventStream* uiEventStream,  		bool useDelayForLatency,  		TimerFactory* timerFactory, -		EventController* eventController) : -			ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory), muc_(muc), nick_(nick), desiredNick_(nick) { +		EventController* eventController, +		EntityCapsProvider* entityCapsProvider) : +			ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider), muc_(muc), nick_(nick), desiredNick_(nick) {  	parting_ = true;  	joined_ = false;  	lastWasPresence_ = false; @@ -82,6 +84,7 @@ MUCController::MUCController (  	if (avatarManager_ != NULL) {  		avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1)));  	}  +	handleBareJIDCapsChanged(muc->getJID());  }  MUCController::~MUCController() { @@ -94,6 +97,23 @@ MUCController::~MUCController() {  	delete completer_;  } +void MUCController::handleBareJIDCapsChanged(const JID& /*jid*/) { +	ChatWindow::Tristate support = ChatWindow::Yes; +	bool any = false; +	foreach (const std::string& nick, currentOccupants_) { +		DiscoInfo::ref disco = entityCapsProvider_->getCaps(toJID_.toBare().toString() + "/" + nick); +		if (disco && disco->hasFeature(DiscoInfo::MessageCorrectionFeature)) { +			any = true; +		} else { +			support = ChatWindow::Maybe; +		} +	} +	if (!any) { +		support = ChatWindow::No; +	} +	chatWindow_->setCorrectionEnabled(support); +} +  /**   * Join the MUC if not already in it.   */ diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index c6901df..3a79920 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -41,7 +41,7 @@ namespace Swift {  	class MUCController : public ChatControllerBase {  		public: -			MUCController(const JID& self, MUC::ref muc, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController); +			MUCController(const JID& self, MUC::ref muc, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider);  			~MUCController();  			boost::signal<void ()> onUserLeft;  			boost::signal<void ()> onUserJoined; @@ -83,6 +83,7 @@ namespace Swift {  			bool shouldUpdateJoinParts();  			void dayTicked() {lastWasPresence_ = false;}  			void processUserPart(); +			void handleBareJIDCapsChanged(const JID& jid);  		private:  			MUC::ref muc_; diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp index 5f5e44d..ad5ceac 100644 --- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp @@ -25,6 +25,7 @@  #include "Swiften/Presence/PresenceOracle.h"  #include "Swiften/Network/TimerFactory.h"  #include "Swiften/Elements/MUCUserPayload.h" +#include "Swiften/Disco/DummyEntityCapsProvider.h"  using namespace Swift; @@ -56,12 +57,14 @@ public:  		TimerFactory* timerFactory = NULL;  		window_ = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();  		mucRegistry_ = new MUCRegistry(); +		entityCapsProvider_ = new DummyEntityCapsProvider();  		muc_ = MUC::ref(new MUC(stanzaChannel_, iqRouter_, directedPresenceSender_, JID("teaparty@rooms.wonderland.lit"), mucRegistry_));  		mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_); -		controller_ = new MUCController (self_, muc_, nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_); +		controller_ = new MUCController (self_, muc_, nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_);  	};  	void tearDown() { +		delete entityCapsProvider_;  		delete controller_;  		delete eventController_;  		delete presenceOracle_; @@ -240,6 +243,7 @@ private:  	UIEventStream* uiEventStream_;  	MockChatWindow* window_;  	MUCRegistry* mucRegistry_; +	DummyEntityCapsProvider* entityCapsProvider_;  };  CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest); | 
 Swift
 Swift