summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Maudsley <richard.maudsley@isode.com>2014-04-09 07:53:12 (GMT)
committerSwift Review <review@swift.im>2014-04-22 21:12:21 (GMT)
commita7fb55381ab4a5c470bf891b31ac6e201611a2c1 (patch)
tree475b3b7fc0142946863580506b00aa250ef8ca14 /Swift/Controllers
parent4444aeb255f8d1712b794c31166f362bb3ec335a (diff)
downloadswift-a7fb55381ab4a5c470bf891b31ac6e201611a2c1.zip
swift-a7fb55381ab4a5c470bf891b31ac6e201611a2c1.tar.bz2
Fix crash in QtUserSearchWindow.
Avoid storing pointers to items in vectors. Using shared_ptr for Contact items. Change-Id: I3baa05fc058011b2beca14dc620ab794988a2b37
Diffstat (limited to 'Swift/Controllers')
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp8
-rw-r--r--Swift/Controllers/Chat/ChatsManager.h4
-rw-r--r--Swift/Controllers/Chat/UserSearchController.cpp22
-rw-r--r--Swift/Controllers/Chat/UserSearchController.h15
-rw-r--r--Swift/Controllers/Contact.h11
-rw-r--r--Swift/Controllers/ContactProvider.h8
-rw-r--r--Swift/Controllers/ContactSuggester.cpp39
-rw-r--r--Swift/Controllers/ContactSuggester.h14
-rw-r--r--Swift/Controllers/ContactsFromXMPPRoster.cpp16
-rw-r--r--Swift/Controllers/ContactsFromXMPPRoster.h8
-rw-r--r--Swift/Controllers/UIInterfaces/UserSearchWindow.h6
11 files changed, 99 insertions, 52 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 919a3d6..654f735 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Kevin Smith
+ * Copyright (c) 2010-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -929,11 +929,11 @@ std::vector<ChatListWindow::Chat> ChatsManager::getRecentChats() const {
return std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end());
}
-std::vector<Contact> Swift::ChatsManager::getContacts() {
- std::vector<Contact> result;
+std::vector<Contact::ref> Swift::ChatsManager::getContacts() {
+ std::vector<Contact::ref> result;
foreach (ChatListWindow::Chat chat, recentChats_) {
if (!chat.isMUC) {
- result.push_back(Contact(chat.chatName.empty() ? chat.jid.toString() : chat.chatName, chat.jid, chat.statusType, chat.avatarPath));
+ result.push_back(boost::make_shared<Contact>(chat.chatName.empty() ? chat.jid.toString() : chat.chatName, chat.jid, chat.statusType, chat.avatarPath));
}
}
return result;
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index 979d52a..88a0986 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Kevin Smith
+ * Copyright (c) 2010-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -73,7 +73,7 @@ namespace Swift {
void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info);
void handleIncomingMessage(boost::shared_ptr<Message> message);
std::vector<ChatListWindow::Chat> getRecentChats() const;
- virtual std::vector<Contact> getContacts();
+ virtual std::vector<Contact::ref> getContacts();
boost::signal<void (bool supportsImpromptu)> onImpromptuMUCServiceDiscovered;
diff --git a/Swift/Controllers/Chat/UserSearchController.cpp b/Swift/Controllers/Chat/UserSearchController.cpp
index 7844c1b..8503609 100644
--- a/Swift/Controllers/Chat/UserSearchController.cpp
+++ b/Swift/Controllers/Chat/UserSearchController.cpp
@@ -215,7 +215,7 @@ void UserSearchController::handlePresenceChanged(Presence::ref presence) {
void UserSearchController::handleJIDUpdateRequested(const std::vector<JID>& jids) {
if (window_) {
- std::vector<Contact> updates;
+ std::vector<Contact::ref> updates;
foreach(const JID& jid, jids) {
updates.push_back(convertJIDtoContact(jid));
}
@@ -224,40 +224,40 @@ void UserSearchController::handleJIDUpdateRequested(const std::vector<JID>& jids
}
void UserSearchController::handleJIDAddRequested(const std::vector<JID>& jids) {
- std::vector<Contact> contacts;
+ std::vector<Contact::ref> contacts;
foreach(const JID& jid, jids) {
contacts.push_back(convertJIDtoContact(jid));
}
window_->addContacts(contacts);
}
-Contact UserSearchController::convertJIDtoContact(const JID& jid) {
- Contact contact;
- contact.jid = jid;
+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();
+ contact->name = rosterItem->getName();
} else {
VCard::ref vcard = vcardManager_->getVCard(jid);
if (vcard && !vcard->getFullName().empty()) {
- contact.name = vcard->getFullName();
+ contact->name = vcard->getFullName();
} else {
- contact.name = jid.toString();
+ contact->name = jid.toString();
}
}
// presence lookup
Presence::ref presence = presenceOracle_->getHighestPriorityPresence(jid);
if (presence) {
- contact.statusType = presence->getShow();
+ contact->statusType = presence->getShow();
} else {
- contact.statusType = StatusShow::None;
+ contact->statusType = StatusShow::None;
}
// avatar lookup
- contact.avatarPath = avatarManager_->getAvatarPath(jid);
+ contact->avatarPath = avatarManager_->getAvatarPath(jid);
return contact;
}
diff --git a/Swift/Controllers/Chat/UserSearchController.h b/Swift/Controllers/Chat/UserSearchController.h
index fc4c8e9..d630580 100644
--- a/Swift/Controllers/Chat/UserSearchController.h
+++ b/Swift/Controllers/Chat/UserSearchController.h
@@ -7,18 +7,20 @@
#pragma once
#include <boost/shared_ptr.hpp>
+
#include <map>
#include <vector>
-#include <Swiften/Base/boost_bsignals.h>
-
-#include <Swiften/Elements/SearchPayload.h>
#include <string>
-#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/Contact.h>
+#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Elements/DiscoItems.h>
#include <Swiften/Elements/ErrorPayload.h>
-#include <Swiften/Elements/VCard.h>
#include <Swiften/Elements/Presence.h>
+#include <Swiften/Elements/SearchPayload.h>
+#include <Swiften/Elements/VCard.h>
+#include <Swiften/JID/JID.h>
namespace Swift {
class UIEventStream;
@@ -32,7 +34,6 @@ namespace Swift {
class ContactSuggester;
class AvatarManager;
class PresenceOracle;
- class Contact;
class UserSearchResult {
public:
@@ -68,7 +69,7 @@ namespace Swift {
void handlePresenceChanged(Presence::ref presence);
void handleJIDUpdateRequested(const std::vector<JID>& jids);
void handleJIDAddRequested(const std::vector<JID>& jids);
- Contact convertJIDtoContact(const JID& jid);
+ Contact::ref convertJIDtoContact(const JID& jid);
void endDiscoWalker();
void initializeUserWindow();
diff --git a/Swift/Controllers/Contact.h b/Swift/Controllers/Contact.h
index 039cd23..ceba152 100644
--- a/Swift/Controllers/Contact.h
+++ b/Swift/Controllers/Contact.h
@@ -4,8 +4,15 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2014 Kevin Smith and Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
#pragma once
+#include <boost/enable_shared_from_this.hpp>
#include <boost/filesystem/path.hpp>
#include <Swiften/Elements/StatusShow.h>
@@ -13,8 +20,10 @@
namespace Swift {
-class Contact {
+class Contact : public boost::enable_shared_from_this<Contact> {
public:
+ typedef boost::shared_ptr<Contact> ref;
+
Contact();
Contact(const std::string& name, const JID& jid, StatusShow::Type statusType, const boost::filesystem::path& path);
diff --git a/Swift/Controllers/ContactProvider.h b/Swift/Controllers/ContactProvider.h
index 9ce371f..0e56de5 100644
--- a/Swift/Controllers/ContactProvider.h
+++ b/Swift/Controllers/ContactProvider.h
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2014 Kevin Smith and Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
#pragma once
#include <vector>
@@ -15,7 +21,7 @@ namespace Swift {
class ContactProvider {
public:
virtual ~ContactProvider();
- virtual std::vector<Contact> getContacts() = 0;
+ virtual std::vector<Contact::ref> getContacts() = 0;
};
}
diff --git a/Swift/Controllers/ContactSuggester.cpp b/Swift/Controllers/ContactSuggester.cpp
index f1104b0..41e0261 100644
--- a/Swift/Controllers/ContactSuggester.cpp
+++ b/Swift/Controllers/ContactSuggester.cpp
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2014 Kevin Smith and Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
#include <Swift/Controllers/ContactSuggester.h>
#include <boost/algorithm/string/find.hpp>
@@ -34,25 +40,22 @@ void ContactSuggester::addContactProvider(ContactProvider* provider) {
contactProviders_.push_back(provider);
}
-bool ContactSuggester::matchContact(const std::string& search, const Contact& c) {
- return fuzzyMatch(c.name, search) || fuzzyMatch(c.jid.toString(), search);
+bool ContactSuggester::matchContact(const std::string& search, const Contact::ref& c) {
+ return fuzzyMatch(c->name, search) || fuzzyMatch(c->jid.toString(), search);
}
-std::vector<Contact> ContactSuggester::getSuggestions(const std::string& search) const {
- std::vector<Contact> results;
+std::vector<Contact::ref> ContactSuggester::getSuggestions(const std::string& search) const {
+ std::vector<Contact::ref> results;
foreach(ContactProvider* provider, contactProviders_) {
append(results, provider->getContacts());
}
- std::sort(results.begin(), results.end(),
- lambda::bind(&Contact::jid, lambda::_1) < lambda::bind(&Contact::jid, lambda::_2));
- results.erase(std::unique(results.begin(), results.end(),
- lambda::bind(&Contact::jid, lambda::_1) == lambda::bind(&Contact::jid, lambda::_2)),
- results.end());
+ std::sort(results.begin(), results.end(), ContactSuggester::contactLexicographicalSortPredicate);
+ results.erase(std::unique(results.begin(), results.end(), ContactSuggester::contactEqualityPredicate), results.end());
results.erase(std::remove_if(results.begin(), results.end(), !lambda::bind(&ContactSuggester::matchContact, search, lambda::_1)),
results.end());
- std::sort(results.begin(), results.end(), ContactSuggester::chatSortPredicate);
+ std::sort(results.begin(), results.end(), ContactSuggester::contactSmartSortPredicate);
return results;
}
@@ -69,11 +72,19 @@ bool ContactSuggester::fuzzyMatch(std::string text, std::string match) {
return true;
}
-bool ContactSuggester::chatSortPredicate(const Contact& a, const Contact& b) {
- if (a.statusType == b.statusType) {
- return a.name.compare(b.name) < 0;
+bool ContactSuggester::contactLexicographicalSortPredicate(const Contact::ref& a, const Contact::ref& b) {
+ return a->jid < b->jid;
+}
+
+bool ContactSuggester::contactEqualityPredicate(const Contact::ref& a, const Contact::ref& b) {
+ return a->jid == b->jid;
+}
+
+bool ContactSuggester::contactSmartSortPredicate(const Contact::ref& a, const Contact::ref& b) {
+ if (a->statusType == b->statusType) {
+ return a->name.compare(b->name) < 0;
} else {
- return a.statusType < b.statusType;
+ return a->statusType < b->statusType;
}
}
diff --git a/Swift/Controllers/ContactSuggester.h b/Swift/Controllers/ContactSuggester.h
index 137e5d3..67b912c 100644
--- a/Swift/Controllers/ContactSuggester.h
+++ b/Swift/Controllers/ContactSuggester.h
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2014 Kevin Smith and Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
#pragma once
#include <string>
@@ -21,14 +27,16 @@ namespace Swift {
void addContactProvider(ContactProvider* provider);
- std::vector<Contact> getSuggestions(const std::string& search) const;
+ std::vector<Contact::ref> getSuggestions(const std::string& search) const;
private:
- static bool matchContact(const std::string& search, const Contact& c);
+ static bool matchContact(const std::string& search, const Contact::ref& c);
/**
* Performs fuzzy matching on the string text. Matches when each character of match string is present in sequence in text string.
*/
static bool fuzzyMatch(std::string text, std::string match);
- static bool chatSortPredicate(const Contact& a, const Contact& b);
+ static bool contactLexicographicalSortPredicate(const Contact::ref& a, const Contact::ref& b);
+ static bool contactEqualityPredicate(const Contact::ref& a, const Contact::ref& b);
+ static bool contactSmartSortPredicate(const Contact::ref& a, const Contact::ref& b);
private:
std::vector<ContactProvider*> contactProviders_;
diff --git a/Swift/Controllers/ContactsFromXMPPRoster.cpp b/Swift/Controllers/ContactsFromXMPPRoster.cpp
index 15a7767..7559962 100644
--- a/Swift/Controllers/ContactsFromXMPPRoster.cpp
+++ b/Swift/Controllers/ContactsFromXMPPRoster.cpp
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2014 Kevin Smith and Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
#include <Swift/Controllers/ContactsFromXMPPRoster.h>
#include <Swiften/Base/foreach.h>
@@ -21,13 +27,13 @@ ContactsFromXMPPRoster::ContactsFromXMPPRoster(XMPPRoster* roster, AvatarManager
ContactsFromXMPPRoster::~ContactsFromXMPPRoster() {
}
-std::vector<Contact> ContactsFromXMPPRoster::getContacts() {
- std::vector<Contact> results;
+std::vector<Contact::ref> ContactsFromXMPPRoster::getContacts() {
+ std::vector<Contact::ref> results;
std::vector<XMPPRosterItem> rosterItems = roster_->getItems();
foreach(const XMPPRosterItem& rosterItem, rosterItems) {
- Contact contact(rosterItem.getName().empty() ? rosterItem.getJID().toString() : rosterItem.getName(), rosterItem.getJID(), StatusShow::None,"");
- contact.statusType = presenceOracle_->getHighestPriorityPresence(contact.jid) ? presenceOracle_->getHighestPriorityPresence(contact.jid)->getShow() : StatusShow::None;
- contact.avatarPath = avatarManager_->getAvatarPath(contact.jid);
+ Contact::ref contact = boost::make_shared<Contact>(rosterItem.getName().empty() ? rosterItem.getJID().toString() : rosterItem.getName(), rosterItem.getJID(), StatusShow::None,"");
+ contact->statusType = presenceOracle_->getHighestPriorityPresence(contact->jid) ? presenceOracle_->getHighestPriorityPresence(contact->jid)->getShow() : StatusShow::None;
+ contact->avatarPath = avatarManager_->getAvatarPath(contact->jid);
results.push_back(contact);
}
return results;
diff --git a/Swift/Controllers/ContactsFromXMPPRoster.h b/Swift/Controllers/ContactsFromXMPPRoster.h
index 3815a99..4adc606 100644
--- a/Swift/Controllers/ContactsFromXMPPRoster.h
+++ b/Swift/Controllers/ContactsFromXMPPRoster.h
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2014 Kevin Smith and Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
#pragma once
#include <Swift/Controllers/ContactProvider.h>
@@ -19,7 +25,7 @@ class ContactsFromXMPPRoster : public ContactProvider {
ContactsFromXMPPRoster(XMPPRoster* roster, AvatarManager* avatarManager, PresenceOracle* presenceOracle);
virtual ~ContactsFromXMPPRoster();
- virtual std::vector<Contact> getContacts();
+ virtual std::vector<Contact::ref> getContacts();
private:
XMPPRoster* roster_;
AvatarManager* avatarManager_;
diff --git a/Swift/Controllers/UIInterfaces/UserSearchWindow.h b/Swift/Controllers/UIInterfaces/UserSearchWindow.h
index 0245f34..56992cc 100644
--- a/Swift/Controllers/UIInterfaces/UserSearchWindow.h
+++ b/Swift/Controllers/UIInterfaces/UserSearchWindow.h
@@ -32,14 +32,14 @@ namespace Swift {
virtual void setSearchFields(boost::shared_ptr<SearchPayload> fields) = 0;
virtual void setNameSuggestions(const std::vector<std::string>& suggestions) = 0;
virtual void prepopulateJIDAndName(const JID& jid, const std::string& name) = 0;
- virtual void setContactSuggestions(const std::vector<Contact>& suggestions) = 0;
+ virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) = 0;
virtual void setJIDs(const std::vector<JID>&) = 0;
virtual void setRoomJID(const JID& roomJID) = 0;
virtual std::string getReason() const = 0;
virtual std::vector<JID> getJIDs() const = 0;
virtual void setCanStartImpromptuChats(bool supportsImpromptu) = 0;
- virtual void updateContacts(const std::vector<Contact>& contacts) = 0;
- virtual void addContacts(const std::vector<Contact>& contacts) = 0;
+ virtual void updateContacts(const std::vector<Contact::ref>& contacts) = 0;
+ virtual void addContacts(const std::vector<Contact::ref>& contacts) = 0;
virtual void show() = 0;