From 59d973448045888d2ffa8e5cd949357d9c93ead3 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Tue, 13 Apr 2010 08:38:37 +0100
Subject: Don't lose presence when receiving a roster item rename push

Resolves: #312

diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index c9ba612..17fd2e9 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -23,6 +23,7 @@
 #include "Swiften/Roster/SetPresence.h"
 #include "Swiften/Roster/AppearOffline.h"
 #include "Swiften/Roster/SetAvatar.h"
+#include "Swiften/Roster/SetName.h"
 #include "Swiften/Roster/OfflineRosterFilter.h"
 #include "Swiften/Roster/OpenChatRosterAction.h"
 #include "Swiften/Roster/TreeWidgetFactory.h"
@@ -144,9 +145,7 @@ void RosterController::handleOnJIDRemoved(const JID& jid) {
 
 void RosterController::handleOnJIDUpdated(const JID& jid, const String& oldName, const std::vector<String> passedOldGroups) {
 	if (oldName != xmppRoster_->getNameForJID(jid)) {
-		handleOnJIDRemoved(jid);
-		handleOnJIDAdded(jid);
-		//FIXME: use a roster visitor to avoid losing presence.
+		roster_->applyOnItems(SetName(xmppRoster_->getNameForJID(jid), jid));
 		return;
 	}
 	std::vector<String> groups = xmppRoster_->getGroupsForJID(jid);
diff --git a/Swiften/Roster/ContactRosterItem.cpp b/Swiften/Roster/ContactRosterItem.cpp
index 06f8536..39e96bd 100644
--- a/Swiften/Roster/ContactRosterItem.cpp
+++ b/Swiften/Roster/ContactRosterItem.cpp
@@ -22,6 +22,10 @@ ContactRosterItem::~ContactRosterItem() {
 	delete widget_;
 }
 
+void ContactRosterItem::setName(const String& name) {
+	widget_->setText(name);
+}
+
 StatusShow::Type ContactRosterItem::getStatusShow() {
 	return statusShow_;
 }
diff --git a/Swiften/Roster/ContactRosterItem.h b/Swiften/Roster/ContactRosterItem.h
index 1c189f4..92b3056 100644
--- a/Swiften/Roster/ContactRosterItem.h
+++ b/Swiften/Roster/ContactRosterItem.h
@@ -32,6 +32,7 @@ class ContactRosterItem : public RosterItem {
 		void setStatusText(const String& status);
 		void setAvatarPath(const String& path);
 		const JID& getJID() const;
+		void setName(const String& name);
 		void show();
 		void hide();
 
diff --git a/Swiften/Roster/SetName.h b/Swiften/Roster/SetName.h
new file mode 100644
index 0000000..17bc2ea
--- /dev/null
+++ b/Swiften/Roster/SetName.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include "Swiften/JID/JID.h"
+#include "Swiften/Roster/RosterItemOperation.h"
+#include "Swiften/Roster/ContactRosterItem.h"
+
+namespace Swift {
+
+class RosterItem;
+
+class SetName : public RosterItemOperation {
+	public:
+		SetName(const String& name, const JID& jid, JID::CompareType compareType = JID::WithoutResource) : name_(name), jid_(jid), compareType_(compareType) {
+		}
+
+		virtual void operator() (RosterItem* item) const {
+			ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+			if (contact && contact->getJID().equals(jid_, compareType_)) {
+				contact->setName(name_);
+			}
+		}
+	
+	private:
+		String name_;
+		JID jid_;
+		JID::CompareType compareType_;
+};
+
+}
+
+
-- 
cgit v0.10.2-6-g49f6