From 0571ecb72660dbdbe06d524eb62e5398dca45586 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Fri, 27 Aug 2010 12:58:06 +0100
Subject: Use own nick at top of roster.

Currently doesn't work because onOwnVCardChanged isn't plumbed in.

diff --git a/.project b/.project
index 17363c7..fcdfcdc 100644
--- a/.project
+++ b/.project
@@ -18,7 +18,7 @@
 				</dictionary>
 				<dictionary>
 					<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
-					<value>check=1 QA</value>
+					<value></value>
 				</dictionary>
 				<dictionary>
 					<key>org.eclipse.cdt.make.core.buildArguments</key>
@@ -29,10 +29,6 @@
 					<value>python</value>
 				</dictionary>
 				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildLocation</key>
-					<value></value>
-				</dictionary>
-				<dictionary>
 					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
 					<value>-c</value>
 				</dictionary>
@@ -54,7 +50,7 @@
 				</dictionary>
 				<dictionary>
 					<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
-					<value>check=1 QA</value>
+					<value></value>
 				</dictionary>
 				<dictionary>
 					<key>org.eclipse.cdt.make.core.stopOnError</key>
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index d5686bd..1676403 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -60,7 +60,7 @@ public:
 		eventController_ = new EventController();
 		chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
 		xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
