summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp65
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp67
-rw-r--r--Swift/Controllers/Chat/MUCController.h20
-rw-r--r--Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp10
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h12
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h3
-rw-r--r--Swift/QtUI/QtAddBookmarkWindow.cpp7
-rw-r--r--Swift/QtUI/QtChatWindow.cpp45
-rw-r--r--Swift/QtUI/QtChatWindow.h7
9 files changed, 162 insertions, 74 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index fe098de..3cd9169 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -3,68 +3,67 @@
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Chat/ChatsManager.h>
-#include <boost/bind.hpp>
#include <boost/algorithm/string.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
-#include <boost/serialization/optional.hpp>
-#include <boost/serialization/vector.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/bind.hpp>
#include <boost/serialization/map.hpp>
-#include <boost/serialization/string.hpp>
+#include <boost/serialization/optional.hpp>
#include <boost/serialization/split_free.hpp>
+#include <boost/serialization/string.hpp>
+#include <boost/serialization/vector.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+#include <Swiften/Avatars/AvatarManager.h>
+#include <Swiften/Base/Log.h>
#include <Swiften/Base/foreach.h>
-#include <Swiften/Presence/PresenceSender.h>
+#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/NickResolver.h>
-#include <Swiften/MUC/MUCManager.h>
+#include <Swiften/Client/StanzaChannel.h>
+#include <Swiften/Disco/DiscoServiceWalker.h>
#include <Swiften/Elements/ChatState.h>
-#include <Swiften/Elements/MUCUserPayload.h>
#include <Swiften/Elements/DeliveryReceipt.h>
#include <Swiften/Elements/DeliveryReceiptRequest.h>
-#include <Swiften/MUC/MUCBookmarkManager.h>
-#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Elements/MUCInvitationPayload.h>
+#include <Swiften/Elements/MUCUserPayload.h>
+#include <Swiften/MUC/MUCBookmarkManager.h>
+#include <Swiften/MUC/MUCManager.h>
+#include <Swiften/Presence/PresenceSender.h>
#include <Swiften/Roster/XMPPRoster.h>
-#include <Swiften/Client/ClientBlockListManager.h>
-#include <Swiften/Client/StanzaChannel.h>
+#include <Swiften/StringCodecs/Base64.h>
#include <Swiften/VCards/VCardManager.h>
+#include <Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h>
#include <Swift/Controllers/Chat/ChatController.h>
#include <Swift/Controllers/Chat/ChatControllerBase.h>
-#include <Swift/Controllers/Chat/MUCSearchController.h>
-#include <Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h>
-#include <Swift/Controllers/XMPPEvents/EventController.h>
+#include <Swift/Controllers/Chat/ChatMessageParser.h>
#include <Swift/Controllers/Chat/MUCController.h>
-#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
-#include <Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h>
-#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
-#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h>
+#include <Swift/Controllers/Chat/MUCSearchController.h>
+#include <Swift/Controllers/Chat/UserSearchController.h>
+#include <Swift/Controllers/FileTransfer/FileTransferController.h>
+#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
+#include <Swift/Controllers/ProfileSettingsProvider.h>
+#include <Swift/Controllers/SettingConstants.h>
+#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h>
-#include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h>
+#include <Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h>
#include <Swift/Controllers/UIEvents/InviteToMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h>
#include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h>
#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
-#include <Swift/Controllers/FileTransfer/FileTransferController.h>
-#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
-#include <Swift/Controllers/ProfileSettingsProvider.h>
-#include <Swift/Controllers/Settings/SettingsProvider.h>
-#include <Swift/Controllers/SettingConstants.h>
#include <Swift/Controllers/WhiteboardManager.h>
-#include <Swift/Controllers/Chat/ChatMessageParser.h>
-#include <Swift/Controllers/Chat/UserSearchController.h>
-#include <Swiften/Disco/DiscoServiceWalker.h>
-#include <Swiften/Client/ClientBlockListManager.h>
-#include <Swiften/StringCodecs/Base64.h>
-#include <Swiften/Base/Log.h>
+#include <Swift/Controllers/XMPPEvents/EventController.h>
BOOST_CLASS_VERSION(Swift::ChatListWindow::Chat, 1)
namespace boost {
namespace serialization {
template<class Archive> void save(Archive& ar, const Swift::JID& jid, const unsigned int /*version*/) {
@@ -808,13 +807,13 @@ MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::opti
MUCController* controller = NULL;
SingleChatWindowFactoryAdapter* chatWindowFactoryAdapter = NULL;
if (reuseChatwindow) {
chatWindowFactoryAdapter = new SingleChatWindowFactoryAdapter(reuseChatwindow);
}
boost::shared_ptr<ChatMessageParser> chatMessageParser = boost::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), true); /* a message parser that knows this is a room/MUC (not a chat) */
- controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_);
+ controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_);
if (chatWindowFactoryAdapter) {
/* The adapters are only passed to chat windows, which are deleted in their
* controllers' dtor, which are deleted in ChatManager's dtor. The adapters
* are also deleted there.*/
chatWindowFactoryAdapters_[controller] = chatWindowFactoryAdapter;
}
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 2706981..054f896 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -3,12 +3,14 @@
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Chat/MUCController.h>
+#include <algorithm>
+
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/Log.h>
@@ -18,43 +20,56 @@
#include <Swiften/Client/BlockList.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Disco/EntityCapsProvider.h>
#include <Swiften/Elements/Delay.h>
#include <Swiften/MUC/MUC.h>
+#include <Swiften/MUC/MUCBookmark.h>
+#include <Swiften/MUC/MUCBookmarkManager.h>
#include <Swiften/Network/Timer.h>
#include <Swiften/Network/TimerFactory.h>
#include <Swiften/Roster/XMPPRoster.h>
#include <SwifTools/TabComplete.h>
#include <Swift/Controllers/Chat/ChatMessageParser.h>
#include <Swift/Controllers/Highlighter.h>
#include <Swift/Controllers/Intl.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/Roster/ItemOperations/SetAvatar.h>
-#include <Swift/Controllers/Roster/ItemOperations/SetPresence.h>
#include <Swift/Controllers/Roster/ItemOperations/SetMUC.h>
+#include <Swift/Controllers/Roster/ItemOperations/SetPresence.h>
#include <Swift/Controllers/Roster/Roster.h>
#include <Swift/Controllers/Roster/RosterVCardProvider.h>
#include <Swift/Controllers/UIEvents/InviteToMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h>
-#include <Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h>
#include <Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
#define MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS 60000
namespace Swift {
-
+
+class MUCBookmarkPredicate {
+ public:
+ MUCBookmarkPredicate(const JID& mucJID) : roomJID_(mucJID) { }
+ bool operator()(const MUCBookmark& operand) {
+ return operand.getRoom() == roomJID_;
+ }
+
+ private:
+ JID roomJID_;
+};
+
/**
* The controller does not gain ownership of the stanzaChannel, nor the factory.
*/
MUCController::MUCController (
const JID& self,
MUC::ref muc,
@@ -75,14 +90,15 @@ MUCController::MUCController (
MUCRegistry* mucRegistry,
HighlightManager* highlightManager,
ClientBlockListManager* clientBlockListManager,
boost::shared_ptr<ChatMessageParser> chatMessageParser,
bool isImpromptu,
AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider,
- VCardManager* vcardManager) :
- ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false), clientBlockListManager_(clientBlockListManager) {
+ VCardManager* vcardManager,
+ MUCBookmarkManager* mucBookmarkManager) :
+ ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false), clientBlockListManager_(clientBlockListManager), mucBookmarkManager_(mucBookmarkManager) {
parting_ = true;
joined_ = false;
lastWasPresence_ = false;
shouldJoinOnReconnect_ = true;
doneGettingHistory_ = false;
events_ = uiEventStream;
@@ -134,12 +150,26 @@ MUCController::MUCController (
setOnline(true);
if (avatarManager_ != NULL) {
avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1)));
}
handleBareJIDCapsChanged(muc->getJID());
eventStream_->onUIEvent.connect(boost::bind(&MUCController::handleUIEvent, this, _1));
+
+
+ // setup handling of MUC bookmark changes
+ mucBookmarkManagerBookmarkAddedConnection_ = (mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&MUCController::handleMUCBookmarkAdded, this, _1)));
+ mucBookmarkManagerBookmarkRemovedConnection_ = (mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&MUCController::handleMUCBookmarkRemoved, this, _1)));
+
+ std::vector<MUCBookmark> mucBookmarks = mucBookmarkManager_->getBookmarks();
+ std::vector<MUCBookmark>::iterator bookmarkIterator = std::find_if(mucBookmarks.begin(), mucBookmarks.end(), MUCBookmarkPredicate(muc->getJID()));
+ if (bookmarkIterator != mucBookmarks.end()) {
+ updateChatWindowBookmarkStatus(*bookmarkIterator);
+ }
+ else {
+ updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>());
+ }
}
MUCController::~MUCController() {
eventStream_->onUIEvent.disconnect(boost::bind(&MUCController::handleUIEvent, this, _1));
chatWindow_->setRosterModel(NULL);
delete rosterVCardProvider_;
@@ -1139,7 +1169,34 @@ void MUCController::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info
blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&MUCController::handleBlockingStateChanged, this));
handleBlockingStateChanged();
}
}
+void MUCController::handleMUCBookmarkAdded(const MUCBookmark& bookmark) {
+ if (bookmark.getRoom() == muc_->getJID()) {
+ updateChatWindowBookmarkStatus(bookmark);
+ }
+}
+
+void MUCController::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) {
+ if (bookmark.getRoom() == muc_->getJID()) {
+ updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>());
+ }
+}
+
+void MUCController::updateChatWindowBookmarkStatus(const boost::optional<MUCBookmark>& bookmark) {
+ assert(chatWindow_);
+ if (bookmark) {
+ if (bookmark->getAutojoin()) {
+ chatWindow_->setBookmarkState(ChatWindow::RoomAutoJoined);
+ }
+ else {
+ chatWindow_->setBookmarkState(ChatWindow::RoomBookmarked);
+ }
+ }
+ else {
+ chatWindow_->setBookmarkState(ChatWindow::RoomNotBookmarked);
+ }
+}
+
}
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index 7c24ae2..36edbdd 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -3,26 +3,26 @@
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <map>
#include <set>
#include <string>
-#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/signals/connection.hpp>
#include <Swiften/Base/boost_bsignals.h>
-#include <Swiften/Network/Timer.h>
-#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/DiscoInfo.h>
+#include <Swiften/Elements/MUCOccupant.h>
+#include <Swiften/Elements/Message.h>
#include <Swiften/JID/JID.h>
#include <Swiften/MUC/MUC.h>
-#include <Swiften/Elements/MUCOccupant.h>
+#include <Swiften/Network/Timer.h>
#include <Swift/Controllers/Chat/ChatControllerBase.h>
#include <Swift/Controllers/Roster/RosterItem.h>
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
namespace Swift {
@@ -37,24 +37,26 @@ namespace Swift {
class XMPPRoster;
class HighlightManager;
class UIEvent;
class VCardManager;
class RosterVCardProvider;
class ClientBlockListManager;
+ class MUCBookmarkManager;
+ class MUCBookmark;
enum JoinPart {Join, Part, JoinThenPart, PartThenJoin};
struct NickJoinPart {
NickJoinPart(const std::string& nick, JoinPart type) : nick(nick), type(type) {}
std::string nick;
JoinPart type;
};
class MUCController : public ChatControllerBase {
public:
- MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager);
+ MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager, MUCBookmarkManager* mucBookmarkManager);
virtual ~MUCController();
boost::signal<void ()> onUserLeft;
boost::signal<void ()> onUserJoined;
boost::signal<void ()> onImpromptuConfigCompleted;
boost::signal<void (const std::string&, const std::string& )> onUserNicknameChanged;
virtual void setOnline(bool online);
@@ -134,12 +136,16 @@ namespace Swift {
void configureAsImpromptuRoom(Form::ref form);
Form::ref buildImpromptuRoomConfiguration(Form::ref roomConfigurationForm);
void handleUnblockUserRequest();
void handleBlockingStateChanged();
+ void handleMUCBookmarkAdded(const MUCBookmark& bookmark);
+ void handleMUCBookmarkRemoved(const MUCBookmark& bookmark);
+ void updateChatWindowBookmarkStatus(const boost::optional<MUCBookmark>& bookmark);
+
private:
MUC::ref muc_;
UIEventStream* events_;
std::string nick_;
std::string desiredNick_;
Roster* roster_;
@@ -166,9 +172,13 @@ namespace Swift {
ClientBlockListManager* clientBlockListManager_;
boost::bsignals::scoped_connection blockingOnStateChangedConnection_;
boost::bsignals::scoped_connection blockingOnItemAddedConnection_;
boost::bsignals::scoped_connection blockingOnItemRemovedConnection_;
boost::optional<ChatWindow::AlertID> blockedContactAlert_;
+
+ MUCBookmarkManager* mucBookmarkManager_;
+ boost::bsignals::scoped_connection mucBookmarkManagerBookmarkAddedConnection_;
+ boost::bsignals::scoped_connection mucBookmarkManagerBookmarkRemovedConnection_;
};
}
diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
index 0b7b793..cc4045a 100644
--- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
@@ -1,27 +1,28 @@
/*
* Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
#include <boost/algorithm/string.hpp>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
#include <hippomocks.h>
#include <Swiften/Avatars/NullAvatarManager.h>
#include <Swiften/Base/foreach.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/DummyStanzaChannel.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
#include <Swiften/Disco/DummyEntityCapsProvider.h>
#include <Swiften/Elements/MUCUserPayload.h>
+#include <Swiften/MUC/MUCBookmarkManager.h>
#include <Swiften/MUC/UnitTest/MockMUC.h>
#include <Swiften/Network/TimerFactory.h>
#include <Swiften/Presence/DirectedPresenceSender.h>
#include <Swiften/Presence/PresenceOracle.h>
#include <Swiften/Presence/StanzaChannelPresenceSender.h>
#include <Swiften/Queries/DummyIQChannel.h>
@@ -85,17 +86,19 @@ public:
muc_ = boost::make_shared<MockMUC>(mucJID_);
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_);
chatMessageParser_ = boost::make_shared<ChatMessageParser>(std::map<std::string, std::string>(), highlightManager_->getRules(), true);
vcardStorage_ = new VCardMemoryStorage(crypto_.get());
vcardManager_ = new VCardManager(self_, iqRouter_, vcardStorage_);
clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
- controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser_, false, NULL, vcardManager_);
+ mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_);
+ controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser_, false, NULL, vcardManager_, mucBookmarkManager_);
}
void tearDown() {
delete controller_;
+ delete mucBookmarkManager_;
delete clientBlockListManager_;
delete vcardManager_;
delete vcardStorage_;
delete highlightManager_;
delete settings_;
delete entityCapsProvider_;
@@ -435,10 +438,11 @@ private:
HighlightManager* highlightManager_;
boost::shared_ptr<ChatMessageParser> chatMessageParser_;
boost::shared_ptr<CryptoProvider> crypto_;
VCardManager* vcardManager_;
VCardMemoryStorage* vcardStorage_;
ClientBlockListManager* clientBlockListManager_;
+ MUCBookmarkManager* mucBookmarkManager_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest);
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 8d0026c..765f16a 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -3,28 +3,28 @@
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <vector>
#include <string>
+#include <vector>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/make_shared.hpp>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
#include <Swiften/Base/boost_bsignals.h>
-#include <Swiften/Elements/SecurityLabelsCatalog.h>
#include <Swiften/Elements/ChatState.h>
#include <Swiften/Elements/Form.h>
#include <Swiften/Elements/MUCOccupant.h>
+#include <Swiften/Elements/SecurityLabelsCatalog.h>
#include <Swiften/MUC/MUCBookmark.h>
-#include <Swift/Controllers/HighlightManager.h>
+#include <Swift/Controllers/HighlightManager.h>
namespace Swift {
class AvatarManager;
class TreeWidget;
class Roster;
class TabComplete;
@@ -92,12 +92,13 @@ namespace Swift {
enum FileTransferState {WaitingForAccept, Negotiating, Transferring, Canceled, Finished, FTFailed};
enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected};
enum BlockingState {BlockingUnsupported, IsBlocked, IsUnblocked};
enum Direction { UnknownDirection, DefaultDirection };
enum MUCType { StandardMUC, ImpromptuMUC };
enum TimestampBehaviour { KeepTimestamp, UpdateTimestamp };
+ enum RoomBookmarkState { RoomNotBookmarked, RoomBookmarked, RoomAutoJoined };
ChatWindow() {}
virtual ~ChatWindow() {}
/** Add message to window.
* @return id of added message (for acks).
@@ -154,12 +155,13 @@ namespace Swift {
virtual void setSubject(const std::string& subject) = 0;
virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) = 0;
virtual void setAvailableRoomActions(const std::vector<RoomAction> &actions) = 0;
virtual void setBlockingState(BlockingState state) = 0;
virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) = 0;
virtual void showBookmarkWindow(const MUCBookmark& bookmark) = 0;
+ virtual void setBookmarkState(RoomBookmarkState bookmarkState) = 0;
/**
* A handle that uniquely identities an alert message.
*/
typedef int AlertID;
/**
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index 1fdd340..2798be6 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -5,15 +5,15 @@
*/
#pragma once
#include <boost/shared_ptr.hpp>
-#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
#include <Swiften/Base/foreach.h>
+#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
namespace Swift {
class MockChatWindow : public ChatWindow {
public:
MockChatWindow() : labelsEnabled_(false) {}
virtual ~MockChatWindow();
@@ -77,12 +77,13 @@ namespace Swift {
virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) {}
virtual void setAvailableRoomActions(const std::vector<RoomAction> &) {}
virtual void setBlockingState(BlockingState) {}
virtual void setCanInitiateImpromptuChats(bool /*supportsImpromptu*/) {}
virtual void showBookmarkWindow(const MUCBookmark& /*bookmark*/) {}
+ virtual void setBookmarkState(RoomBookmarkState) {}
std::string bodyFromMessage(const ChatMessage& message) {
boost::shared_ptr<ChatTextMessagePart> text;
foreach (boost::shared_ptr<ChatMessagePart> part, message.getParts()) {
if ((text = boost::dynamic_pointer_cast<ChatTextMessagePart>(part))) {
return text->text;
diff --git a/Swift/QtUI/QtAddBookmarkWindow.cpp b/Swift/QtUI/QtAddBookmarkWindow.cpp
index a272aa2..3596657 100644
--- a/Swift/QtUI/QtAddBookmarkWindow.cpp
+++ b/Swift/QtUI/QtAddBookmarkWindow.cpp
@@ -1,23 +1,22 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include "QtAddBookmarkWindow.h"
-#include <qdebug.h>
-
namespace Swift {
QtAddBookmarkWindow::QtAddBookmarkWindow(UIEventStream* eventStream) : eventStream_(eventStream) {
-
+ setWindowTitle(tr("Add Bookmark Details"));
}
QtAddBookmarkWindow::QtAddBookmarkWindow(UIEventStream* eventStream, const MUCBookmark& bookmark) : eventStream_(eventStream) {
createFormFromBookmark(bookmark);
+ setWindowTitle(tr("Add Bookmark Details"));
}
bool QtAddBookmarkWindow::commit() {
boost::optional<MUCBookmark> bookmark = createBookmarkFromForm();
if (bookmark) {
eventStream_->send(boost::shared_ptr<UIEvent>(new AddMUCBookmarkUIEvent(*bookmark)));
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index f25c033..b1b9f83 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -7,13 +7,12 @@
#include <Swift/QtUI/QtChatWindow.h>
#include <boost/cstdint.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/smart_ptr/make_shared.hpp>
-#include <qdebug.h>
#include <QApplication>
#include <QBoxLayout>
#include <QCloseEvent>
#include <QComboBox>
#include <QCursor>
#include <QFileDialog>
@@ -31,39 +30,41 @@
#include <QString>
#include <QTextDocument>
#include <QTextEdit>
#include <QTime>
#include <QToolButton>
#include <QUrl>
-#include <QMimeData>
+
+#include <qdebug.h>
#include <Swiften/Base/Log.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/Roster.h>
#include <Swift/Controllers/Roster/RosterItem.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
-#include <Swift/Controllers/UIEvents/UIEventStream.h>
-#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <SwifTools/TabComplete.h>
-#include <Swift/QtUI/Roster/QtOccupantListWidget.h>
#include <Swift/QtUI/QtAddBookmarkWindow.h>
+#include <Swift/QtUI/QtEditBookmarkWindow.h>
#include <Swift/QtUI/QtPlainChatView.h>
-#include <Swift/QtUI/QtSettingsProvider.h>
#include <Swift/QtUI/QtScaledAvatarCache.h>
+#include <Swift/QtUI/QtSettingsProvider.h>
#include <Swift/QtUI/QtTextEdit.h>
#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/QtUI/QtUtilities.h>
#include <Swift/QtUI/QtWebKitChatView.h>
+#include <Swift/QtUI/Roster/QtOccupantListWidget.h>
namespace Swift {
-QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, const std::map<std::string, std::string>& emoticons) : QtTabbable(), id_(Q2PSTRING(contact)), contact_(contact), nextAlertId_(0), eventStream_(eventStream), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false) {
+QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, const std::map<std::string, std::string>& emoticons) : QtTabbable(), id_(Q2PSTRING(contact)), contact_(contact), nextAlertId_(0), eventStream_(eventStream), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false), roomBookmarkState_(RoomNotBookmarked) {
settings_ = settings;
unreadCount_ = 0;
isOnline_ = true;
completer_ = NULL;
affiliationEditor_ = NULL;
theme_ = theme;
@@ -521,15 +522,12 @@ void QtChatWindow::updateTitleWithUnreadCount() {
else {
setWindowTitle(contact_);
}
emit titleUpdated();
}
-
-
-
void QtChatWindow::flash() {
emit requestFlash();
}
int QtChatWindow::getCount() {
return unreadCount_;
@@ -722,14 +720,22 @@ void QtChatWindow::handleActionButtonClicked() {
invite->setEnabled(isOnline_);
break;
}
}
}
- QAction* bookmark = contextMenu.addAction(tr("Add bookmark..."));
- bookmark->setEnabled(isOnline_);
+ QAction* bookmark = NULL;
+ if (isMUC_) {
+ if (roomBookmarkState_ == RoomNotBookmarked) {
+ bookmark = contextMenu.addAction(tr("Bookmark this room..."));
+ }
+ else {
+ bookmark = contextMenu.addAction(tr("Edit bookmark..."));
+ }
+ bookmark->setEnabled(isOnline_);
+ }
QAction* result = contextMenu.exec(QCursor::pos());
if (result == NULL) {
/* Skip processing. Note that otherwise, because the actions could be null they could match */
}
else if (result == changeSubject) {
@@ -794,14 +800,20 @@ void QtChatWindow::setBlockingState(BlockingState state) {
void QtChatWindow::setCanInitiateImpromptuChats(bool supportsImpromptu) {
supportsImpromptuChat_ = supportsImpromptu;
}
void QtChatWindow::showBookmarkWindow(const MUCBookmark& bookmark) {
- QtAddBookmarkWindow* window = new QtAddBookmarkWindow(eventStream_, bookmark);
- window->show();
+ if (roomBookmarkState_ == RoomNotBookmarked) {
+ QtAddBookmarkWindow* window = new QtAddBookmarkWindow(eventStream_, bookmark);
+ window->show();
+ }
+ else {
+ QtEditBookmarkWindow* window = new QtEditBookmarkWindow(eventStream_, bookmark);
+ window->show();
+ }
}
std::string QtChatWindow::getID() const {
return id_;
}
@@ -876,13 +888,12 @@ void QtChatWindow::setFileTransferProgress(std::string id, const int percentageD
}
void QtChatWindow::setFileTransferStatus(std::string id, const FileTransferState state, const std::string& msg) {
messageLog_->setFileTransferStatus(id, state, msg);
}
-
std::string QtChatWindow::addWhiteboardRequest(bool senderIsSelf) {
handleAppendedToLog();
return messageLog_->addWhiteboardRequest(contact_, senderIsSelf);
}
void QtChatWindow::setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state) {
@@ -898,7 +909,11 @@ void QtChatWindow::setAckState(const std::string& id, AckState state) {
}
void QtChatWindow::setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) {
messageLog_->setMessageReceiptState(id, state);
}
+void QtChatWindow::setBookmarkState(RoomBookmarkState bookmarkState) {
+ roomBookmarkState_ = bookmarkState;
+}
+
}
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index 5c6fa2a..06c6064 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -11,24 +11,23 @@
#include <QMap>
#include <QMenu>
#include <QPointer>
#include <QString>
#include <QTextCursor>
-#include <SwifTools/LastLineTracker.h>
-
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
+#include <SwifTools/LastLineTracker.h>
+
#include <Swift/QtUI/ChatSnippet.h>
#include <Swift/QtUI/QtAffiliationEditor.h>
#include <Swift/QtUI/QtEmoticonsGrid.h>
#include <Swift/QtUI/QtMUCConfigurationWindow.h>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtTabbable.h>
-
class QTextEdit;
class QLineEdit;
class QComboBox;
class QLabel;
class QSplitter;
class QPushButton;
@@ -130,12 +129,13 @@ namespace Swift {
void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true, bool isImpromptu = false, bool isContinuation = false);
void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&);
void setAvailableRoomActions(const std::vector<RoomAction>& actions);
void setBlockingState(BlockingState state);
virtual void setCanInitiateImpromptuChats(bool supportsImpromptu);
virtual void showBookmarkWindow(const MUCBookmark& bookmark);
+ virtual void setBookmarkState(RoomBookmarkState bookmarkState);
virtual std::string getID() const;
public slots:
void handleChangeSplitterState(QByteArray state);
void handleFontResized(int fontSizeSteps);
AlertID addAlert(const std::string& alertText);
@@ -222,9 +222,10 @@ namespace Swift {
QPalette defaultLabelsPalette_;
LabelModel* labelModel_;
BlockingState blockingState_;
bool impromptu_;
bool isMUC_;
bool supportsImpromptuChat_;
+ RoomBookmarkState roomBookmarkState_;
QMenu* emoticonsMenu_;
};
}