From e4807335c4e38dc2f047d400641c65448854b062 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sat, 26 Feb 2011 15:34:03 +0100
Subject: Add "Edit details" section to Add User widget.

Resolves: #618

diff --git a/Swift/Controllers/Chat/UserSearchController.cpp b/Swift/Controllers/Chat/UserSearchController.cpp
index 37059c2..b3403d7 100644
--- a/Swift/Controllers/Chat/UserSearchController.cpp
+++ b/Swift/Controllers/Chat/UserSearchController.cpp
@@ -18,9 +18,10 @@
 #include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
 #include <Swift/Controllers/UIInterfaces/UserSearchWindow.h>
 #include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h>
+#include <Swift/Controllers/Roster/RosterController.h>
 
 namespace Swift {
-UserSearchController::UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, UserSearchWindowFactory* factory, IQRouter* iqRouter) : type_(type), jid_(jid), uiEventStream_(uiEventStream), factory_(factory), iqRouter_(iqRouter) {
+UserSearchController::UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, UserSearchWindowFactory* factory, IQRouter* iqRouter, RosterController* rosterController) : type_(type), jid_(jid), uiEventStream_(uiEventStream), factory_(factory), iqRouter_(iqRouter), rosterController_(rosterController) {
 	uiEventStream_->onUIEvent.connect(boost::bind(&UserSearchController::handleUIEvent, this, _1));
 	window_ = NULL;
 	discoWalker_ = NULL;
@@ -50,7 +51,7 @@ void UserSearchController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
 	}
 	if (handle) {
 		if (!window_) {
-			window_ = factory_->createUserSearchWindow(type_ == AddContact ? UserSearchWindow::AddContact : UserSearchWindow::ChatToContact, uiEventStream_);
+			window_ = factory_->createUserSearchWindow(type_ == AddContact ? UserSearchWindow::AddContact : UserSearchWindow::ChatToContact, uiEventStream_, rosterController_->getGroups());
 			window_->onFormRequested.connect(boost::bind(&UserSearchController::handleFormRequested, this, _1));
 			window_->onSearchRequested.connect(boost::bind(&UserSearchController::handleSearch, this, _1, _2));
 			window_->setSelectedService(JID(jid_.getDomain()));
diff --git a/Swift/Controllers/Chat/UserSearchController.h b/Swift/Controllers/Chat/UserSearchController.h
index 69795fb..071ec33 100644
--- a/Swift/Controllers/Chat/UserSearchController.h
+++ b/Swift/Controllers/Chat/UserSearchController.h
@@ -25,6 +25,7 @@ namespace Swift {
 	class UserSearchWindowFactory;
 	class IQRouter;
 	class DiscoServiceWalker;
+	class RosterController;
 
 	class UserSearchResult {
 		public:
@@ -39,7 +40,7 @@ namespace Swift {
 	class UserSearchController {
 		public:
 			enum Type {AddContact, StartChat};
-			UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, UserSearchWindowFactory* userSearchWindowFactory, IQRouter* iqRouter);
+			UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, UserSearchWindowFactory* userSearchWindowFactory, IQRouter* iqRouter, RosterController* rosterController);
 			~UserSearchController();
 
 		private:
@@ -58,6 +59,7 @@ namespace Swift {
 			UIEventStream* uiEventStream_;
 			UserSearchWindowFactory* factory_;
 			IQRouter* iqRouter_;
+			RosterController* rosterController_;
 			UserSearchWindow* window_;
 			DiscoServiceWalker* discoWalker_;
 	};
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index adde70a..d499335 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -262,8 +262,8 @@ void MainController::handleConnected() {
 		client_->getDiscoManager()->setDiscoInfo(discoInfo);
 
 
-		userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, uiFactory_, client_->getIQRouter());
-		userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, uiFactory_, client_->getIQRouter());
+		userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, uiFactory_, client_->getIQRouter(), rosterController_);
+		userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, uiFactory_, client_->getIQRouter(), rosterController_);
 	}
 	
 	client_->requestRoster();
diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp
index 83291e4..706f50a 100644
--- a/Swift/Controllers/Roster/RosterController.cpp
+++ b/Swift/Controllers/Roster/RosterController.cpp
@@ -180,6 +180,7 @@ void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
 		RosterItemPayload item;
 		item.setName(addContactEvent->getName());
 		item.setJID(addContactEvent->getJID());
+		item.setGroups(std::vector<std::string>(addContactEvent->getGroups().begin(), addContactEvent->getGroups().end()));
 		boost::shared_ptr<RosterPayload> roster(new RosterPayload());
 		roster->addItem(item);
 		SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_);
diff --git a/Swift/Controllers/UIEvents/AddContactUIEvent.h b/Swift/Controllers/UIEvents/AddContactUIEvent.h
index b2bf5ce..d92d3af 100644
--- a/Swift/Controllers/UIEvents/AddContactUIEvent.h
+++ b/Swift/Controllers/UIEvents/AddContactUIEvent.h
@@ -7,17 +7,30 @@
 #pragma once
 
 #include <string>
+#include <set>
 
 #include "Swift/Controllers/UIEvents/UIEvent.h"
 
 namespace Swift {
 	class AddContactUIEvent : public UIEvent {
 		public:
-			AddContactUIEvent(const JID& jid, const std::string& name) : jid_(jid), name_(name) {};
-			std::string getName() {return name_;};
-			JID getJID() {return jid_;};
+			AddContactUIEvent(const JID& jid, const std::string& name, const std::set<std::string>& groups) : jid_(jid), name_(name), groups_(groups) {};
+
+			const std::string& getName() const {
+				return name_;
+			};
+
+			const JID& getJID() const {
+				return jid_;
+			};
+
+			const std::set<std::string>& getGroups() const {
+				return groups_;
+			}
+
 		private:
 			JID jid_;
 			std::string name_;
+			std::set<std::string> groups_;
 	};
 }
diff --git a/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h b/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h
index 88e0a07..2a15806 100644
--- a/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h
@@ -6,6 +6,8 @@
 
 #pragma once
 
+#include <set>
+
 #include "Swift/Controllers/UIInterfaces/UserSearchWindow.h"
 
 namespace Swift {
@@ -14,6 +16,6 @@ namespace Swift {
 		public:
 			virtual ~UserSearchWindowFactory() {};
 
-			virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream) = 0;
+			virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) = 0;
 	};
 }
diff --git a/Swift/QtUI/QtContactEditWidget.cpp b/Swift/QtUI/QtContactEditWidget.cpp
index fbc9685..a5134e4 100644
--- a/Swift/QtUI/QtContactEditWidget.cpp
+++ b/Swift/QtUI/QtContactEditWidget.cpp
@@ -90,4 +90,11 @@ std::set<std::string> QtContactEditWidget::getSelectedGroups() const {
 	return groups;
 }
 
+void QtContactEditWidget::clear() {
+	name_->clear();
+	setSelectedGroups(std::vector<std::string>());
+	newGroup_->setChecked(false);
+	newGroupName_->clear();
+}
+
 }