-		nickResolver_ = new NickResolver(xmppRoster_);
+		nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL);
 		presenceOracle_ = new PresenceOracle(stanzaChannel_);
 		serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
 		presenceSender_ = new PresenceSender(stanzaChannel_);
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 1032de1..f4d67f6 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -221,18 +221,18 @@ void MainController::handleConnected() {
 	loginWindow_->setIsLoggingIn(false);
 	resetCurrentError();
 	resetPendingReconnects();
-	//FIXME: this freshLogin thing is temporary so I can see what's what before I split into a seperate method.
 	bool freshLogin = rosterController_ == NULL;
 	if (freshLogin) {
 		serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
 		xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
 		presenceOracle_ = new PresenceOracle(client_);
-		nickResolver_ = new NickResolver(xmppRoster_);		
 
 		vcardManager_ = new VCardManager(jid_, client_, getVCardStorageForProfile(jid_));
 		vcardManager_->onOwnVCardChanged.connect(boost::bind(&MainController::handleOwnVCardReceived, this, _1));
 		avatarManager_ = new AvatarManager(vcardManager_, client_, avatarStorage_);
 
+		nickResolver_ = new NickResolver(this->jid_.toBare(), xmppRoster_, vcardManager_);
+
 		rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickResolver_, presenceOracle_, eventController_, uiEventStream_, client_);
 		rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
 		rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
diff --git a/Swift/Controllers/NickResolver.cpp b/Swift/Controllers/NickResolver.cpp
index 29ff51b..1d2a3a0 100644
--- a/Swift/Controllers/NickResolver.cpp
+++ b/Swift/Controllers/NickResolver.cpp
@@ -7,14 +7,22 @@
 #include "Swift/Controllers/NickResolver.h"
 
 #include <boost/shared_ptr.hpp>
+#include <boost/bind.hpp>
 
 #include "Swiften/MUC/MUCRegistry.h"
 #include "Swiften/Roster/XMPPRoster.h"
+#include "Swiften/VCards/VCardManager.h"
 
 namespace Swift {
 
-NickResolver::NickResolver(boost::shared_ptr<XMPPRoster> xmppRoster) {
+NickResolver::NickResolver(const JID& ownJID, boost::shared_ptr<XMPPRoster> xmppRoster, VCardManager* vcardManager) : ownJID_(ownJID) {
 	xmppRoster_ = xmppRoster;
+	vcardManager_ = vcardManager;
+	if (vcardManager_) {
+		vcardManager_->onOwnVCardChanged.connect(boost::bind(&NickResolver::handleOwnVCardReceived, this, _1));
+		VCard::ref ownVCard = vcardManager_->getVCardAndRequestWhenNeeded(ownJID_);
+		handleOwnVCardReceived(ownVCard);
+	}
 	mucRegistry_ = NULL;
 }
 
@@ -23,6 +31,11 @@ void NickResolver::setMUCRegistry(MUCRegistry* mucRegistry) {
 }
 
 String NickResolver::jidToNick(const JID& jid) {
+	if (jid.toBare() == ownJID_) {
+		if (!ownNick_.isEmpty()) {
+			return ownNick_;
+		}
+	}
 	String nick;
 
 	if (mucRegistry_ && mucRegistry_->isMUC(jid.toBare()) ) {
@@ -37,5 +50,22 @@ String NickResolver::jidToNick(const JID& jid) {
 	return (it == map_.end()) ? jid.toBare() : it->second;
 }
 
+void NickResolver::handleOwnVCardReceived(VCard::ref ownVCard) {
+	String initialNick = ownNick_;
+	ownNick_ = ownJID_.toString();
+	if (ownVCard) {
+		if (!ownVCard->getNickname().isEmpty()) {
+			ownNick_ = ownVCard->getNickname();
+		} else if (!ownVCard->getGivenName().isEmpty()) {
+			ownNick_ = ownVCard->getGivenName();
+		} else if (!ownVCard->getFullName().isEmpty()) {
+			ownNick_ = ownVCard->getFullName();
+		}
+	}
+	if (ownNick_ != initialNick) {
+		onOwnNickChanged(ownNick_);
+	}
+}
+
 }
 
diff --git a/Swift/Controllers/NickResolver.h b/Swift/Controllers/NickResolver.h
index c85274a..4abb71d 100644
--- a/Swift/Controllers/NickResolver.h
+++ b/Swift/Controllers/NickResolver.h
@@ -8,23 +8,33 @@
 #define SWIFTEN_NickResolver_H
 
 #include <map>
+#include <boost/signals.hpp>
 #include <boost/shared_ptr.hpp>
 
 #include "Swiften/Base/String.h"
 #include "Swiften/JID/JID.h"
+#include "Swiften/Elements/VCard.h"
 
 namespace Swift {
 	class XMPPRoster;
 	class MUCRegistry;
+	class VCardManager;
 	class NickResolver {
 		public:
-			NickResolver(boost::shared_ptr<XMPPRoster> xmppRoster);
+			NickResolver(const JID& ownJID, boost::shared_ptr<XMPPRoster> xmppRoster, VCardManager* vcardManager);
 			String jidToNick(const JID& jid);
 			void setMUCRegistry(MUCRegistry* registry);
+
+			boost::signal<void (const String&)> onOwnNickChanged;
 		private:
+			void handleOwnVCardReceived(VCard::ref vCard);
+			JID ownJID_;
+			String ownNick_;
 			std::map<JID, String> map_;
+
 			boost::shared_ptr<XMPPRoster> xmppRoster_;
 			MUCRegistry* mucRegistry_;
+			VCardManager* vcardManager_;
 	};
 }
 #endif
diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index 46248a1..5ba00e4 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -66,10 +66,16 @@ RosterController::~RosterController() {
 void RosterController::setNickResolver(NickResolver* nickResolver) {
 	nickResolver_ = nickResolver;
 	if (nickResolver_ != NULL) {
-		mainWindow_->setMyName(nickResolver_->jidToNick(myJID_));
+		handleOwnNickChanged(nickResolver_->jidToNick(myJID_));
+
+		nickResolver_->onOwnNickChanged.connect(boost::bind(&RosterController::handleOwnNickChanged, this, _1));
 	}
 }
 
+void RosterController::handleOwnNickChanged(const String& nick) {
+	mainWindow_->setMyName(nick);
+}
+
 void RosterController::setAvatarManager(AvatarManager* avatarManager) {
 	if (avatarManager_ != NULL) {
 		//FIXME: disconnect old signal;
diff --git a/Swift/Controllers/RosterController.h b/Swift/Controllers/RosterController.h
index b01db96..18f6c92 100644
--- a/Swift/Controllers/RosterController.h
+++ b/Swift/Controllers/RosterController.h
@@ -56,6 +56,7 @@ namespace Swift {
 			void handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event);
 			void handleUIEvent(boost::shared_ptr<UIEvent> event);
 			void handleRosterSetError(boost::optional<ErrorPayload> error, boost::shared_ptr<RosterPayload> rosterPayload);
+			void handleOwnNickChanged(const String& nick);
 			JID myJID_;
 			boost::shared_ptr<XMPPRoster> xmppRoster_;
 			MainWindowFactory* mainWindowFactory_;
diff --git a/Swift/Controllers/UnitTest/NickResolverTest.cpp b/Swift/Controllers/UnitTest/NickResolverTest.cpp
index 913bdcc..67b42ac 100644
--- a/Swift/Controllers/UnitTest/NickResolverTest.cpp
+++ b/Swift/Controllers/UnitTest/NickResolverTest.cpp
@@ -10,6 +10,10 @@
 #include "Swift/Controllers/NickResolver.h"
 #include "Swift/Controllers/UnitTest/MockMUCRegistry.h"
 #include "Swiften/Roster/XMPPRoster.h"
+#include "Swiften/VCards/VCardManager.h"
+#include "Swiften/VCards/VCardMemoryStorage.h"
+#include "Swiften/Queries/IQRouter.h"
+#include "Swiften/Client/DummyStanzaChannel.h"
 
 using namespace Swift;
 
@@ -24,80 +28,124 @@ class NickResolverTest : public CppUnit::TestFixture
 		CPPUNIT_TEST(testMUCNick);
 		CPPUNIT_TEST(testMUCNoNick);
 		CPPUNIT_TEST(testRemovedMatch);
+		CPPUNIT_TEST(testOwnNickFullOnly);
+		CPPUNIT_TEST(testOwnNickGivenAndFull);
+		CPPUNIT_TEST(testOwnNickNickEtAl);
 		CPPUNIT_TEST_SUITE_END();
 
 		std::vector<String> groups_;
+		boost::shared_ptr<XMPPRoster> xmppRoster_;
+		VCardStorage* vCardStorage_;
+		IQRouter* iqRouter_;
+		DummyStanzaChannel* stanzaChannel_;
+		VCardManager* vCardManager_;
+		NickResolver* resolver_;
+		JID ownJID_;
 
 	public:
 		NickResolverTest() {}
 
+		void setUp() {
+			ownJID_ = JID("kev@wonderland.lit");
+			xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
+			stanzaChannel_ = new DummyStanzaChannel();
+		  iqRouter_ = new IQRouter(stanzaChannel_);
+			vCardStorage_ = new VCardMemoryStorage();
+			vCardManager_ = new VCardManager(ownJID_, iqRouter_, vCardStorage_);
+			resolver_ = new NickResolver(ownJID_, xmppRoster_, vCardManager_);
+		}
+
+		void tearDown() {
+			delete vCardManager_;
+			delete stanzaChannel_;
+			delete iqRouter_;
+			delete vCardStorage_;
+			delete resolver_;
+		}
+
 		void testMUCNick() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			NickResolver resolver(xmppRoster);
 			MockMUCRegistry registry;
-			resolver.setMUCRegistry(&registry);
+			resolver_->setMUCRegistry(&registry);
 			registry.setNext(true);
 			JID testJID("foo@bar/baz");
 
-			CPPUNIT_ASSERT_EQUAL(String("baz"), resolver.jidToNick(testJID));
+			CPPUNIT_ASSERT_EQUAL(String("baz"), resolver_->jidToNick(testJID));
 		}
 
 		void testMUCNoNick() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			NickResolver resolver(xmppRoster);
 			MockMUCRegistry registry;
-			resolver.setMUCRegistry(&registry);
+			resolver_->setMUCRegistry(&registry);
 			registry.setNext(true);
 			JID testJID("foo@bar");
 
-			CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver.jidToNick(testJID));
+			CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver_->jidToNick(testJID));
 		}
 
 
 		void testNoMatch() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			NickResolver resolver(xmppRoster);
 			JID testJID("foo@bar/baz");
 
-			CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver.jidToNick(testJID));
+			CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver_->jidToNick(testJID));
 		}
 		
 		void testZeroLengthMatch() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			NickResolver resolver(xmppRoster);
 			JID testJID("foo@bar/baz");
