summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Maudsley <richard.maudsley@isode.com>2014-04-07 09:19:50 (GMT)
committerRichard Maudsley <richard.maudsley@isode.com>2014-04-07 13:07:43 (GMT)
commita7c7602e89d58056940885112f8764a31e9991da (patch)
treee713e2d7eed2c2ba2925ec0a70fe93eb707c077a /Swift/QtUI/UserSearch
parent1a35178bcad7c30e50a19e4017d021fb0485ccf0 (diff)
downloadswift-contrib-a7c7602e89d58056940885112f8764a31e9991da.zip
swift-contrib-a7c7602e89d58056940885112f8764a31e9991da.tar.bz2
Allow contacts to be dragged from the Chats tab into the search window
Change-Id: Ib1ecd2f95fb26269d8aa19094aac6e1f691cdf35
Diffstat (limited to 'Swift/QtUI/UserSearch')
-rw-r--r--Swift/QtUI/UserSearch/ContactListModel.cpp43
-rw-r--r--Swift/QtUI/UserSearch/ContactListModel.h7
-rw-r--r--Swift/QtUI/UserSearch/QtContactListWidget.cpp23
-rw-r--r--Swift/QtUI/UserSearch/QtContactListWidget.h9
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp40
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h11
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.cpp25
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.h3
8 files changed, 99 insertions, 62 deletions
diff --git a/Swift/QtUI/UserSearch/ContactListModel.cpp b/Swift/QtUI/UserSearch/ContactListModel.cpp
index 4c4a3ea..907142f 100644
--- a/Swift/QtUI/UserSearch/ContactListModel.cpp
+++ b/Swift/QtUI/UserSearch/ContactListModel.cpp
@@ -1,15 +1,21 @@
/*
* 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/ContactListModel.h>
#include <QMimeData>
#include <Swiften/Base/Path.h>
#include <Swiften/Base/foreach.h>
#include <Swiften/Elements/StatusShow.h>
#include <Swift/QtUI/QtSwiftUtil.h>
@@ -76,55 +82,18 @@ QVariant ContactListModel::data(const QModelIndex& index, int role) const {
if (role == Qt::EditRole) {
return P2QSTRING(contact.jid.toString());
}
return dataForContact(contact, role);
} else {
return QVariant();
}
}
-bool ContactListModel::dropMimeData(const QMimeData* data, Qt::DropAction /*action*/, int /*row*/, int /*column*/, const QModelIndex& /*parent*/) {
- if (!data->hasFormat("application/vnd.swift.contact-jid")) {
- return false;
- }
-
- QByteArray dataBytes = data->data("application/vnd.swift.contact-jid");
- QDataStream dataStream(&dataBytes, QIODevice::ReadOnly);
- QString jidString;
- QString displayName;
- QString statusText;
- StatusShow::Type statusType;
- QString avatarPath;
-
- dataStream >> jidString;
- dataStream >> displayName;
- dataStream >> statusText;
- dataStream >> statusType;
- dataStream >> avatarPath;
-
- JID jid = JID(Q2PSTRING(jidString));
-
- foreach(const Contact& contact, contacts_) {
- if (contact.jid == jid) {
- return false;
- }
- }
-
- emit layoutAboutToBeChanged();
- contacts_.push_back(Contact(Q2PSTRING(displayName), jid, statusType, Q2PSTRING(avatarPath)));
- emit layoutChanged();
-
- onJIDsDropped(std::vector<JID>(1, jid));
- onListChanged(getList());
-
- return true;
-}
-
QModelIndex ContactListModel::index(int row, int column, const QModelIndex& parent) const {
if (!hasIndex(row, column, parent)) {
return QModelIndex();
}
return boost::numeric_cast<size_t>(row) < contacts_.size() ? createIndex(row, column, (void*)&(contacts_[row])) : QModelIndex();
}
QModelIndex ContactListModel::parent(const QModelIndex& index) const {
diff --git a/Swift/QtUI/UserSearch/ContactListModel.h b/Swift/QtUI/UserSearch/ContactListModel.h
index e7f4a0b..6ca505e 100644
--- a/Swift/QtUI/UserSearch/ContactListModel.h
+++ b/Swift/QtUI/UserSearch/ContactListModel.h
@@ -1,15 +1,21 @@
/*
* 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.
+ */
+
#pragma once
#include <vector>
#include <boost/bind.hpp>
#include <Swiften/Base/boost_bsignals.h>
#include <QAbstractItemModel>
#include <Swift/Controllers/Contact.h>
@@ -30,19 +36,18 @@ namespace Swift {
public:
ContactListModel(bool editable);
void setList(const std::vector<Contact>& list);
const std::vector<Contact>& getList() const;
Qt::ItemFlags flags(const QModelIndex& index) const;
int columnCount(const QModelIndex& parent = QModelIndex()) const;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex& index) const;
int rowCount(const QModelIndex& parent = QModelIndex()) const;
bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
private:
QVariant dataForContact(const Contact& contact, int role) const;
QIcon getPresenceIconForContact(const Contact& contact) const;
diff --git a/Swift/QtUI/UserSearch/QtContactListWidget.cpp b/Swift/QtUI/UserSearch/QtContactListWidget.cpp
index 90adc11..6ad1169 100644
--- a/Swift/QtUI/UserSearch/QtContactListWidget.cpp
+++ b/Swift/QtUI/UserSearch/QtContactListWidget.cpp
@@ -1,40 +1,42 @@
/*
* 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/QtContactListWidget.h>
#include <Swift/QtUI/UserSearch/ContactListModel.h>
#include <Swift/QtUI/UserSearch/ContactListDelegate.h>
#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h>
#include <QHeaderView>
namespace Swift {
QtContactListWidget::QtContactListWidget(QWidget* parent, SettingsProvider* settings) : QTreeView(parent), settings_(settings), limited_(false) {
contactListModel_ = new ContactListModel(true);
setModel(contactListModel_);
- connect(contactListModel_, SIGNAL(onListChanged(std::vector<Contact>)), this, SLOT(handleListChanged(std::vector<Contact>)));
connect(contactListModel_, SIGNAL(onListChanged(std::vector<Contact>)), this, SIGNAL(onListChanged(std::vector<Contact>)));
connect(contactListModel_, SIGNAL(onJIDsDropped(std::vector<JID>)), this, SIGNAL(onJIDsAdded(std::vector<JID>)));
setSelectionMode(QAbstractItemView::SingleSelection);
setSelectionBehavior(QAbstractItemView::SelectRows);
- setDragEnabled(true);
- setAcceptDrops(true);
- setDropIndicatorShown(true);
setUniformRowHeights(true);
setAlternatingRowColors(true);
setIndentation(0);
setHeaderHidden(true);
setExpandsOnDoubleClick(false);
setItemsExpandable(false);
setEditTriggers(QAbstractItemView::DoubleClicked);
@@ -63,42 +65,29 @@ void QtContactListWidget::setList(const std::vector<Contact>& list) {
contactListModel_->setList(list);
}
std::vector<Contact> QtContactListWidget::getList() const {
return contactListModel_->getList();
}
void QtContactListWidget::setMaximumNoOfContactsToOne(bool limited) {
limited_ = limited;
- if (limited) {
- handleListChanged(getList());
- } else {
- setAcceptDrops(true);
- setDropIndicatorShown(true);
- }
}
void QtContactListWidget::updateContacts(const std::vector<Contact>& contactUpdates) {
std::vector<Contact> contacts = contactListModel_->getList();
foreach(const Contact& contactUpdate, contactUpdates) {
for(size_t n = 0; n < contacts.size(); n++) {
if (contactUpdate.jid == contacts[n].jid) {
contacts[n] = contactUpdate;
break;
}
}
}
contactListModel_->setList(contacts);
}
-void QtContactListWidget::handleListChanged(std::vector<Contact> list) {
- if (limited_) {
- setAcceptDrops(list.size() <= 1);
- setDropIndicatorShown(list.size() <= 1);
- }
-}
-
void QtContactListWidget::handleSettingsChanged(const std::string&) {
contactListDelegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
}
}
diff --git a/Swift/QtUI/UserSearch/QtContactListWidget.h b/Swift/QtUI/UserSearch/QtContactListWidget.h
index f360a91..a83b47a 100644
--- a/Swift/QtUI/UserSearch/QtContactListWidget.h
+++ b/Swift/QtUI/UserSearch/QtContactListWidget.h
@@ -1,15 +1,21 @@
/*
* 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.
+ */
+
#pragma once
#include <vector>
#include <QTreeView>
#include <Swift/Controllers/Contact.h>
#include <Swiften/Base/Log.h>
@@ -35,21 +41,18 @@ public:
void setMaximumNoOfContactsToOne(bool limited);
public slots:
void updateContacts(const std::vector<Contact>& contactUpdates);
signals:
void onListChanged(std::vector<Contact> list);
void onJIDsAdded(const std::vector<JID>& jids);
-private slots:
- void handleListChanged(std::vector<Contact> list);
-
private:
void handleSettingsChanged(const std::string&);
private:
SettingsProvider* settings_;
ContactListModel* contactListModel_;
ContactListDelegate* contactListDelegate_;
QtRemovableItemDelegate* removableItemDelegate_;
bool limited_;
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp
index b1e9a12..360ce0a 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp
@@ -1,20 +1,30 @@
/*
* 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/QtUserSearchFirstMultiJIDPage.h"
+#include <QMessageBox>
+#include <QMimeData>
+#include <QUrl>
+
#include "Swift/QtUI/QtSwiftUtil.h"
-#include <Swift/QtUI/UserSearch/QtContactListWidget.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
+#include <Swift/QtUI/UserSearch/QtContactListWidget.h>
#include <Swift/QtUI/UserSearch/QtSuggestingJIDInput.h>
namespace Swift {
QtUserSearchFirstMultiJIDPage::QtUserSearchFirstMultiJIDPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings) {
setupUi(this);
setTitle(title);
QString introText = "";
switch (type) {
@@ -33,24 +43,52 @@ QtUserSearchFirstMultiJIDPage::QtUserSearchFirstMultiJIDPage(UserSearchWindow::T
contactList_ = new QtContactListWidget(this, settings);
horizontalLayout_5->addWidget(contactList_);
jid_ = new QtSuggestingJIDInput(this, settings);
horizontalLayout_6->insertWidget(0, jid_);
connect(contactList_, SIGNAL(onListChanged(std::vector<Contact>)), this, SLOT(emitCompletenessCheck()));
connect(jid_, SIGNAL(editingDone()), this, SLOT(handleEditingDone()));
+
+ setAcceptDrops(true);
}
bool QtUserSearchFirstMultiJIDPage::isComplete() const {
return !contactList_->getList().empty();
}
void QtUserSearchFirstMultiJIDPage::emitCompletenessCheck() {
emit completeChanged();
}
void QtUserSearchFirstMultiJIDPage::handleEditingDone() {
addContactButton_->setFocus();
}
+void QtUserSearchFirstMultiJIDPage::dragEnterEvent(QDragEnterEvent *event) {
+ if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")
+ || event->mimeData()->hasFormat("application/vnd.swift.contact-jid-muc")) {
+ event->acceptProposedAction();
+ }
+}
+
+void QtUserSearchFirstMultiJIDPage::dropEvent(QDropEvent *event) {
+ if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) {
+ QByteArray dataBytes = event->mimeData()->data("application/vnd.swift.contact-jid-list");
+ QDataStream dataStream(&dataBytes, QIODevice::ReadOnly);
+ std::vector<JID> jids;
+ while (!dataStream.atEnd()) {
+ QString jidString;
+ dataStream >> jidString;
+ jids.push_back(Q2PSTRING(jidString));
+ }
+ onJIDsDropped(jids);
+ } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-muc")) {
+ QMessageBox* messageBox = new QMessageBox(this);
+ messageBox->setText(tr("You can't invite a room to chat."));
+ messageBox->setWindowTitle(tr("Error inviting room to chat"));
+ messageBox->show();
+ }
+}
+
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h
index 427995e..9905f21 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h
@@ -1,15 +1,21 @@
/*
* 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.
+ */
+
#pragma once
#include <QWizardPage>
#include <Swift/QtUI/UserSearch/ui_QtUserSearchFirstMultiJIDPage.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindow.h>
namespace Swift {
class UserSearchModel;
@@ -23,18 +29,23 @@ namespace Swift {
class SettingsProvider;
class QtSuggestingJIDInput;
class QtUserSearchFirstMultiJIDPage : public QWizardPage, public Ui::QtUserSearchFirstMultiJIDPage {
Q_OBJECT
public:
QtUserSearchFirstMultiJIDPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings);
virtual bool isComplete() const;
+ signals:
+ void onJIDsDropped(std::vector<JID> jid);
+
public slots:
void emitCompletenessCheck();
void handleEditingDone();
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dropEvent(QDropEvent *event);
public:
QtContactListWidget* contactList_;
QtSuggestingJIDInput* jid_;
};
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
index c0c7972..ec5dd39 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
@@ -1,11 +1,11 @@
/*
- * 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.
*/
#include "Swift/QtUI/UserSearch/QtUserSearchWindow.h"
#include <QItemDelegate>
#include <QModelIndex>
#include <QWizardPage>
@@ -371,32 +371,52 @@ void QtUserSearchWindow::setCanStartImpromptuChats(bool supportsImpromptu) {
}
}
void QtUserSearchWindow::updateContacts(const std::vector<Contact>& contacts) {
if (type_ != AddContact) {
firstMultiJIDPage_->contactList_->updateContacts(contacts);
}
}
+void QtUserSearchWindow::addContacts(const std::vector<Contact>& contacts) {
+ if (type_ != AddContact) {
+ /* prevent duplicate JIDs from appearing in the contact list */
+ foreach (const Contact& newContact, contacts) {
+ bool found = false;
+ foreach (const Contact& oldContact, contactVector_) {
+ if (newContact.jid == oldContact.jid) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ contactVector_.push_back(newContact);
+ }
+ }
+ firstMultiJIDPage_->contactList_->setList(contactVector_);
+ firstMultiJIDPage_->emitCompletenessCheck();
+ }
+}
+
void QtUserSearchWindow::handleAddViaSearch() {
searchNext_ = true;
next();
}
void QtUserSearchWindow::handleListChanged(std::vector<Contact> list) {
contactVector_ = list;
if (type_ == ChatToContact) {
firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1));
}
}
void QtUserSearchWindow::handleJIDsAdded(std::vector<JID> jids) {
- onJIDUpdateRequested(jids);
+ onJIDAddRequested(jids);
}
void QtUserSearchWindow::setResults(const std::vector<UserSearchResult>& results) {
UserSearchModel *newModel = new UserSearchModel();
newModel->setResults(results);
resultsPage_->results_->setModel(newModel);
resultsPage_->results_->setItemDelegate(delegate_);
resultsPage_->results_->setHeaderHidden(true);
delete model_;
@@ -443,18 +463,19 @@ void QtUserSearchWindow::setFirstPage(QString title) {
setPage(1, firstPage_);
} else {
firstMultiJIDPage_ = new QtUserSearchFirstMultiJIDPage(type_, title.isEmpty() ? firstMultiJIDPage_->title() : title, settings_);
connect(firstMultiJIDPage_->addContactButton_, SIGNAL(clicked()), this, SLOT(addContact()));
connect(firstMultiJIDPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleContactSuggestionRequested(QString)));
firstMultiJIDPage_->jid_->onUserSelected.connect(boost::bind(&QtUserSearchWindow::addSearchedJIDToList, this, _1));
connect(firstMultiJIDPage_->addViaSearchButton_, SIGNAL(clicked()), this, SLOT(handleAddViaSearch()));
connect(firstMultiJIDPage_->contactList_, SIGNAL(onListChanged(std::vector<Contact>)), this, SLOT(handleListChanged(std::vector<Contact>)));
connect(firstMultiJIDPage_->contactList_, SIGNAL(onJIDsAdded(std::vector<JID>)), this, SLOT(handleJIDsAdded(std::vector<JID>)));
+ connect(firstMultiJIDPage_, SIGNAL(onJIDsDropped(std::vector<JID>)), this, SLOT(handleJIDsAdded(std::vector<JID>)));
setPage(1, firstMultiJIDPage_);
}
}
void QtUserSearchWindow::setSecondPage() {
if (page(2) != 0) {
removePage(2);
}
fieldsPage_ = new QtUserSearchFieldsPage();
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.h b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
index e5a9f80..941e455 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
@@ -1,11 +1,11 @@
/*
- * 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.
*/
#pragma once
#include <QWizard>
#include <set>
@@ -44,18 +44,19 @@ namespace Swift {
virtual void setNameSuggestions(const std::vector<std::string>& suggestions);
virtual void prepopulateJIDAndName(const JID& jid, const std::string& name);
virtual void setContactSuggestions(const std::vector<Contact>& suggestions);
virtual void setJIDs(const std::vector<JID> &jids);
virtual void setRoomJID(const JID &roomJID);
virtual std::string getReason() const;
virtual std::vector<JID> getJIDs() const;
virtual void setCanStartImpromptuChats(bool supportsImpromptu);
virtual void updateContacts(const std::vector<Contact> &contacts);
+ virtual void addContacts(const std::vector<Contact>& contacts);
protected:
virtual int nextId() const;
private slots:
void handleFirstPageRadioChange();
virtual void handleCurrentChanged(int);
virtual void handleAccepted();
void handleContactSuggestionRequested(const QString& text);