diff --git a/Swift/QtUI/QtContactEditWidget.h b/Swift/QtUI/QtContactEditWidget.h
index 26a9968..8ff267d 100644
--- a/Swift/QtUI/QtContactEditWidget.h
+++ b/Swift/QtUI/QtContactEditWidget.h
@@ -30,6 +30,8 @@ namespace Swift {
 			void setSelectedGroups(const std::vector<std::string>& groups);
 			std::set<std::string> getSelectedGroups() const;
 
+			void clear();
+
 		private:
 			typedef std::map<std::string, QCheckBox*> CheckBoxMap;
 			CheckBoxMap checkBoxes_;
diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp
index 4832205..35fbfcd 100644
--- a/Swift/QtUI/QtUIFactory.cpp
+++ b/Swift/QtUI/QtUIFactory.cpp
@@ -83,8 +83,8 @@ ChatWindow* QtUIFactory::createChatWindow(const JID& contact, UIEventStream* eve
 	return chatWindowFactory->createChatWindow(contact, eventStream);
 }
 
-UserSearchWindow* QtUIFactory::createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream) {
-	return new QtUserSearchWindow(eventStream, type);
+UserSearchWindow* QtUIFactory::createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) {
+	return new QtUserSearchWindow(eventStream, type, groups);
 };
 
 JoinMUCWindow* QtUIFactory::createJoinMUCWindow() {
diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h
index aa88fa3..ddaaf6e 100644
--- a/Swift/QtUI/QtUIFactory.h
+++ b/Swift/QtUI/QtUIFactory.h
@@ -33,7 +33,7 @@ namespace Swift {
 			virtual ChatListWindow* createChatListWindow(UIEventStream*);
 			virtual MUCSearchWindow* createMUCSearchWindow();
 			virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
-			virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream);
+			virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups);
 			virtual JoinMUCWindow* createJoinMUCWindow();
 			virtual ProfileWindow* createProfileWindow();
 			virtual ContactEditWindow* createContactEditWindow();
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index ee720a1..b8c3ebe 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -121,6 +121,7 @@ sources = [
     "UserSearch/QtUserSearchFirstPage.cpp",
     "UserSearch/QtUserSearchFieldsPage.cpp",
     "UserSearch/QtUserSearchResultsPage.cpp",
+    "UserSearch/QtUserSearchDetailsPage.cpp",
     "UserSearch/QtUserSearchWindow.cpp",
     "UserSearch/UserSearchModel.cpp",
     "UserSearch/UserSearchDelegate.cpp",
diff --git a/Swift/QtUI/UserSearch/QtUserSearchResultsPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchResultsPage.cpp
index c5fa85a..bc6933e7 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchResultsPage.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchResultsPage.cpp
@@ -11,7 +11,7 @@ namespace Swift {
 QtUserSearchResultsPage::QtUserSearchResultsPage() {
 	setupUi(this);
 	connect(results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(emitCompletenessCheck()));
-	connect(results_, SIGNAL(activated(const QModelIndex&)), this, SIGNAL(onUserTriggersFinish()));
+	connect(results_, SIGNAL(activated(const QModelIndex&)), this, SIGNAL(onUserTriggersContinue()));
 	connect(results_, SIGNAL(clicked(const QModelIndex&)), this, SLOT(emitCompletenessCheck()));
 	connect(results_, SIGNAL(entered(const QModelIndex&)), this, SLOT(emitCompletenessCheck()));
 	results_->setExpandsOnDoubleClick(false);
diff --git a/Swift/QtUI/UserSearch/QtUserSearchResultsPage.h b/Swift/QtUI/UserSearch/QtUserSearchResultsPage.h
index 855d6b3..2bb4fa5 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchResultsPage.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchResultsPage.h
@@ -17,7 +17,7 @@ namespace Swift {
 			QtUserSearchResultsPage();
 			virtual bool isComplete() const;
 		signals:
-		  void onUserTriggersFinish();
+		  void onUserTriggersContinue();
 		public slots:
 			void emitCompletenessCheck();
 	};
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
index 2927c9b..2c1de3d 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
@@ -6,10 +6,10 @@
 
 #include "Swift/QtUI/UserSearch/QtUserSearchWindow.h"
 
-#include <qdebug.h>
 #include <QModelIndex>
 #include <QWizardPage>
 #include <QMovie>
+#include <boost/smart_ptr/make_shared.hpp>
 
 #include "Swift/Controllers/UIEvents/UIEventStream.h"
 #include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
@@ -20,10 +20,11 @@
 #include "QtUserSearchFirstPage.h"
 #include "QtUserSearchFieldsPage.h"
 #include "QtUserSearchResultsPage.h"
+#include "QtUserSearchDetailsPage.h"
 
 namespace Swift {
 
-QtUserSearchWindow::QtUserSearchWindow(UIEventStream* eventStream, UserSearchWindow::Type type) : eventStream_(eventStream), type_(type) {
+QtUserSearchWindow::QtUserSearchWindow(UIEventStream* eventStream, UserSearchWindow::Type type, const std::set<std::string>& groups) : eventStream_(eventStream), type_(type) {
 	setupUi(this);
 #ifndef Q_WS_MAC
 	setWindowIcon(QIcon(":/logo-icon-16.png"));
@@ -56,8 +57,16 @@ QtUserSearchWindow::QtUserSearchWindow(UIEventStream* eventStream, UserSearchWin
 #ifdef SWIFT_PLATFORM_MACOSX
 	resultsPage_->results_->setAlternatingRowColors(true);
 #endif
+	if (type == AddContact) {
+		connect(resultsPage_, SIGNAL(onUserTriggersContinue()), this, SLOT(next()));
+	}
+	else {
+		connect(resultsPage_, SIGNAL(onUserTriggersContinue()), this, SLOT(accept()));
+	}
 	setPage(3, resultsPage_);
-	connect(resultsPage_, SIGNAL(onUserTriggersFinish()), this, SLOT(accept()));
+
+	detailsPage_ = new QtUserSearchDetailsPage(groups);
+	setPage(4, detailsPage_);
 
 	connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(handleCurrentChanged(int)));
 	connect(this, SIGNAL(accepted()), this, SLOT(handleAccepted()));
@@ -79,6 +88,9 @@ void QtUserSearchWindow::handleCurrentChanged(int page) {
 	else if (page == 3 && lastPage_ == 2) {
 		handleSearch();
 	}
+	else if (page == 4) {
+		detailsPage_->clear();
+	}
 	lastPage_ = page;
 }
 
@@ -97,10 +109,9 @@ void QtUserSearchWindow::handleAccepted() {
 	else {
 		jid = JID(Q2PSTRING(firstPage_->jid_->text()));
 	}
+
 	if (type_ == AddContact) {
-		/* FIXME: allow specifying a nick */
-		boost::shared_ptr<UIEvent> event(new AddContactUIEvent(jid, jid.toString()));
-		eventStream_->send(event);
+		eventStream_->send(boost::make_shared<AddContactUIEvent>(jid, detailsPage_->getName(), detailsPage_->getSelectedGroups()));
 	}
 	else {
 		boost::shared_ptr<UIEvent> event(new RequestChatUIEvent(jid));
@@ -110,9 +121,9 @@ void QtUserSearchWindow::handleAccepted() {
 
 int QtUserSearchWindow::nextId() const {
 	switch (currentId()) {
-		case 1: return firstPage_->byJID_->isChecked() ? -1 : 2;
+		case 1: return firstPage_->byJID_->isChecked() ? (type_ == AddContact ? 4 : -1) : 2;
 		case 2: return 3;
-		case 3: return 4;
+		case 3: return type_ == AddContact ? 4 : -1;
 		case 4: return -1;
 		default: return -1;
 	}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.h b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
index 6c90731..bb40cd3 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
@@ -7,6 +7,7 @@
 #pragma once
 
 #include <QWizard>
+#include <set>
 
 #include <Swift/QtUI/UserSearch/ui_QtUserSearchWizard.h>
 #include <Swift/Controllers/UIInterfaces/UserSearchWindow.h>
@@ -19,11 +20,12 @@ namespace Swift {
 	class QtUserSearchFirstPage;
 	class QtUserSearchFieldsPage;
 	class QtUserSearchResultsPage;
+	class QtUserSearchDetailsPage;
 
 	class QtUserSearchWindow : public QWizard, public UserSearchWindow, private Ui::QtUserSearchWizard {
 		Q_OBJECT
 		public:
-			QtUserSearchWindow(UIEventStream* eventStream, UserSearchWindow::Type type);
+			QtUserSearchWindow(UIEventStream* eventStream, UserSearchWindow::Type type, const std::set<std::string>& groups);
 			virtual ~QtUserSearchWindow();
 
 			virtual void addSavedServices(const std::vector<JID>& services);
@@ -55,6 +57,7 @@ namespace Swift {
 			QtUserSearchFirstPage* firstPage_;
 			QtUserSearchFieldsPage* fieldsPage_;
 			QtUserSearchResultsPage* resultsPage_;
+			QtUserSearchDetailsPage* detailsPage_;
 			JID myServer_;
 			int lastPage_;
 	};
-- 
cgit v0.10.2-6-g49f6