-			xmppRoster->addContact(testJID, "", groups_, RosterItemPayload::Both);
-			CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver.jidToNick(testJID));
+			xmppRoster_->addContact(testJID, "", groups_, RosterItemPayload::Both);
+			CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver_->jidToNick(testJID));
 		}
 
 		void testMatch() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			NickResolver resolver(xmppRoster);
 			JID testJID("foo@bar/baz");
-			xmppRoster->addContact(testJID, "Test", groups_, RosterItemPayload::Both);
+			xmppRoster_->addContact(testJID, "Test", groups_, RosterItemPayload::Both);
 
-			CPPUNIT_ASSERT_EQUAL(String("Test"), resolver.jidToNick(testJID));
+			CPPUNIT_ASSERT_EQUAL(String("Test"), resolver_->jidToNick(testJID));
 		}
 
 		void testOverwrittenMatch() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			NickResolver resolver(xmppRoster);
 			JID testJID("foo@bar/baz");
-			xmppRoster->addContact(testJID, "FailTest", groups_, RosterItemPayload::Both);
-			xmppRoster->addContact(testJID, "Test", groups_, RosterItemPayload::Both);
+			xmppRoster_->addContact(testJID, "FailTest", groups_, RosterItemPayload::Both);
+			xmppRoster_->addContact(testJID, "Test", groups_, RosterItemPayload::Both);
 
