From 2b6b227ef4ae0e68709d8ad327260cb8f609909c Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Mon, 18 Nov 2013 23:41:22 +0100
Subject: Convert Roster::setAvailableFeatures() and Roster::setBlockedState()
 to RosterItemOperations.

Change-Id: I67943bd50ca9eb4ae53e1acefbea1c7b67684cc9
License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.

diff --git a/Swift/Controllers/Roster/ContactRosterItem.cpp b/Swift/Controllers/Roster/ContactRosterItem.cpp
index 6239033..622b6ae 100644
--- a/Swift/Controllers/Roster/ContactRosterItem.cpp
+++ b/Swift/Controllers/Roster/ContactRosterItem.cpp
@@ -139,6 +139,7 @@ void ContactRosterItem::removeGroup(const std::string& group) {
 
 void ContactRosterItem::setSupportedFeatures(const std::set<Feature>& features) {
 	features_ = features;
+	onDataChanged();
 }
 
 bool ContactRosterItem::supportsFeature(const Feature feature) const {
diff --git a/Swift/Controllers/Roster/Roster.cpp b/Swift/Controllers/Roster/Roster.cpp
index dbb1780..51e888f 100644
--- a/Swift/Controllers/Roster/Roster.cpp
+++ b/Swift/Controllers/Roster/Roster.cpp
@@ -66,36 +66,15 @@ GroupRosterItem* Roster::getGroup(const std::string& groupName) {
 	return group;
 }
 
-void Roster::setAvailableFeatures(const JID& jid, const std::set<ContactRosterItem::Feature>& features) {
-	ItemMap::const_iterator i = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare());
-	if (i == itemMap_.end()) {
-		return;
-	}
-	foreach(ContactRosterItem* item, i->second) {
-		item->setSupportedFeatures(features);
-	}
-}
-
-void Roster::setBlockedState(const std::vector<JID> &jids, ContactRosterItem::BlockState state) {
-	if (!blockingSupported_ ) {
+void Roster::setBlockingSupported(bool isSupported) {
+	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;
+	blockingSupported_ = isSupported;
 }
 
 void Roster::removeGroup(const std::string& group) {
diff --git a/Swift/Controllers/Roster/Roster.h b/Swift/Controllers/Roster/Roster.h
index 821c8f5..9a1dfa3 100644
--- a/Swift/Controllers/Roster/Roster.h
+++ b/Swift/Controllers/Roster/Roster.h
@@ -47,8 +47,7 @@ class Roster {
 		boost::signal<void (RosterItem*)> onDataChanged;
 		boost::signal<void (JID&)> onVCardUpdateRequested;
 		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);
+		void setBlockingSupported(bool isSupported);
 
 	private:
 		void handleDataChanged(RosterItem* item);
diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp
index fd0dbb8..cb6d4d2 100644
--- a/Swift/Controllers/Roster/RosterController.cpp
+++ b/Swift/Controllers/Roster/RosterController.cpp
@@ -35,6 +35,8 @@
 #include <Swift/Controllers/Roster/Roster.h>
 #include <Swift/Controllers/Roster/RosterVCardProvider.h>
 #include <Swift/Controllers/Roster/SetAvatar.h>
+#include <Swift/Controllers/Roster/SetAvailableFeatures.h>
+#include <Swift/Controllers/Roster/SetBlockingState.h>
 #include <Swift/Controllers/Roster/SetName.h>
 #include <Swift/Controllers/Roster/SetPresence.h>
 #include <Swift/Controllers/Roster/SetVCard.h>
@@ -191,16 +193,18 @@ void RosterController::handleSettingChanged(const std::string& settingPath) {
 
 void RosterController::handleBlockingStateChanged() {
 	if (clientBlockListManager_->getBlockList()->getState() == BlockList::Available) {
-		roster_->setBlockedState(clientBlockListManager_->getBlockList()->getItems(), ContactRosterItem::IsBlocked);
+		foreach(const JID& jid, clientBlockListManager_->getBlockList()->getItems()) {
+			roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked));
+		}
 	}
 }
 
 void RosterController::handleBlockingItemAdded(const JID& jid) {
-	roster_->setBlockedState(std::vector<JID>(1, jid), ContactRosterItem::IsBlocked);
+	roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked));
 }
 
 void RosterController::handleBlockingItemRemoved(const JID& jid) {
-	roster_->setBlockedState(std::vector<JID>(1, jid), ContactRosterItem::IsUnblocked);
+	roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsUnblocked));
 }
 
 void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
@@ -282,9 +286,11 @@ void RosterController::initBlockingCommand() {
 	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));
-
+	roster_->setBlockingSupported(true);
 	if (blockList->getState() == BlockList::Available) {
-		roster_->setBlockedState(blockList->getItems(), ContactRosterItem::IsBlocked);
+		foreach(const JID& jid, blockList->getItems()) {
+			roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked));
+		}
 	}
 }
 
@@ -356,7 +362,7 @@ void RosterController::handleOnCapsChanged(const JID& jid) {
 		if (info->hasFeature(DiscoInfo::WhiteboardFeature)) {
 			features.insert(ContactRosterItem::WhiteboardFeature);
 		}
-		roster_->setAvailableFeatures(jid, features);
+		roster_->applyOnItems(SetAvailableFeatures(jid, features));
 	}
 }
 
diff --git a/Swift/Controllers/Roster/SetAvailableFeatures.h b/Swift/Controllers/Roster/SetAvailableFeatures.h
new file mode 100644
index 0000000..f7e00d0
--- /dev/null
+++ b/Swift/Controllers/Roster/SetAvailableFeatures.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/Roster/RosterItemOperation.h>
+#include <Swift/Controllers/Roster/ContactRosterItem.h>
+
+namespace Swift {
+
+class RosterItem;
+
+class SetAvailableFeatures : public RosterItemOperation {
+	public:
+		SetAvailableFeatures(const JID& jid, const std::set<ContactRosterItem::Feature>& availableFeatures, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), availableFeatures_(availableFeatures), compareType_(compareType) {
+		}
+
+		virtual void operator() (RosterItem* item) const {
+			ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+			if (contact && contact->getJID().equals(jid_, compareType_)) {
+				contact->setSupportedFeatures(availableFeatures_);
+			}
+		}
+
+	private:
+		JID jid_;
+		std::set<ContactRosterItem::Feature> availableFeatures_;
+		JID::CompareType compareType_;
+};
+
+}
diff --git a/Swift/Controllers/Roster/SetBlockingState.h b/Swift/Controllers/Roster/SetBlockingState.h
new file mode 100644
index 0000000..72fd2e5
--- /dev/null
+++ b/Swift/Controllers/Roster/SetBlockingState.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/Roster/RosterItemOperation.h>
+#include <Swift/Controllers/Roster/ContactRosterItem.h>
+
+namespace Swift {
+
+class RosterItem;
+
+class SetBlockingState : public RosterItemOperation {
+	public:
+		SetBlockingState(const JID& jid, ContactRosterItem::BlockState state, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), state_(state), compareType_(compareType) {
+		}
+
+		virtual void operator() (RosterItem* item) const {
+			ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+			if (contact && contact->getJID().equals(jid_, compareType_)) {
+				contact->setBlockState(state_);
+			}
+		}
+
+	private:
+		JID jid_;
+		ContactRosterItem::BlockState state_;
+		JID::CompareType compareType_;
+};
+
+}
-- 
cgit v0.10.2-6-g49f6