summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2013-03-08 15:17:30 (GMT)
committerTobias Markmann <tm@ayena.de>2013-03-27 14:12:26 (GMT)
commit497b647fe034a3d2cdc6d75ce0ff70e3df3aaf04 (patch)
treedc81e56199f54cf20f834c78bda7fc26ffbc38f9 /Swift/Controllers
parent20ead0a84fdd8c9e870e98ee6a2712bfa263d7fb (diff)
downloadswift-497b647fe034a3d2cdc6d75ce0ff70e3df3aaf04.zip
swift-497b647fe034a3d2cdc6d75ce0ff70e3df3aaf04.tar.bz2
Adding support for Blocking Command (XEP-0191) to Swift(-en).
Change-Id: I7c92518dc389474d520d4cf96f96a11459f73d26 License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.
Diffstat (limited to 'Swift/Controllers')
-rw-r--r--Swift/Controllers/BlockListController.cpp159
-rw-r--r--Swift/Controllers/BlockListController.h48
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp48
-rw-r--r--Swift/Controllers/Chat/ChatController.h13
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.h2
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp9
-rw-r--r--Swift/Controllers/Chat/ChatsManager.h4
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp80
-rw-r--r--Swift/Controllers/MainController.cpp15
-rw-r--r--Swift/Controllers/MainController.h2
-rw-r--r--Swift/Controllers/Roster/ContactRosterItem.cpp10
-rw-r--r--Swift/Controllers/Roster/ContactRosterItem.h10
-rw-r--r--Swift/Controllers/Roster/Roster.cpp27
-rw-r--r--Swift/Controllers/Roster/Roster.h2
-rw-r--r--Swift/Controllers/Roster/RosterController.cpp31
-rw-r--r--Swift/Controllers/Roster/RosterController.h15
-rw-r--r--Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp6
-rw-r--r--Swift/Controllers/SConscript1
-rw-r--r--Swift/Controllers/UIEvents/RequestBlockListDialogUIEvent.h16
-rw-r--r--Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h37
-rw-r--r--Swift/Controllers/UIInterfaces/BlockListEditorWidget.h32
-rw-r--r--Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h20
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/MainWindow.h1
-rw-r--r--Swift/Controllers/UIInterfaces/UIFactory.h4
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h2
-rw-r--r--Swift/Controllers/UnitTest/MockMainWindow.h1
27 files changed, 540 insertions, 57 deletions
diff --git a/Swift/Controllers/BlockListController.cpp b/Swift/Controllers/BlockListController.cpp
new file mode 100644
index 0000000..e7bc45d
--- /dev/null
+++ b/Swift/Controllers/BlockListController.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swift/Controllers/BlockListController.h>
+
+#include <boost/bind.hpp>
+
+#include <Swiften/Client/ClientBlockListManager.h>
+
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Base/format.h>
+#include <Swift/Controllers/Intl.h>
+#include <Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestBlockListDialogUIEvent.h>
+#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
+#include <Swift/Controllers/UIInterfaces/BlockListEditorWidget.h>
+#include <Swift/Controllers/XMPPEvents/EventController.h>
+
+namespace Swift {
+
+BlockListController::BlockListController(ClientBlockListManager* blockListManager, UIEventStream* uiEventStream, BlockListEditorWidgetFactory* blockListEditorWidgetFactory, EventController* eventController) : blockListManager_(blockListManager), blockListEditorWidgetFactory_(blockListEditorWidgetFactory), blockListEditorWidget_(0), eventController_(eventController), remainingRequests_(0) {
+ uiEventStream->onUIEvent.connect(boost::bind(&BlockListController::handleUIEvent, this, _1));
+ blockListManager_->getBlockList()->onItemAdded.connect(boost::bind(&BlockListController::handleBlockListChanged, this));
+ blockListManager_->getBlockList()->onItemRemoved.connect(boost::bind(&BlockListController::handleBlockListChanged, this));
+}
+
+BlockListController::~BlockListController() {
+ blockListManager_->getBlockList()->onItemAdded.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this));
+ blockListManager_->getBlockList()->onItemRemoved.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this));
+}
+
+void BlockListController::blockListDifferences(const std::vector<JID> &newBlockList, std::vector<JID> &jidsToUnblock, std::vector<JID> &jidsToBlock) const {
+ foreach (const JID& jid, blockListBeforeEdit) {
+ if (std::find(newBlockList.begin(), newBlockList.end(), jid) == newBlockList.end()) {
+ jidsToUnblock.push_back(jid);
+ }
+ }
+
+ foreach (const JID& jid, newBlockList) {
+ if (std::find(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid) == blockListBeforeEdit.end()) {
+ jidsToBlock.push_back(jid);
+ }
+ }
+}
+
+void BlockListController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) {
+ // handle UI dialog
+ boost::shared_ptr<RequestBlockListDialogUIEvent> requestDialogEvent = boost::dynamic_pointer_cast<RequestBlockListDialogUIEvent>(rawEvent);
+ if (requestDialogEvent != NULL) {
+ if (blockListEditorWidget_ == NULL) {
+ blockListEditorWidget_ = blockListEditorWidgetFactory_->createBlockListEditorWidget();
+ blockListEditorWidget_->onSetNewBlockList.connect(boost::bind(&BlockListController::handleSetNewBlockList, this, _1));
+ }
+ blockListBeforeEdit = blockListManager_->getBlockList()->getItems();
+ blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit);
+ blockListEditorWidget_->show();
+ return;
+ }
+
+ // handle block state change
+ boost::shared_ptr<RequestChangeBlockStateUIEvent> changeStateEvent = boost::dynamic_pointer_cast<RequestChangeBlockStateUIEvent>(rawEvent);
+ if (changeStateEvent != NULL) {
+ if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Blocked) {
+ GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDRequest(changeStateEvent->getContact());
+ blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false));
+ blockRequest->send();
+ } else if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Unblocked) {
+ GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDRequest(changeStateEvent->getContact());
+ unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false));
+ unblockRequest->send();
+ }
+ return;
+ }
+}
+
+void BlockListController::handleBlockResponse(GenericRequest<BlockPayload>::ref request, boost::shared_ptr<BlockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor) {
+ if (error) {
+ std::string errorMessage;
+ // FIXME: Handle reporting of list of JIDs in a translatable way.
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to block %1%.")) % jids.at(0).toString());
+ if (!error->getText().empty()) {
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText());
+ }
+ eventController_->handleIncomingEvent(boost::make_shared<ErrorEvent>(request->getReceiver(), errorMessage));
+ }
+ if (originEditor) {
+ remainingRequests_--;
+ if (blockListEditorWidget_ && (remainingRequests_ == 0)) {
+ blockListEditorWidget_->setBusy(false);
+ }
+ }
+}
+
+void BlockListController::handleUnblockResponse(GenericRequest<UnblockPayload>::ref request, boost::shared_ptr<UnblockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor) {
+ if (error) {
+ std::string errorMessage;
+ // FIXME: Handle reporting of list of JIDs in a translatable way.
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to unblock %1%.")) % jids.at(0).toString());
+ if (!error->getText().empty()) {
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText());
+ }
+ eventController_->handleIncomingEvent(boost::make_shared<ErrorEvent>(request->getReceiver(), errorMessage));
+ }
+ if (originEditor) {
+ remainingRequests_--;
+ if (blockListEditorWidget_ && (remainingRequests_ == 0)) {
+ blockListEditorWidget_->setBusy(false);
+ }
+ }
+}
+
+void BlockListController::handleSetNewBlockList(const std::vector<JID> &newBlockList) {
+ std::vector<JID> jidsToBlock;
+ std::vector<JID> jidsToUnblock;
+
+ blockListDifferences(newBlockList, jidsToUnblock, jidsToBlock);
+
+ if (!jidsToBlock.empty()) {
+ remainingRequests_++;
+ GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDsRequest(jidsToBlock);
+ blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, jidsToBlock, true));
+ blockRequest->send();
+ }
+ if (!jidsToUnblock.empty()) {
+ remainingRequests_++;
+ GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDsRequest(jidsToUnblock);
+ unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, jidsToUnblock, true));
+ unblockRequest->send();
+ }
+ if (!jidsToBlock.empty() || jidsToUnblock.empty()) {
+ assert(blockListEditorWidget_);
+ blockListEditorWidget_->setBusy(true);
+ }
+}
+
+void BlockListController::handleBlockListChanged() {
+ if (blockListEditorWidget_) {
+ std::vector<JID> jidsToBlock;
+ std::vector<JID> jidsToUnblock;
+
+ blockListDifferences(blockListEditorWidget_->getCurrentBlockList(), jidsToUnblock, jidsToBlock);
+ blockListBeforeEdit = blockListManager_->getBlockList()->getItems();
+
+ foreach (const JID& jid, jidsToBlock) {
+ blockListBeforeEdit.push_back(jid);
+ }
+
+ foreach (const JID& jid, jidsToUnblock) {
+ blockListBeforeEdit.erase(std::remove(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid), blockListBeforeEdit.end());;
+ }
+
+ blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit);
+ }
+}
+
+}
diff --git a/Swift/Controllers/BlockListController.h b/Swift/Controllers/BlockListController.h
new file mode 100644
index 0000000..4c9caad
--- /dev/null
+++ b/Swift/Controllers/BlockListController.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/Queries/GenericRequest.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h>
+
+namespace Swift {
+
+class BlockPayload;
+class UnblockPayload;
+class ClientBlockListManager;
+class EventController;
+
+class BlockListController {
+public:
+ BlockListController(ClientBlockListManager* blockListManager, UIEventStream* uiEventStream, BlockListEditorWidgetFactory* blockListEditorWidgetFactory, EventController* eventController);
+ ~BlockListController();
+
+private:
+ void blockListDifferences(const std::vector<JID> &newBlockList, std::vector<JID>& jidsToUnblock, std::vector<JID>& jidsToBlock) const;
+
+ void handleUIEvent(boost::shared_ptr<UIEvent> event);
+
+ void handleBlockResponse(GenericRequest<BlockPayload>::ref, boost::shared_ptr<BlockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor);
+ void handleUnblockResponse(GenericRequest<UnblockPayload>::ref, boost::shared_ptr<UnblockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor);
+
+ void handleSetNewBlockList(const std::vector<JID>& newBlockList);
+
+ void handleBlockListChanged();
+
+private:
+ ClientBlockListManager* blockListManager_;
+ BlockListEditorWidgetFactory* blockListEditorWidgetFactory_;
+ BlockListEditorWidget* blockListEditorWidget_;
+ EventController* eventController_;
+ std::vector<JID> blockListBeforeEdit;
+ int remainingRequests_;
+};
+
+}
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index 3c0e933..f0de59c 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -36,14 +36,15 @@
#include <Swift/Controllers/SettingConstants.h>
#include <Swift/Controllers/Highlighter.h>
#include <Swiften/Base/Log.h>
+#include <Swiften/Client/ClientBlockListManager.h>
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, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager)
- : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts), settings_(settings) {
+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, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager)
+ : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts), settings_(settings), clientBlockListManager_(clientBlockListManager) {
isInMUC_ = isInMUC;
lastWasPresence_ = false;
chatStateNotifier_ = new ChatStateNotifier(stanzaChannel, contact, entityCapsProvider);
@@ -145,6 +146,19 @@ void ChatController::setToJID(const JID& jid) {
handleBareJIDCapsChanged(toJID_);
}
+void ChatController::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) {
+ ChatControllerBase::setAvailableServerFeatures(info);
+ if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) {
+ boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+
+ blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&ChatController::handleBlockingStateChanged, this));
+ blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&ChatController::handleBlockingItemAdded, this, _1));
+ blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&ChatController::handleBlockingItemRemoved, this, _1));
+
+ handleBlockingStateChanged();
+ }
+}
+
bool ChatController::isIncomingMessageFromMe(boost::shared_ptr<Message>) {
return false;
}
@@ -216,6 +230,36 @@ void ChatController::checkForDisplayingDisplayReceiptsAlert() {
}
}
+void ChatController::handleBlockingStateChanged() {
+ boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+ if (blockList->getState() == BlockList::Available) {
+ if (blockList->isBlocked(toJID_.toBare())) {
+ chatWindow_->setAlert(QT_TRANSLATE_NOOP("", "You've currently blocked this contact. To continue your conversation you have to unblock the contact first."));
+ chatWindow_->setInputEnabled(false);
+ chatWindow_->setBlockingState(ChatWindow::IsBlocked);
+ } else {
+ chatWindow_->setBlockingState(ChatWindow::IsUnblocked);
+ }
+ }
+}
+
+void ChatController::handleBlockingItemAdded(const JID& jid) {
+ if (jid == toJID_.toBare()) {
+ chatWindow_->setAlert(QT_TRANSLATE_NOOP("", "You've currently blocked this contact. To continue your conversation you have to unblock the contact first."));
+ chatWindow_->setInputEnabled(false);
+ chatWindow_->setBlockingState(ChatWindow::IsBlocked);
+ }
+}
+
+void ChatController::handleBlockingItemRemoved(const JID& jid) {
+ if (jid == toJID_.toBare()) {
+ // FIXME: Support for different types of alerts.
+ chatWindow_->cancelAlert();
+ chatWindow_->setInputEnabled(true);
+ chatWindow_->setBlockingState(ChatWindow::IsUnblocked);
+ }
+}
+
void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<Stanza> sentStanza) {
boost::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>();
if (replace) {
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index 6021ec1..4322240 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -23,12 +23,14 @@ namespace Swift {
class SettingsProvider;
class HistoryController;
class HighlightManager;
+ class ClientBlockListManager;
class ChatController : public ChatControllerBase {
public:
- 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, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager);
+ 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, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager);
virtual ~ChatController();
virtual void setToJID(const JID& jid);
+ virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info);
virtual void setOnline(bool online);
virtual void handleNewFileTransferController(FileTransferController* ftc);
virtual void handleWhiteboardSessionRequest(bool senderIsSelf);
@@ -67,6 +69,10 @@ namespace Swift {
void handleSettingChanged(const std::string& settingPath);
void checkForDisplayingDisplayReceiptsAlert();
+ void handleBlockingStateChanged();
+ void handleBlockingItemAdded(const JID&);
+ void handleBlockingItemRemoved(const JID&);
+
private:
NickResolver* nickResolver_;
ChatStateNotifier* chatStateNotifier_;
@@ -86,6 +92,11 @@ namespace Swift {
std::map<std::string, FileTransferController*> ftControllers;
SettingsProvider* settings_;
std::string lastWbID_;
+
+ ClientBlockListManager* clientBlockListManager_;
+ boost::bsignals::scoped_connection blockingOnStateChangedConnection_;
+ boost::bsignals::scoped_connection blockingOnItemAddedConnection_;
+ boost::bsignals::scoped_connection blockingOnItemRemovedConnection_;
};
}
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h
index baef9e6..84bd06a 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.h
+++ b/Swift/Controllers/Chat/ChatControllerBase.h
@@ -48,7 +48,7 @@ namespace Swift {
virtual ~ChatControllerBase();
void showChatWindow();
void activateChatWindow();
- void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info);
+ virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info);
void handleIncomingMessage(boost::shared_ptr<MessageEvent> message);
std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight);
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index dba8565..d6010e9 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -43,6 +43,7 @@
#include <Swift/Controllers/SettingConstants.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swift/Controllers/WhiteboardManager.h>
+#include <Swiften/Client/ClientBlockListManager.h>
namespace Swift {
@@ -75,7 +76,8 @@ ChatsManager::ChatsManager(
SettingsProvider* settings,
HistoryController* historyController,
WhiteboardManager* whiteboardManager,
- HighlightManager* highlightManager) :
+ HighlightManager* highlightManager,
+ ClientBlockListManager* clientBlockListManager) :
jid_(jid),
joinMUCWindowFactory_(joinMUCWindowFactory),
useDelayForLatency_(useDelayForLatency),
@@ -88,7 +90,8 @@ ChatsManager::ChatsManager(
settings_(settings),
historyController_(historyController),
whiteboardManager_(whiteboardManager),
- highlightManager_(highlightManager) {
+ highlightManager_(highlightManager),
+ clientBlockListManager_(clientBlockListManager) {
timerFactory_ = timerFactory;
eventController_ = eventController;
stanzaChannel_ = stanzaChannel;
@@ -523,7 +526,7 @@ ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact)
ChatController* ChatsManager::createNewChatController(const JID& contact) {
assert(chatControllers_.find(contact) == chatControllers_.end());
- ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_, highlightManager_);
+ ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_);
chatControllers_[contact] = controller;
controller->setAvailableServerFeatures(serverDiscoInfo_);
controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false));
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index 55e62b9..4d7e9a8 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -51,10 +51,11 @@ namespace Swift {
class WhiteboardManager;
class HistoryController;
class HighlightManager;
+ class ClientBlockListManager;
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, HistoryController* historyController_, WhiteboardManager* whiteboardManager, HighlightManager* highlightManager);
+ 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, HistoryController* historyController_, WhiteboardManager* whiteboardManager, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager);
virtual ~ChatsManager();
void setAvatarManager(AvatarManager* avatarManager);
void setOnline(bool enabled);
@@ -138,5 +139,6 @@ namespace Swift {
HistoryController* historyController_;
WhiteboardManager* whiteboardManager_;
HighlightManager* highlightManager_;
+ ClientBlockListManager* clientBlockListManager_;
};
}
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index dd90d66..84a407c 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -10,48 +10,49 @@
#include <boost/bind.hpp>
-#include "Swift/Controllers/Chat/ChatsManager.h"
-
-#include "Swift/Controllers/Chat/UnitTest/MockChatListWindow.h"
-#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
-#include "Swift/Controllers/Settings/DummySettingsProvider.h"
-#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
-#include "Swift/Controllers/UIInterfaces/ChatListWindowFactory.h"
-#include "Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h"
-#include "Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h"
-#include "Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h"
-#include "Swiften/Client/Client.h"
-#include "Swiften/Disco/EntityCapsManager.h"
-#include "Swiften/Disco/CapsProvider.h"
-#include "Swiften/MUC/MUCManager.h"
-#include "Swift/Controllers/Chat/ChatController.h"
-#include "Swift/Controllers/XMPPEvents/EventController.h"
-#include "Swift/Controllers/Chat/MUCController.h"
-#include "Swiften/Presence/StanzaChannelPresenceSender.h"
-#include "Swiften/Avatars/NullAvatarManager.h"
-#include "Swiften/Avatars/AvatarMemoryStorage.h"
-#include "Swiften/VCards/VCardManager.h"
-#include "Swiften/VCards/VCardMemoryStorage.h"
-#include "Swiften/Client/NickResolver.h"
-#include "Swiften/Presence/DirectedPresenceSender.h"
-#include "Swiften/Roster/XMPPRosterImpl.h"
-#include "Swift/Controllers/UnitTest/MockChatWindow.h"
-#include "Swiften/Client/DummyStanzaChannel.h"
-#include "Swiften/Queries/DummyIQChannel.h"
-#include "Swiften/Presence/PresenceOracle.h"
-#include "Swiften/Jingle/JingleSessionManager.h"
-#include "Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h"
-#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
-#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
-#include "Swift/Controllers/UIEvents/UIEventStream.h"
+#include <Swift/Controllers/Chat/ChatsManager.h>
+
+#include <Swift/Controllers/Chat/UnitTest/MockChatListWindow.h>
+#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
+#include <Swift/Controllers/Settings/DummySettingsProvider.h>
+#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h>
+#include <Swiften/Client/Client.h>
+#include <Swiften/Disco/EntityCapsManager.h>
+#include <Swiften/Disco/CapsProvider.h>
+#include <Swiften/MUC/MUCManager.h>
+#include <Swift/Controllers/Chat/ChatController.h>
+#include <Swift/Controllers/XMPPEvents/EventController.h>
+#include <Swift/Controllers/Chat/MUCController.h>
+#include <Swiften/Presence/StanzaChannelPresenceSender.h>
+#include <Swiften/Avatars/NullAvatarManager.h>
+#include <Swiften/Avatars/AvatarMemoryStorage.h>
+#include <Swiften/VCards/VCardManager.h>
+#include <Swiften/VCards/VCardMemoryStorage.h>
+#include <Swiften/Client/NickResolver.h>
+#include <Swiften/Presence/DirectedPresenceSender.h>
+#include <Swiften/Roster/XMPPRosterImpl.h>
+#include <Swift/Controllers/UnitTest/MockChatWindow.h>
+#include <Swiften/Client/DummyStanzaChannel.h>
+#include <Swiften/Queries/DummyIQChannel.h>
+#include <Swiften/Presence/PresenceOracle.h>
+#include <Swiften/Jingle/JingleSessionManager.h>
+#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
+#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
+#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/ProfileSettingsProvider.h>
-#include "Swift/Controllers/FileTransfer/FileTransferOverview.h"
-#include "Swiften/Elements/DeliveryReceiptRequest.h"
-#include "Swiften/Elements/DeliveryReceipt.h"
+#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
+#include <Swiften/Elements/DeliveryReceiptRequest.h>
+#include <Swiften/Elements/DeliveryReceipt.h>
#include <Swiften/Base/Algorithm.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swift/Controllers/WhiteboardManager.h>
#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
+#include <Swiften/Client/ClientBlockListManager.h>
using namespace Swift;
@@ -109,7 +110,8 @@ public:
highlightManager_ = new HighlightManager(settings_);
mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_);
- manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, NULL, wbManager_, highlightManager_);
+ clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
+ manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, NULL, wbManager_, highlightManager_, clientBlockListManager_);
manager_->setAvatarManager(avatarManager_);
}
@@ -120,6 +122,7 @@ public:
delete profileSettings_;
delete avatarManager_;
delete manager_;
+ delete clientBlockListManager_;
delete ftOverview_;
delete ftManager_;
delete wbSessionManager_;
@@ -484,6 +487,7 @@ private:
WhiteboardSessionManager* wbSessionManager_;
WhiteboardManager* wbManager_;
HighlightManager* highlightManager_;
+ ClientBlockListManager* clientBlockListManager_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest);
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 0c9c09c..32d045d 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -87,6 +87,8 @@
#include <Swiften/Client/StanzaChannel.h>
#include <Swift/Controllers/HighlightManager.h>
#include <Swift/Controllers/HighlightEditorController.h>
+#include <Swiften/Client/ClientBlockListManager.h>
+#include <Swift/Controllers/BlockListController.h>
namespace Swift {
@@ -130,6 +132,7 @@ MainController::MainController(
historyViewController_ = NULL;
eventWindowController_ = NULL;
profileController_ = NULL;
+ blockListController_ = NULL;
showProfileController_ = NULL;
contactEditController_ = NULL;
userSearchControllerChat_ = NULL;
@@ -321,11 +324,13 @@ void MainController::handleConnected() {
client_->getFileTransferManager()->startListeningOnPort(randomPort);
ftOverview_ = new FileTransferOverview(client_->getFileTransferManager());
fileTransferListController_->setFileTransferOverview(ftOverview_);
- rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_);
+ rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_, client_->getClientBlockListManager());
rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
rosterController_->getWindow()->onShowCertificateRequest.connect(boost::bind(&MainController::handleShowCertificateRequest, this));
+ blockListController_ = new BlockListController(client_->getClientBlockListManager(), uiEventStream_, uiFactory_, eventController_);
+
contactEditController_ = new ContactEditController(rosterController_, client_->getVCardManager(), uiFactory_, uiEventStream_);
whiteboardManager_ = new WhiteboardManager(uiFactory_, uiEventStream_, client_->getNickResolver(), client_->getWhiteboardSessionManager());
@@ -337,9 +342,9 @@ void MainController::handleConnected() {
#ifdef SWIFT_EXPERIMENTAL_HISTORY
historyController_ = new HistoryController(storages_->getHistoryStorage());
historyViewController_ = new HistoryViewController(jid_, uiEventStream_, historyController_, client_->getNickResolver(), client_->getAvatarManager(), client_->getPresenceOracle(), uiFactory_);
- 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_, historyController_, whiteboardManager_, highlightManager_);
+ 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_, historyController_, whiteboardManager_, highlightManager_, client_->getClientBlockListManager());
#else
- 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_, NULL, whiteboardManager_, highlightManager_);
+ 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_, NULL, whiteboardManager_, highlightManager_, client_->getClientBlockListManager());
#endif
client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
@@ -731,6 +736,10 @@ void MainController::handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo>
if (!error) {
chatsManager_->setServerDiscoInfo(info);
adHocManager_->setServerDiscoInfo(info);
+ if (info->hasFeature(DiscoInfo::BlockingCommandFeature)) {
+ rosterController_->getWindow()->setBlockingCommandAvailable(true);
+ rosterController_->initBlockingCommand();
+ }
}
}
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index 4f37e12..d60805a 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -74,6 +74,7 @@ namespace Swift {
class WhiteboardManager;
class HighlightManager;
class HighlightEditorController;
+ class BlockListController;
class MainController {
public:
@@ -154,6 +155,7 @@ namespace Swift {
HistoryViewController* historyViewController_;
HistoryController* historyController_;
FileTransferListController* fileTransferListController_;
+ BlockListController* blockListController_;
ChatsManager* chatsManager_;
ProfileController* profileController_;
ShowProfileController* showProfileController_;
diff --git a/Swift/Controllers/Roster/ContactRosterItem.cpp b/Swift/Controllers/Roster/ContactRosterItem.cpp
index f301552..bf85167 100644
--- a/Swift/Controllers/Roster/ContactRosterItem.cpp
+++ b/Swift/Controllers/Roster/ContactRosterItem.cpp
@@ -16,7 +16,7 @@
namespace Swift {
-ContactRosterItem::ContactRosterItem(const JID& jid, const JID& displayJID, const std::string& name, GroupRosterItem* parent) : RosterItem(name, parent), jid_(jid), displayJID_(displayJID) {
+ContactRosterItem::ContactRosterItem(const JID& jid, const JID& displayJID, const std::string& name, GroupRosterItem* parent) : RosterItem(name, parent), jid_(jid), displayJID_(displayJID), blockState_(BlockingNotSupported) {
}
ContactRosterItem::~ContactRosterItem() {
@@ -134,6 +134,14 @@ bool ContactRosterItem::supportsFeature(const Feature feature) const {
return features_.find(feature) != features_.end();
}
+void ContactRosterItem::setBlockState(BlockState state) {
+ blockState_ = state;
+}
+
+ContactRosterItem::BlockState ContactRosterItem::blockState() const {
+ return blockState_;
+}
+
}
diff --git a/Swift/Controllers/Roster/ContactRosterItem.h b/Swift/Controllers/Roster/ContactRosterItem.h
index 247c606..fc65d6d 100644
--- a/Swift/Controllers/Roster/ContactRosterItem.h
+++ b/Swift/Controllers/Roster/ContactRosterItem.h
@@ -28,6 +28,12 @@ class ContactRosterItem : public RosterItem {
FileTransferFeature,
WhiteboardFeature
};
+
+ enum BlockState {
+ BlockingNotSupported,
+ IsBlocked,
+ IsUnblocked
+ };
public:
ContactRosterItem(const JID& jid, const JID& displayJID, const std::string& name, GroupRosterItem* parent);
@@ -53,6 +59,9 @@ class ContactRosterItem : public RosterItem {
void setSupportedFeatures(const std::set<Feature>& features);
bool supportsFeature(Feature feature) const;
+ void setBlockState(BlockState state);
+ BlockState blockState() const;
+
private:
JID jid_;
JID displayJID_;
@@ -63,6 +72,7 @@ class ContactRosterItem : public RosterItem {
boost::shared_ptr<Presence> shownPresence_;
std::vector<std::string> groups_;
std::set<Feature> features_;
+ BlockState blockState_;
};
}
diff --git a/Swift/Controllers/Roster/Roster.cpp b/Swift/Controllers/Roster/Roster.cpp
index b5c5998..3d0ca2e 100644
--- a/Swift/Controllers/Roster/Roster.cpp
+++ b/Swift/Controllers/Roster/Roster.cpp
@@ -22,7 +22,7 @@
namespace Swift {
-Roster::Roster(bool sortByStatus, bool fullJIDMapping) {
+Roster::Roster(bool sortByStatus, bool fullJIDMapping) : blockingSupported_(false) {
sortByStatus_ = sortByStatus;
fullJIDMapping_ = fullJIDMapping;
root_ = new GroupRosterItem("Dummy-Root", NULL, sortByStatus_);
@@ -71,6 +71,28 @@ void Roster::setAvailableFeatures(const JID& jid, const std::set<ContactRosterIt
}
}
+void Roster::setBlockedState(const std::vector<JID> &jids, ContactRosterItem::BlockState state) {
+ if (!blockingSupported_ ) {
+ foreach(ItemMap::value_type i, itemMap_) {
+ foreach(ContactRosterItem* item, i.second) {
+ item->setBlockState(ContactRosterItem::IsUnblocked);
+ }
+ }
+ }
+
+ foreach(const JID& jid, jids) {
+ ItemMap::const_iterator i = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare());
+ if (i == itemMap_.end()) {
+ continue;
+ }
+ foreach(ContactRosterItem* item, i->second) {
+ item->setBlockState(state);
+ }
+ }
+
+ blockingSupported_ = true;
+}
+
void Roster::removeGroup(const std::string& group) {
root_->removeGroupChild(group);
}
@@ -87,6 +109,9 @@ void Roster::addContact(const JID& jid, const JID& displayJID, const std::string
GroupRosterItem* group(getGroup(groupName));
ContactRosterItem *item = new ContactRosterItem(jid, displayJID, name, group);
item->setAvatarPath(avatarPath);
+ if (blockingSupported_) {
+ item->setBlockState(ContactRosterItem::IsUnblocked);
+ }
group->addChild(item);
ItemMap::iterator i = itemMap_.insert(std::make_pair(fullJIDMapping_ ? jid : jid.toBare(), std::vector<ContactRosterItem*>())).first;
if (!i->second.empty()) {
diff --git a/Swift/Controllers/Roster/Roster.h b/Swift/Controllers/Roster/Roster.h
index 74547d6..91a152f 100644
--- a/Swift/Controllers/Roster/Roster.h
+++ b/Swift/Controllers/Roster/Roster.h
@@ -45,6 +45,7 @@ class Roster {
boost::signal<void (RosterItem*)> onDataChanged;
GroupRosterItem* getGroup(const std::string& groupName);
void setAvailableFeatures(const JID& jid, const std::set<ContactRosterItem::Feature>& features);
+ void setBlockedState(const std::vector<JID>& jids, ContactRosterItem::BlockState state);
private:
void handleDataChanged(RosterItem* item);
@@ -58,6 +59,7 @@ class Roster {
ItemMap itemMap_;
bool fullJIDMapping_;
bool sortByStatus_;
+ bool blockingSupported_;
};
}
diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp
index ec52993..d09ef4c 100644
--- a/Swift/Controllers/Roster/RosterController.cpp
+++ b/Swift/Controllers/Roster/RosterController.cpp
@@ -44,14 +44,15 @@
#include <Swiften/Disco/EntityCapsManager.h>
#include <Swiften/Jingle/JingleSessionManager.h>
#include <Swift/Controllers/SettingConstants.h>
+#include <Swiften/Client/ClientBlockListManager.h>
namespace Swift {
/**
* The controller does not gain ownership of these parameters.
*/
-RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsManager, FileTransferOverview* fileTransferOverview)
- : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), nickManager_(nickManager), nickResolver_(nickResolver), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview) {
+RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsManager, FileTransferOverview* fileTransferOverview, ClientBlockListManager* clientBlockListManager)
+ : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), nickManager_(nickManager), nickResolver_(nickResolver), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview), clientBlockListManager_(clientBlockListManager) {
assert(fileTransferOverview);
iqRouter_ = iqRouter;
presenceOracle_ = presenceOracle;
@@ -183,6 +184,20 @@ void RosterController::handleSettingChanged(const std::string& settingPath) {
}
}
+void RosterController::handleBlockingStateChanged() {
+ if (clientBlockListManager_->getBlockList()->getState() == BlockList::Available) {
+ roster_->setBlockedState(clientBlockListManager_->getBlockList()->getItems(), ContactRosterItem::IsBlocked);
+ }
+}
+
+void RosterController::handleBlockingItemAdded(const JID& jid) {
+ roster_->setBlockedState(std::vector<JID>(1, jid), ContactRosterItem::IsBlocked);
+}
+
+void RosterController::handleBlockingItemRemoved(const JID& jid) {
+ roster_->setBlockedState(std::vector<JID>(1, jid), ContactRosterItem::IsUnblocked);
+}
+
void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
if (boost::shared_ptr<AddContactUIEvent> addContactEvent = boost::dynamic_pointer_cast<AddContactUIEvent>(event)) {
RosterItemPayload item;
@@ -256,6 +271,18 @@ void RosterController::updateItem(const XMPPRosterItem& item) {
request->send();
}
+void RosterController::initBlockingCommand() {
+ boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+
+ blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&RosterController::handleBlockingStateChanged, this));
+ blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&RosterController::handleBlockingItemAdded, this, _1));
+ blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&RosterController::handleBlockingItemRemoved, this, _1));
+
+ if (blockList->getState() == BlockList::Available) {
+ roster_->setBlockedState(blockList->getItems(), ContactRosterItem::IsBlocked);
+ }
+}
+
void RosterController::handleRosterSetError(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload) {
if (!error) {
return;
diff --git a/Swift/Controllers/Roster/RosterController.h b/Swift/Controllers/Roster/RosterController.h
index ec07574..06b551e 100644
--- a/Swift/Controllers/Roster/RosterController.h
+++ b/Swift/Controllers/Roster/RosterController.h
@@ -39,10 +39,11 @@ namespace Swift {
class NickManager;
class EntityCapsProvider;
class FileTransferManager;
-
+ class ClientBlockListManager;
+
class RosterController {
public:
- RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview);
+ RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview, ClientBlockListManager* clientBlockListManager);
~RosterController();
void showRosterWindow();
MainWindow* getWindow() {return mainWindow_;}
@@ -57,6 +58,8 @@ namespace Swift {
void setContactGroups(const JID& jid, const std::vector<std::string>& groups);
void updateItem(const XMPPRosterItem&);
+ void initBlockingCommand();
+
private:
void handleOnJIDAdded(const JID &jid);
void handleRosterCleared();
@@ -76,6 +79,10 @@ namespace Swift {
void handleOnCapsChanged(const JID& jid);
void handleSettingChanged(const std::string& settingPath);
+ void handleBlockingStateChanged();
+ void handleBlockingItemAdded(const JID& jid);
+ void handleBlockingItemRemoved(const JID& jid);
+
JID myJID_;
XMPPRoster* xmppRoster_;
MainWindowFactory* mainWindowFactory_;
@@ -94,7 +101,11 @@ namespace Swift {
UIEventStream* uiEventStream_;
EntityCapsProvider* entityCapsManager_;
FileTransferOverview* ftOverview_;
+ ClientBlockListManager* clientBlockListManager_;
+ boost::bsignals::scoped_connection blockingOnStateChangedConnection_;
+ boost::bsignals::scoped_connection blockingOnItemAddedConnection_;
+ boost::bsignals::scoped_connection blockingOnItemRemovedConnection_;
boost::bsignals::scoped_connection changeStatusConnection_;
boost::bsignals::scoped_connection signOutConnection_;
boost::bsignals::scoped_connection uiEventConnection_;
diff --git a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
index e439c78..b0034e6 100644
--- a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
+++ b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
@@ -37,6 +37,7 @@
#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
#include <Swiften/Base/Algorithm.h>
#include <Swiften/EventLoop/DummyEventLoop.h>
+#include <Swiften/Client/ClientBlockListManager.h>
using namespace Swift;
@@ -82,12 +83,14 @@ class RosterControllerTest : public CppUnit::TestFixture {
ftManager_ = new DummyFileTransferManager();
ftOverview_ = new FileTransferOverview(ftManager_);
- rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickManager_, nickResolver_, presenceOracle_, subscriptionManager_, eventController_, uiEventStream_, router_, settings_, entityCapsManager_, ftOverview_);
+ clientBlockListManager_ = new ClientBlockListManager(router_);
+ rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickManager_, nickResolver_, presenceOracle_, subscriptionManager_, eventController_, uiEventStream_, router_, settings_, entityCapsManager_, ftOverview_, clientBlockListManager_);
mainWindow_ = mainWindowFactory_->last;
}
void tearDown() {
delete rosterController_;
+ delete clientBlockListManager_;
delete ftManager_;
delete jingleSessionManager_;
@@ -337,6 +340,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
JingleSessionManager* jingleSessionManager_;
FileTransferManager* ftManager_;
FileTransferOverview* ftOverview_;
+ ClientBlockListManager* clientBlockListManager_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(RosterControllerTest);
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index 26b9334..6f36a52 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -49,6 +49,7 @@ if env["SCONS_STAGE"] == "build" :
"HistoryViewController.cpp",
"HistoryController.cpp",
"FileTransferListController.cpp",
+ "BlockListController.cpp",
"StatusTracker.cpp",
"PresenceNotifier.cpp",
"EventNotifier.cpp",
diff --git a/Swift/Controllers/UIEvents/RequestBlockListDialogUIEvent.h b/Swift/Controllers/UIEvents/RequestBlockListDialogUIEvent.h
new file mode 100644
index 0000000..d29cb4f
--- /dev/null
+++ b/Swift/Controllers/UIEvents/RequestBlockListDialogUIEvent.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+namespace Swift {
+
+class RequestBlockListDialogUIEvent : public UIEvent {
+};
+
+}
diff --git a/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h b/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h
new file mode 100644
index 0000000..9b7abcb
--- /dev/null
+++ b/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+#include <Swiften/JID/JID.h>
+
+namespace Swift {
+
+class RequestChangeBlockStateUIEvent : public UIEvent {
+ public:
+ enum BlockState {
+ Blocked,
+ Unblocked
+ };
+
+ public:
+ RequestChangeBlockStateUIEvent(BlockState newState, const JID& contact) : state_(newState), contact_(contact) {}
+
+ BlockState getBlockState() const {
+ return state_;
+ }
+
+ JID getContact() const {
+ return contact_;
+ }
+ private:
+ BlockState state_;
+ JID contact_;
+};
+
+}
diff --git a/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h b/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h
new file mode 100644
index 0000000..60a1c11
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include <Swiften/JID/JID.h>
+#include <Swiften/Base/boost_bsignals.h>
+
+namespace Swift {
+
+ class ClientBlockListManager;
+
+ class BlockListEditorWidget {
+ public:
+ virtual ~BlockListEditorWidget() {}
+
+ virtual void show() = 0;
+
+ virtual void setCurrentBlockList(const std::vector<JID>& blockedJIDs) = 0;
+ virtual void setBusy(bool isBusy) = 0;
+
+ virtual std::vector<JID> getCurrentBlockList() const = 0;
+
+ boost::signal<void (const std::vector<JID>& /* blockedJID */)> onSetNewBlockList;
+ };
+
+}
diff --git a/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h b/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h
new file mode 100644
index 0000000..eb91ac1
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+namespace Swift {
+
+ class BlockListEditorWidget;
+
+ class BlockListEditorWidgetFactory {
+ public:
+ virtual ~BlockListEditorWidgetFactory() {}
+
+ virtual BlockListEditorWidget* createBlockListEditorWidget() = 0;
+ };
+
+}
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index d6b3656..b8e6722 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -39,6 +39,7 @@ namespace Swift {
enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite};
enum FileTransferState {WaitingForAccept, Negotiating, Transferring, Canceled, Finished, FTFailed};
enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected};
+ enum BlockingState {BlockingUnsupported, IsBlocked, IsUnblocked};
ChatWindow() {}
virtual ~ChatWindow() {}
@@ -89,6 +90,7 @@ 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;
/**
* Set an alert on the window.
* @param alertText Description of alert (required).
diff --git a/Swift/Controllers/UIInterfaces/MainWindow.h b/Swift/Controllers/UIInterfaces/MainWindow.h
index 2df2c10..3b10041 100644
--- a/Swift/Controllers/UIInterfaces/MainWindow.h
+++ b/Swift/Controllers/UIInterfaces/MainWindow.h
@@ -34,6 +34,7 @@ namespace Swift {
/** Must be able to cope with NULL to clear the roster */
virtual void setRosterModel(Roster* roster) = 0;
virtual void setConnecting() = 0;
+ virtual void setBlockingCommandAvailable(bool isAvailable) = 0;
virtual void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands) = 0;
virtual void setStreamEncryptionStatus(bool tlsInPlaceAndValid) = 0;
virtual void openCertificateDialog(const std::vector<Certificate::ref>& chain) = 0;
diff --git a/Swift/Controllers/UIInterfaces/UIFactory.h b/Swift/Controllers/UIInterfaces/UIFactory.h
index dcd1779..990dc98 100644
--- a/Swift/Controllers/UIInterfaces/UIFactory.h
+++ b/Swift/Controllers/UIInterfaces/UIFactory.h
@@ -22,6 +22,7 @@
#include <Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h>
#include <Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h>
+#include <Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h>
namespace Swift {
class UIFactory :
@@ -40,7 +41,8 @@ namespace Swift {
public AdHocCommandWindowFactory,
public FileTransferListWidgetFactory,
public WhiteboardWindowFactory,
- public HighlightEditorWidgetFactory {
+ public HighlightEditorWidgetFactory,
+ public BlockListEditorWidgetFactory {
public:
virtual ~UIFactory() {}
};
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index 84aaa04..8af65f7 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -60,6 +60,8 @@ namespace Swift {
virtual void setAvailableRoomActions(const std::vector<RoomAction> &) {}
virtual InviteToChatWindow* createInviteToChatWindow() {return NULL;}
+ virtual void setBlockingState(BlockingState) {}
+
std::string name_;
std::string lastMessageBody_;
std::vector<SecurityLabelsCatalog::Item> labels_;
diff --git a/Swift/Controllers/UnitTest/MockMainWindow.h b/Swift/Controllers/UnitTest/MockMainWindow.h
index 19ab522..69a4e25 100644
--- a/Swift/Controllers/UnitTest/MockMainWindow.h
+++ b/Swift/Controllers/UnitTest/MockMainWindow.h
@@ -24,6 +24,7 @@ namespace Swift {
virtual void setConnecting() {}
virtual void setStreamEncryptionStatus(bool /*tlsInPlaceAndValid*/) {}
virtual void openCertificateDialog(const std::vector<Certificate::ref>& /*chain*/) {}
+ virtual void setBlockingCommandAvailable(bool /*isAvailable*/) {}
Roster* roster;
};