-			CPPUNIT_ASSERT_EQUAL(String("Test"), resolver.jidToNick(testJID));
+			CPPUNIT_ASSERT_EQUAL(String("Test"), resolver_->jidToNick(testJID));
 		}
 
 		void testRemovedMatch() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			NickResolver resolver(xmppRoster);
 			JID testJID("foo@bar/baz");
-			xmppRoster->addContact(testJID, "FailTest", groups_, RosterItemPayload::Both);
-			xmppRoster->removeContact(testJID);
-			CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver.jidToNick(testJID));
+			xmppRoster_->addContact(testJID, "FailTest", groups_, RosterItemPayload::Both);
+			xmppRoster_->removeContact(testJID);
+			CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver_->jidToNick(testJID));
+		}
+
+		void testOwnNickFullOnly() {
+			populateOwnVCard("", "", "Kevin Smith");
+			CPPUNIT_ASSERT_EQUAL(String("Kevin Smith"), resolver_->jidToNick(ownJID_));
 		}
 
+		void testOwnNickGivenAndFull() {
+			populateOwnVCard("", "Kevin", "Kevin Smith");
+			CPPUNIT_ASSERT_EQUAL(String("Kevin"), resolver_->jidToNick(ownJID_));
+		}
+
+		void testOwnNickNickEtAl() {
+			populateOwnVCard("Kev", "Kevin", "Kevin Smith");
+			CPPUNIT_ASSERT_EQUAL(String("Kev"), resolver_->jidToNick(ownJID_));
+		}
+
+		void populateOwnVCard(const String& nick, const String& given, const String& full) {
+			VCard::ref vcard(new VCard());
+			if (!nick.isEmpty()) {
+				vcard->setNickname(nick);
+			}
+			if (!given.isEmpty()) {
+				vcard->setGivenName(given);
+			}
+			if (!full.isEmpty()) {
+				vcard->setFullName(full);
+			}
+			vCardManager_->requestVCard(ownJID_);
+			IQ::ref result(IQ::createResult(JID(), stanzaChannel_->sentStanzas[0]->getID(), vcard));
+			stanzaChannel_->onIQReceived(result);
+		}
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(NickResolverTest);
diff --git a/Swift/Controllers/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/UnitTest/RosterControllerTest.cpp
index c8eb1dc..f57240f 100644
--- a/Swift/Controllers/UnitTest/RosterControllerTest.cpp
+++ b/Swift/Controllers/UnitTest/RosterControllerTest.cpp
@@ -44,7 +44,7 @@ class RosterControllerTest : public CppUnit::TestFixture
 			xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
 			avatarManager_ = NULL;//new AvatarManager();
 			mainWindowFactory_ = new MockMainWindowFactory();
-			nickResolver_ = new NickResolver(xmppRoster_);
+			nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL);
 			channel_ = new DummyIQChannel();
 			router_ = new IQRouter(channel_);
 			stanzaChannel_ = new DummyStanzaChannel();
-- 
cgit v0.10.2-6-g49f6