summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat/UserSearchController.cpp')
-rw-r--r--Swift/Controllers/Chat/UserSearchController.cpp170
1 files changed, 152 insertions, 18 deletions
diff --git a/Swift/Controllers/Chat/UserSearchController.cpp b/Swift/Controllers/Chat/UserSearchController.cpp
index 839f4fa..f1849c9 100644
--- a/Swift/Controllers/Chat/UserSearchController.cpp
+++ b/Swift/Controllers/Chat/UserSearchController.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -16,16 +16,22 @@
#include <Swiften/Disco/DiscoServiceWalker.h>
#include <Swiften/VCards/VCardManager.h>
+#include <Swiften/Presence/PresenceOracle.h>
+#include <Swiften/Avatars/AvatarManager.h>
#include <Swift/Controllers/ContactEditController.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindow.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h>
#include <Swift/Controllers/Roster/RosterController.h>
+#include <Swift/Controllers/ContactSuggester.h>
namespace Swift {
-UserSearchController::UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, VCardManager* vcardManager, UserSearchWindowFactory* factory, IQRouter* iqRouter, RosterController* rosterController) : type_(type), jid_(jid), uiEventStream_(uiEventStream), vcardManager_(vcardManager), factory_(factory), iqRouter_(iqRouter), rosterController_(rosterController) {
+UserSearchController::UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, VCardManager* vcardManager, UserSearchWindowFactory* factory, IQRouter* iqRouter, RosterController* rosterController, ContactSuggester* contactSuggester, AvatarManager* avatarManager, PresenceOracle* presenceOracle) : type_(type), jid_(jid), uiEventStream_(uiEventStream), vcardManager_(vcardManager), factory_(factory), iqRouter_(iqRouter), rosterController_(rosterController), contactSuggester_(contactSuggester), avatarManager_(avatarManager), presenceOracle_(presenceOracle) {
uiEventStream_->onUIEvent.connect(boost::bind(&UserSearchController::handleUIEvent, this, _1));
vcardManager_->onVCardChanged.connect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2));
+ avatarManager_->onAvatarChanged.connect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1));
+ presenceOracle_->onPresenceChange.connect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1));
window_ = NULL;
discoWalker_ = NULL;
@@ -39,38 +45,61 @@ UserSearchController::~UserSearchController() {
window_->onFormRequested.disconnect(boost::bind(&UserSearchController::handleFormRequested, this, _1));
window_->onSearchRequested.disconnect(boost::bind(&UserSearchController::handleSearch, this, _1, _2));
+ window_->onJIDUpdateRequested.disconnect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1));
+ window_->onJIDAddRequested.disconnect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1));
delete window_;
}
+ presenceOracle_->onPresenceChange.disconnect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1));
+ avatarManager_->onAvatarChanged.disconnect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1));
vcardManager_->onVCardChanged.disconnect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2));
uiEventStream_->onUIEvent.disconnect(boost::bind(&UserSearchController::handleUIEvent, this, _1));
}
+UserSearchWindow* UserSearchController::getUserSearchWindow() {
+ initializeUserWindow();
+ assert(window_);
+ return window_;
+}
+
+void UserSearchController::setCanInitiateImpromptuMUC(bool supportsImpromptu) {
+ if (!window_) {
+ initializeUserWindow();
+ }
+ window_->setCanStartImpromptuChats(supportsImpromptu);
+}
+
void UserSearchController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
bool handle = false;
- boost::shared_ptr<RequestAddUserDialogUIEvent> request = boost::shared_ptr<RequestAddUserDialogUIEvent>();
- if (type_ == AddContact) {
- if ((request = boost::dynamic_pointer_cast<RequestAddUserDialogUIEvent>(event))) {
+ boost::shared_ptr<RequestAddUserDialogUIEvent> addUserRequest = boost::shared_ptr<RequestAddUserDialogUIEvent>();
+ RequestInviteToMUCUIEvent::ref inviteToMUCRequest = RequestInviteToMUCUIEvent::ref();
+ switch (type_) {
+ case AddContact:
+ if ((addUserRequest = boost::dynamic_pointer_cast<RequestAddUserDialogUIEvent>(event))) {
handle = true;
}
- } else {
+ break;
+ case StartChat:
if (boost::dynamic_pointer_cast<RequestChatWithUserDialogUIEvent>(event)) {
handle = true;
}
+ break;
+ case InviteToChat:
+ if ((inviteToMUCRequest = boost::dynamic_pointer_cast<RequestInviteToMUCUIEvent>(event))) {
+ handle = true;
}
- if (handle) {
- if (!window_) {
- window_ = factory_->createUserSearchWindow(type_ == AddContact ? UserSearchWindow::AddContact : UserSearchWindow::ChatToContact, uiEventStream_, rosterController_->getGroups());
- window_->onNameSuggestionRequested.connect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1));
- window_->onFormRequested.connect(boost::bind(&UserSearchController::handleFormRequested, this, _1));
- window_->onSearchRequested.connect(boost::bind(&UserSearchController::handleSearch, this, _1, _2));
- window_->setSelectedService(JID(jid_.getDomain()));
- window_->clear();
+ break;
}
+ if (handle) {
+ initializeUserWindow();
window_->show();
- if (request) {
- const std::string& name = request->getPredefinedName();
- const JID& jid = request->getPredefinedJID();
+ if (addUserRequest) {
+ const std::string& name = addUserRequest->getPredefinedName();
+ const JID& jid = addUserRequest->getPredefinedJID();
if (!name.empty() && jid.isValid()) {
window_->prepopulateJIDAndName(jid, name);
}
+ } else if (inviteToMUCRequest) {
+ window_->setCanSupplyDescription(!inviteToMUCRequest->isImpromptu());
+ window_->setJIDs(inviteToMUCRequest->getInvites());
+ window_->setRoomJID(inviteToMUCRequest->getRoom());
}
return;
@@ -99,5 +128,4 @@ void UserSearchController::endDiscoWalker() {
}
-
void UserSearchController::handleDiscoServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> info) {
//bool isUserDirectory = false;
@@ -167,4 +195,26 @@ void UserSearchController::handleNameSuggestionRequest(const JID &jid) {
}
+void UserSearchController::handleContactSuggestionsRequested(std::string text) {
+ const std::vector<JID> existingJIDs = window_->getJIDs();
+ std::vector<Contact::ref> suggestions = contactSuggester_->getSuggestions(text, false);
+ /* do not suggest contacts that have already been added to the chat list */
+ std::vector<Contact::ref>::iterator i = suggestions.begin();
+ while (i != suggestions.end()) {
+ bool found = false;
+ foreach (const JID& jid, existingJIDs) {
+ if ((*i)->jid == jid) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ i = suggestions.erase(i);
+ } else {
+ i++;
+ }
+ }
+ window_->setContactSuggestions(suggestions);
+}
+
void UserSearchController::handleVCardChanged(const JID& jid, VCard::ref vcard) {
if (jid == suggestionsJID_) {
@@ -172,4 +222,61 @@ void UserSearchController::handleVCardChanged(const JID& jid, VCard::ref vcard)
suggestionsJID_ = JID();
}
+ handleJIDUpdateRequested(std::vector<JID>(1, jid));
+}
+
+void UserSearchController::handleAvatarChanged(const JID& jid) {
+ handleJIDUpdateRequested(std::vector<JID>(1, jid));
+}
+
+void UserSearchController::handlePresenceChanged(Presence::ref presence) {
+ handleJIDUpdateRequested(std::vector<JID>(1, presence->getFrom().toBare()));
+}
+
+void UserSearchController::handleJIDUpdateRequested(const std::vector<JID>& jids) {
+ if (window_) {
+ std::vector<Contact::ref> updates;
+ foreach(const JID& jid, jids) {
+ updates.push_back(convertJIDtoContact(jid));
+ }
+ window_->updateContacts(updates);
+ }
+}
+
+void UserSearchController::handleJIDAddRequested(const std::vector<JID>& jids) {
+ std::vector<Contact::ref> contacts;
+ foreach(const JID& jid, jids) {
+ contacts.push_back(convertJIDtoContact(jid));
+ }
+ window_->addContacts(contacts);
+}
+
+Contact::ref UserSearchController::convertJIDtoContact(const JID& jid) {
+ Contact::ref contact = boost::make_shared<Contact>();
+ contact->jid = jid;
+
+ // name lookup
+ boost::optional<XMPPRosterItem> rosterItem = rosterController_->getItem(jid);
+ if (rosterItem && !rosterItem->getName().empty()) {
+ contact->name = rosterItem->getName();
+ } else {
+ VCard::ref vcard = vcardManager_->getVCard(jid);
+ if (vcard && !vcard->getFullName().empty()) {
+ contact->name = vcard->getFullName();
+ } else {
+ contact->name = jid.toString();
+ }
+ }
+
+ // presence lookup
+ Presence::ref presence = presenceOracle_->getHighestPriorityPresence(jid);
+ if (presence) {
+ contact->statusType = presence->getShow();
+ } else {
+ contact->statusType = StatusShow::None;
+ }
+
+ // avatar lookup
+ contact->avatarPath = avatarManager_->getAvatarPath(jid);
+ return contact;
}
@@ -179,3 +286,30 @@ void UserSearchController::handleDiscoWalkFinished() {
}
+void UserSearchController::initializeUserWindow() {
+ if (!window_) {
+ UserSearchWindow::Type windowType = UserSearchWindow::AddContact;
+ switch(type_) {
+ case AddContact:
+ windowType = UserSearchWindow::AddContact;
+ break;
+ case StartChat:
+ windowType = UserSearchWindow::ChatToContact;
+ break;
+ case InviteToChat:
+ windowType = UserSearchWindow::InviteToChat;
+ break;
+ }
+
+ window_ = factory_->createUserSearchWindow(windowType, uiEventStream_, rosterController_->getGroups());
+ window_->onNameSuggestionRequested.connect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1));
+ window_->onFormRequested.connect(boost::bind(&UserSearchController::handleFormRequested, this, _1));
+ window_->onSearchRequested.connect(boost::bind(&UserSearchController::handleSearch, this, _1, _2));
+ window_->onContactSuggestionsRequested.connect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1));
+ window_->onJIDUpdateRequested.connect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1));
+ window_->onJIDAddRequested.connect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1));
+ window_->setSelectedService(JID(jid_.getDomain()));
+ window_->clear();
+ }
+}
+
}