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/QtUI/UserSearch/QtSuggestingJIDInput.cpp
parent4444aeb255f8d1712b794c31166f362bb3ec335a (diff)
downloadswift-contrib-a7fb55381ab4a5c470bf891b31ac6e201611a2c1.zip
swift-contrib-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/QtUI/UserSearch/QtSuggestingJIDInput.cpp')
-rw-r--r--Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp41
1 files changed, 24 insertions, 17 deletions
diff --git a/Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp b/Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp
index de935d9..a4a4610 100644
--- a/Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp
+++ b/Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp
@@ -1,168 +1,175 @@
/*
* Copyright (c) 2013 Tobias Markmann
* Licensed under the simplified BSD license.
* 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/QtUI/UserSearch/QtSuggestingJIDInput.h>
#include <Swift/QtUI/UserSearch/ContactListDelegate.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/QtUI/UserSearch/ContactListModel.h>
#include <Swiften/Base/boost_bsignals.h>
#include <boost/bind.hpp>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <QAbstractItemView>
#include <QApplication>
#include <QDesktopWidget>
#include <QKeyEvent>
namespace Swift {
-QtSuggestingJIDInput::QtSuggestingJIDInput(QWidget* parent, SettingsProvider* settings) : QLineEdit(parent), settings_(settings), currentContact_(NULL) {
+QtSuggestingJIDInput::QtSuggestingJIDInput(QWidget* parent, SettingsProvider* settings) : QLineEdit(parent), settings_(settings) {
treeViewPopup_ = new QTreeView();
treeViewPopup_->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
//treeViewPopup_->setAttribute(Qt::WA_ShowWithoutActivating);
treeViewPopup_->setAlternatingRowColors(true);
treeViewPopup_->setIndentation(0);
treeViewPopup_->setHeaderHidden(true);
treeViewPopup_->setExpandsOnDoubleClick(false);
treeViewPopup_->setItemsExpandable(false);
treeViewPopup_->setSelectionMode(QAbstractItemView::SingleSelection);
treeViewPopup_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
treeViewPopup_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
QSizePolicy policy(treeViewPopup_->sizePolicy());
policy.setVerticalPolicy(QSizePolicy::Expanding);
treeViewPopup_->setSizePolicy(policy);
treeViewPopup_->hide();
treeViewPopup_->setFocusProxy(this);
connect(treeViewPopup_, SIGNAL(clicked(QModelIndex)), this, SLOT(handleClicked(QModelIndex)));
connect(treeViewPopup_, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(handleClicked(QModelIndex)));
contactListModel_ = new ContactListModel(false);
treeViewPopup_->setModel(contactListModel_);
contactListDelegate_ = new ContactListDelegate(settings->getSetting(QtUISettingConstants::COMPACT_ROSTER));
treeViewPopup_->setItemDelegate(contactListDelegate_);
settings_->onSettingChanged.connect(boost::bind(&QtSuggestingJIDInput::handleSettingsChanged, this, _1));
}
QtSuggestingJIDInput::~QtSuggestingJIDInput() {
settings_->onSettingChanged.disconnect(boost::bind(&QtSuggestingJIDInput::handleSettingsChanged, this, _1));
delete treeViewPopup_;
}
-const Contact* QtSuggestingJIDInput::getContact() {
- if (currentContact_ != NULL) {
+Contact::ref QtSuggestingJIDInput::getContact() {
+ if (!!currentContact_) {
return currentContact_;
- } else {
- if (!text().isEmpty()) {
- JID jid(Q2PSTRING(text()));
- if (jid.isValid()) {
- manualContact_.name = jid.toString();
- manualContact_.jid = jid;
- return &manualContact_;
- }
+ }
+
+ if (!text().isEmpty()) {
+ JID jid(Q2PSTRING(text()));
+ if (jid.isValid()) {
+ Contact::ref manualContact = boost::make_shared<Contact>();
+ manualContact->name = jid.toString();
+ manualContact->jid = jid;
+ return manualContact;
}
- return NULL;
}
+ return boost::shared_ptr<Contact>();
}
-void QtSuggestingJIDInput::setSuggestions(const std::vector<Contact>& suggestions) {
+void QtSuggestingJIDInput::setSuggestions(const std::vector<Contact::ref>& suggestions) {
contactListModel_->setList(suggestions);
positionPopup();
if (!suggestions.empty()) {
treeViewPopup_->setCurrentIndex(contactListModel_->index(0, 0));
showPopup();
} else {
- currentContact_ = NULL;
+ currentContact_.reset();
}
}
void QtSuggestingJIDInput::keyPressEvent(QKeyEvent* event) {
if (event->key() == Qt::Key_Up) {
if (contactListModel_->rowCount() > 0) {
int row = treeViewPopup_->currentIndex().row();
row = (row + contactListModel_->rowCount() - 1) % contactListModel_->rowCount();
treeViewPopup_->setCurrentIndex(contactListModel_->index(row, 0));
}
} else if (event->key() == Qt::Key_Down) {
if (contactListModel_->rowCount() > 0) {
int row = treeViewPopup_->currentIndex().row();
row = (row + contactListModel_->rowCount() + 1) % contactListModel_->rowCount();
treeViewPopup_->setCurrentIndex(contactListModel_->index(row, 0));
}
} else if (event->key() == Qt::Key_Return && treeViewPopup_->isVisible()) {
QModelIndex index = treeViewPopup_->currentIndex();
if (!contactListModel_->getList().empty() && index.isValid()) {
- currentContact_ = &contactListModel_->getList()[index.row()];
+ currentContact_ = contactListModel_->getContact(index.row());
setText(P2QSTRING(currentContact_->jid.toString()));
hidePopup();
clearFocus();
} else {
- currentContact_ = NULL;
+ currentContact_.reset();
}
editingDone();
} else {
QLineEdit::keyPressEvent(event);
}
}
void QtSuggestingJIDInput::handleApplicationFocusChanged(QWidget* /*old*/, QWidget* /*now*/) {
/* Using the now argument gives use the wrong widget. This is part of the code needed
to prevent stealing of focus when opening a the suggestion window. */
QWidget* now = qApp->focusWidget();
if (!now || (now != treeViewPopup_ && now != this && !now->isAncestorOf(this) && !now->isAncestorOf(treeViewPopup_) && !this->isAncestorOf(now) && !treeViewPopup_->isAncestorOf(now))) {
hidePopup();
}
}
void QtSuggestingJIDInput::handleSettingsChanged(const std::string& setting) {
if (setting == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
contactListDelegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
}
}
void QtSuggestingJIDInput::handleClicked(const QModelIndex& index) {
if (index.isValid()) {
- currentContact_ = &contactListModel_->getList()[index.row()];
+ currentContact_ = contactListModel_->getContact(index.row());
setText("");
onUserSelected(currentContact_->jid);
hidePopup();
}
}
void QtSuggestingJIDInput::positionPopup() {
QDesktopWidget* desktop = QApplication::desktop();
int screen = desktop->screenNumber(this);
QPoint point = mapToGlobal(QPoint(0, height()));
QRect geometry = desktop->availableGeometry(screen);
int x = point.x();
int y = point.y();
int width = this->width();
int height = 80;
int screenWidth = geometry.x() + geometry.width();
if (x + width > screenWidth) {
x = screenWidth - width;
}
height = treeViewPopup_->sizeHintForRow(0) * contactListModel_->rowCount();
height = height > 200 ? 200 : height;
int marginLeft;
int marginTop;
int marginRight;
int marginBottom;
treeViewPopup_->getContentsMargins(&marginLeft, &marginTop, &marginRight, &marginBottom);
height += marginTop + marginBottom;
width += marginLeft + marginRight;
treeViewPopup_->setGeometry(x, y, width, height);
treeViewPopup_->move(x, y);
treeViewPopup_->setMaximumWidth(width);