diff options
Diffstat (limited to 'Swift/QtUI')
| -rw-r--r-- | Swift/QtUI/UserSearch/ContactListDelegate.cpp | 8 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/ContactListModel.cpp | 26 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/ContactListModel.h | 13 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtContactListWidget.cpp | 18 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtContactListWidget.h | 9 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp | 41 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtSuggestingJIDInput.h | 13 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp | 2 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtUserSearchWindow.cpp | 37 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtUserSearchWindow.h | 10 |
10 files changed, 102 insertions, 75 deletions
diff --git a/Swift/QtUI/UserSearch/ContactListDelegate.cpp b/Swift/QtUI/UserSearch/ContactListDelegate.cpp index 29cab83..56c479b 100644 --- a/Swift/QtUI/UserSearch/ContactListDelegate.cpp +++ b/Swift/QtUI/UserSearch/ContactListDelegate.cpp @@ -1,46 +1,52 @@ /* * 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/ContactListDelegate.h> #include <Swift/QtUI/UserSearch/ContactListModel.h> #include <Swift/Controllers/Contact.h> #include <Swift/QtUI/QtSwiftUtil.h> namespace Swift { ContactListDelegate::ContactListDelegate(bool compact) : compact_(compact) { } ContactListDelegate::~ContactListDelegate() { } void ContactListDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (!index.isValid()) { return; } - const Contact* contact = static_cast<Contact*>(index.internalPointer()); + const Contact::ref contact = static_cast<Contact*>(index.internalPointer())->shared_from_this(); QColor nameColor = index.data(Qt::TextColorRole).value<QColor>(); QString avatarPath = index.data(ContactListModel::AvatarRole).value<QString>(); QIcon presenceIcon =index.data(ChatListRecentItem::PresenceIconRole).isValid() && !index.data(ChatListRecentItem::PresenceIconRole).value<QIcon>().isNull() ? index.data(ChatListRecentItem::PresenceIconRole).value<QIcon>() : QIcon(":/icons/offline.png"); QString name = P2QSTRING(contact->name); QString statusText = P2QSTRING(contact->jid.toString()); common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, false, 0, compact_); } QSize ContactListDelegate::sizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const { QFontMetrics nameMetrics(common_.nameFont); QFontMetrics statusMetrics(common_.detailFont); int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height(); return QSize(150, sizeByText); } void ContactListDelegate::setCompact(bool compact) { compact_ = compact; } } diff --git a/Swift/QtUI/UserSearch/ContactListModel.cpp b/Swift/QtUI/UserSearch/ContactListModel.cpp index 907142f..ef6383c 100644 --- a/Swift/QtUI/UserSearch/ContactListModel.cpp +++ b/Swift/QtUI/UserSearch/ContactListModel.cpp @@ -20,116 +20,120 @@ #include <Swift/QtUI/QtSwiftUtil.h> #include <Swift/QtUI/QtResourceHelper.h> namespace Swift { QDataStream& operator >>(QDataStream& in, StatusShow::Type& e){ quint32 buffer; in >> buffer; switch(buffer) { case StatusShow::Online: e = StatusShow::Online; break; case StatusShow::Away: e = StatusShow::Away; break; case StatusShow::FFC: e = StatusShow::FFC; break; case StatusShow::XA: e = StatusShow::XA; break; case StatusShow::DND: e = StatusShow::DND; break; default: e = StatusShow::None; break; } return in; } ContactListModel::ContactListModel(bool editable) : QAbstractItemModel(), editable_(editable) { } -void ContactListModel::setList(const std::vector<Contact>& list) { +void ContactListModel::setList(const std::vector<Contact::ref>& list) { emit layoutAboutToBeChanged(); contacts_ = list; emit layoutChanged(); } -const std::vector<Contact>& ContactListModel::getList() const { +const std::vector<Contact::ref>& ContactListModel::getList() const { return contacts_; } +Contact::ref ContactListModel::getContact(const size_t i) const { + return contacts_[i]; +} + Qt::ItemFlags ContactListModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); if (index.isValid()) { flags = flags & ~Qt::ItemIsDropEnabled; } else { flags = Qt::ItemIsDropEnabled | flags; } return flags; } int ContactListModel::columnCount(const QModelIndex&) const { return editable_ ? 2 : 1; } QVariant ContactListModel::data(const QModelIndex& index, int role) const { if (boost::numeric_cast<size_t>(index.row()) < contacts_.size()) { - const Contact& contact = contacts_[index.row()]; + const Contact::ref& contact = contacts_[index.row()]; if (role == Qt::EditRole) { - return P2QSTRING(contact.jid.toString()); + return P2QSTRING(contact->jid.toString()); } return dataForContact(contact, role); } else { return QVariant(); } } 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(); + return boost::numeric_cast<size_t>(row) < contacts_.size() ? createIndex(row, column, contacts_[row].get()) : QModelIndex(); } QModelIndex ContactListModel::parent(const QModelIndex& index) const { if (!index.isValid()) { return QModelIndex(); } return QModelIndex(); } int ContactListModel::rowCount(const QModelIndex& /*parent*/) const { return contacts_.size(); } bool ContactListModel::removeRows(int row, int /*count*/, const QModelIndex& /*parent*/) { if (boost::numeric_cast<size_t>(row) < contacts_.size()) { emit layoutAboutToBeChanged(); contacts_.erase(contacts_.begin() + row); emit layoutChanged(); onListChanged(getList()); return true; } return false; } -QVariant ContactListModel::dataForContact(const Contact& contact, int role) const { +QVariant ContactListModel::dataForContact(const Contact::ref& contact, int role) const { switch (role) { - case Qt::DisplayRole: return P2QSTRING(contact.name); - case DetailTextRole: return P2QSTRING(contact.jid.toString()); - case AvatarRole: return QVariant(P2QSTRING(pathToString(contact.avatarPath))); + case Qt::DisplayRole: return P2QSTRING(contact->name); + case DetailTextRole: return P2QSTRING(contact->jid.toString()); + case AvatarRole: return QVariant(P2QSTRING(pathToString(contact->avatarPath))); case PresenceIconRole: return getPresenceIconForContact(contact); default: return QVariant(); } } -QIcon ContactListModel::getPresenceIconForContact(const Contact& contact) const { - return QIcon(statusShowTypeToIconPath(contact.statusType)); +QIcon ContactListModel::getPresenceIconForContact(const Contact::ref& contact) const { + return QIcon(statusShowTypeToIconPath(contact->statusType)); } } diff --git a/Swift/QtUI/UserSearch/ContactListModel.h b/Swift/QtUI/UserSearch/ContactListModel.h index 6ca505e..e582ac4 100644 --- a/Swift/QtUI/UserSearch/ContactListModel.h +++ b/Swift/QtUI/UserSearch/ContactListModel.h @@ -4,60 +4,61 @@ * 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> #include <Swift/QtUI/ChatList/ChatListItem.h> #include <Swift/QtUI/ChatList/ChatListGroupItem.h> #include <Swift/QtUI/ChatList/ChatListRecentItem.h> namespace Swift { class ContactListModel : public QAbstractItemModel { Q_OBJECT public: enum ContactRoles { DetailTextRole = Qt::UserRole, AvatarRole = Qt::UserRole + 1, PresenceIconRole = Qt::UserRole + 2 }; public: ContactListModel(bool editable); - void setList(const std::vector<Contact>& list); - const std::vector<Contact>& getList() const; + void setList(const std::vector<Contact::ref>& list); + const std::vector<Contact::ref>& getList() const; + Contact::ref getContact(const size_t i) 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; 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; + QVariant dataForContact(const Contact::ref& contact, int role) const; + QIcon getPresenceIconForContact(const Contact::ref& contact) const; signals: - void onListChanged(std::vector<Contact> list); + void onListChanged(std::vector<Contact::ref> list); void onJIDsDropped(const std::vector<JID>& contact); private: bool editable_; - std::vector<Contact> contacts_; + std::vector<Contact::ref> contacts_; }; } diff --git a/Swift/QtUI/UserSearch/QtContactListWidget.cpp b/Swift/QtUI/UserSearch/QtContactListWidget.cpp index 6ad1169..4adc929 100644 --- a/Swift/QtUI/UserSearch/QtContactListWidget.cpp +++ b/Swift/QtUI/UserSearch/QtContactListWidget.cpp @@ -1,93 +1,97 @@ /* * 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, SIGNAL(onListChanged(std::vector<Contact>))); + connect(contactListModel_, SIGNAL(onListChanged(std::vector<Contact::ref>)), this, SIGNAL(onListChanged(std::vector<Contact::ref>))); connect(contactListModel_, SIGNAL(onJIDsDropped(std::vector<JID>)), this, SIGNAL(onJIDsAdded(std::vector<JID>))); setSelectionMode(QAbstractItemView::SingleSelection); setSelectionBehavior(QAbstractItemView::SelectRows); setUniformRowHeights(true); setAlternatingRowColors(true); setIndentation(0); setHeaderHidden(true); setExpandsOnDoubleClick(false); setItemsExpandable(false); setEditTriggers(QAbstractItemView::DoubleClicked); contactListDelegate_ = new ContactListDelegate(settings->getSetting(QtUISettingConstants::COMPACT_ROSTER)); removableItemDelegate_ = new QtRemovableItemDelegate(style()); setItemDelegateForColumn(0, contactListDelegate_); setItemDelegateForColumn(1, removableItemDelegate_); header()->resizeSection(1, removableItemDelegate_->sizeHint(QStyleOptionViewItem(), QModelIndex()).width()); header()->setStretchLastSection(false); #if QT_VERSION >= 0x050000 header()->setSectionResizeMode(0, QHeaderView::Stretch); #else header()->setResizeMode(0, QHeaderView::Stretch); #endif } QtContactListWidget::~QtContactListWidget() { delete contactListDelegate_; delete removableItemDelegate_; } -void QtContactListWidget::setList(const std::vector<Contact>& list) { +void QtContactListWidget::setList(const std::vector<Contact::ref>& list) { contactListModel_->setList(list); } -std::vector<Contact> QtContactListWidget::getList() const { +std::vector<Contact::ref> QtContactListWidget::getList() const { return contactListModel_->getList(); } +Contact::ref QtContactListWidget::getContact(const size_t i) { + return contactListModel_->getContact(i); +} + void QtContactListWidget::setMaximumNoOfContactsToOne(bool limited) { limited_ = limited; } -void QtContactListWidget::updateContacts(const std::vector<Contact>& contactUpdates) { - std::vector<Contact> contacts = contactListModel_->getList(); - foreach(const Contact& contactUpdate, contactUpdates) { +void QtContactListWidget::updateContacts(const std::vector<Contact::ref>& contactUpdates) { + std::vector<Contact::ref> contacts = contactListModel_->getList(); + foreach(const Contact::ref& contactUpdate, contactUpdates) { for(size_t n = 0; n < contacts.size(); n++) { - if (contactUpdate.jid == contacts[n].jid) { + if (contactUpdate->jid == contacts[n]->jid) { contacts[n] = contactUpdate; break; } } } contactListModel_->setList(contacts); } 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 a83b47a..601d320 100644 --- a/Swift/QtUI/UserSearch/QtContactListWidget.h +++ b/Swift/QtUI/UserSearch/QtContactListWidget.h @@ -4,58 +4,59 @@ * 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> #include <QDragEnterEvent> #include <QDragMoveEvent> #include <QDropEvent> namespace Swift { class ContactListDelegate; class ContactListModel; class SettingsProvider; class QtRemovableItemDelegate; class QtContactListWidget : public QTreeView { Q_OBJECT public: QtContactListWidget(QWidget* parent, SettingsProvider* settings); virtual ~QtContactListWidget(); - void setList(const std::vector<Contact>& list); - std::vector<Contact> getList() const; + void setList(const std::vector<Contact::ref>& list); + std::vector<Contact::ref> getList() const; + Contact::ref getContact(const size_t i); void setMaximumNoOfContactsToOne(bool limited); public slots: - void updateContacts(const std::vector<Contact>& contactUpdates); + void updateContacts(const std::vector<Contact::ref>& contactUpdates); signals: - void onListChanged(std::vector<Contact> list); + void onListChanged(std::vector<Contact::ref> list); void onJIDsAdded(const std::vector<JID>& jids); private: void handleSettingsChanged(const std::string&); private: SettingsProvider* settings_; ContactListModel* contactListModel_; ContactListDelegate* contactListDelegate_; QtRemovableItemDelegate* removableItemDelegate_; bool limited_; }; } 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); diff --git a/Swift/QtUI/UserSearch/QtSuggestingJIDInput.h b/Swift/QtUI/UserSearch/QtSuggestingJIDInput.h index 9ec0512..25e7d42 100644 --- a/Swift/QtUI/UserSearch/QtSuggestingJIDInput.h +++ b/Swift/QtUI/UserSearch/QtSuggestingJIDInput.h @@ -1,59 +1,64 @@ /* * 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 <QLineEdit> #include <QTreeView> #include <Swiften/Base/boost_bsignals.h> #include <Swift/Controllers/Contact.h> namespace Swift { class ContactListDelegate; class SettingsProvider; class ContactListModel; class QtSuggestingJIDInput : public QLineEdit { Q_OBJECT public: QtSuggestingJIDInput(QWidget* parent, SettingsProvider* settings); virtual ~QtSuggestingJIDInput(); - const Contact* getContact(); + Contact::ref getContact(); - void setSuggestions(const std::vector<Contact>& suggestions); + void setSuggestions(const std::vector<Contact::ref>& suggestions); boost::signal<void (const JID&)> onUserSelected; signals: void editingDone(); protected: virtual void keyPressEvent(QKeyEvent* event); private: void handleSettingsChanged(const std::string& setting); private slots: void handleClicked(const QModelIndex& index); void handleApplicationFocusChanged(QWidget* old, QWidget* now); private: void positionPopup(); void showPopup(); void hidePopup(); private: SettingsProvider* settings_; ContactListModel* contactListModel_; QTreeView* treeViewPopup_; ContactListDelegate* contactListDelegate_; - Contact manualContact_; - const Contact* currentContact_; + Contact::ref currentContact_; }; } diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp index 47d62d9..597c88b 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp +++ b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp @@ -15,71 +15,71 @@ #include <QMessageBox> #include <QMimeData> #include <QUrl> #include "Swift/QtUI/QtSwiftUtil.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) { case UserSearchWindow::AddContact: introText = tr("Add another user to your contact list"); break; case UserSearchWindow::ChatToContact: introText = tr("Chat to another user"); break; case UserSearchWindow::InviteToChat: introText = tr("Invite contact to chat"); break; } setSubTitle(QString(tr("%1. If you know their address you can enter it directly, or you can search for them.")).arg(introText)); 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(contactList_, SIGNAL(onListChanged(std::vector<Contact::ref>)), this, SLOT(emitCompletenessCheck())); connect(jid_, SIGNAL(editingDone()), this, SLOT(handleEditingDone())); setAcceptDrops(true); } bool QtUserSearchFirstMultiJIDPage::isComplete() const { return !contactList_->getList().empty(); } void QtUserSearchFirstMultiJIDPage::reset() { reason_->clear(); } 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; diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp index ed0fae2..c154c8f 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp +++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp @@ -98,99 +98,98 @@ void QtUserSearchWindow::handleCurrentChanged(int page) { firstPage_->byRemoteSearch_->setChecked(remote); firstPage_->service_->setEditText(P2QSTRING(server.toString())); } else { bool remote = firstMultiJIDPage_->byRemoteSearch_->isChecked(); setFirstPage(); firstMultiJIDPage_->byRemoteSearch_->setChecked(remote); firstMultiJIDPage_->service_->setEditText(P2QSTRING(server.toString())); } } else if (page == 4) { detailsPage_->clear(); detailsPage_->setJID(getContactJID()); onNameSuggestionRequested(getContactJID()); } lastPage_ = page; } JID QtUserSearchWindow::getServerToSearch() { if (type_ == AddContact) { return firstPage_->byRemoteSearch_->isChecked() ? JID(Q2PSTRING(firstPage_->service_->currentText().trimmed())) : myServer_; } else { return firstMultiJIDPage_->byRemoteSearch_->isChecked() ? JID(Q2PSTRING(firstMultiJIDPage_->service_->currentText().trimmed())) : myServer_; } } void QtUserSearchWindow::handleAccepted() { JID jid; std::vector<JID> jids; switch(type_) { case AddContact: jid = getContactJID(); eventStream_->send(boost::make_shared<AddContactUIEvent>(jid, detailsPage_->getName(), detailsPage_->getSelectedGroups())); break; case ChatToContact: if (contactVector_.size() == 1) { - boost::shared_ptr<UIEvent> event(new RequestChatUIEvent(contactVector_[0].jid)); + boost::shared_ptr<UIEvent> event(new RequestChatUIEvent(contactVector_[0]->jid)); eventStream_->send(event); break; } - foreach(const Contact& contact, contactVector_) { - jids.push_back(contact.jid); + foreach(Contact::ref contact, contactVector_) { + jids.push_back(contact->jid); } eventStream_->send(boost::make_shared<CreateImpromptuMUCUIEvent>(jids, JID(), Q2PSTRING(firstMultiJIDPage_->reason_->text()))); break; case InviteToChat: - foreach(const Contact& contact, contactVector_) { - jids.push_back(contact.jid); + foreach(Contact::ref contact, contactVector_) { + jids.push_back(contact->jid); } eventStream_->send(boost::make_shared<InviteToMUCUIEvent>(roomJID_, jids, Q2PSTRING(firstMultiJIDPage_->reason_->text()))); break; } } void QtUserSearchWindow::handleContactSuggestionRequested(const QString& text) { std::string stdText = Q2PSTRING(text); onContactSuggestionsRequested(stdText); } void QtUserSearchWindow::addContact() { - if (firstMultiJIDPage_->jid_->getContact() != 0) { - Contact contact = *(firstMultiJIDPage_->jid_->getContact()); - contactVector_.push_back(contact); + if (!!firstMultiJIDPage_->jid_->getContact()) { + contactVector_.push_back(firstMultiJIDPage_->jid_->getContact()); } firstMultiJIDPage_->contactList_->setList(contactVector_); firstMultiJIDPage_->emitCompletenessCheck(); if (type_ == ChatToContact) { firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1)); } } int QtUserSearchWindow::nextId() const { if (type_ == AddContact) { switch (currentId()) { case 1: return firstPage_->byJID_->isChecked() ? (type_ == AddContact ? 4 : -1) : 2; case 2: return 3; case 3: return type_ == AddContact ? 4 : -1; case 4: return -1; default: return -1; } } else { switch (currentId()) { case 1: return searchNext_ ? 2 : -1; case 2: return 3; case 3: return 1; case 4: return -1; default: return -1; } } } void QtUserSearchWindow::handleFirstPageRadioChange() { if (firstPage_->byJID_->isChecked()) { firstPage_->jid_->setText(""); firstPage_->jid_->setEnabled(true); firstPage_->service_->setEnabled(false); restart(); } @@ -239,270 +238,270 @@ JID QtUserSearchWindow::getContactJID() const { useSearchResult = true; } if (useSearchResult) { if (dynamic_cast<UserSearchModel*>(model_)) { UserSearchResult* userItem = static_cast<UserSearchResult*>(resultsPage_->results_->currentIndex().internalPointer()); if (userItem) { /* Remember to leave this if we change to dynamic cast */ jid = userItem->getJID(); } } else { int row = resultsPage_->results_->currentIndex().row(); Form::FormItem item = dynamic_cast<QtFormResultItemModel*>(model_)->getForm()->getItems().at(row); JID fallbackJid; foreach(FormField::ref field, item) { if (field->getType() == FormField::JIDSingleType) { jid = JID(field->getJIDSingleValue()); break; } if (field->getName() == "jid") { fallbackJid = field->getValues()[0]; } } if (!jid.isValid()) { jid = fallbackJid; } } } else { jid = JID(Q2PSTRING(firstPage_->jid_->text().trimmed())); } return jid; } void QtUserSearchWindow::addSearchedJIDToList(const JID& jid) { - Contact contact(jid, jid.toString(), StatusShow::None, ""); + Contact::ref contact = boost::make_shared<Contact>(jid, jid.toString(), StatusShow::None, ""); contactVector_.push_back(contact); firstMultiJIDPage_->contactList_->setList(contactVector_); firstMultiJIDPage_->emitCompletenessCheck(); if (type_ == ChatToContact) { firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1)); } } void QtUserSearchWindow::show() { clear(); QWidget::show(); } void QtUserSearchWindow::addSavedServices(const std::vector<JID>& services) { if (type_ == AddContact) { firstPage_->service_->clear(); foreach (JID jid, services) { firstPage_->service_->addItem(P2QSTRING(jid.toString())); } firstPage_->service_->clearEditText(); } else { firstMultiJIDPage_->service_->clear(); foreach (JID jid, services) { firstMultiJIDPage_->service_->addItem(P2QSTRING(jid.toString())); } firstMultiJIDPage_->service_->clearEditText(); } } void QtUserSearchWindow::setSearchFields(boost::shared_ptr<SearchPayload> fields) { fieldsPage_->fetchingThrobber_->hide(); fieldsPage_->fetchingThrobber_->movie()->stop(); fieldsPage_->fetchingLabel_->hide(); fieldsPage_->instructionsLabel_->setText(fields->getInstructions() ? P2QSTRING(fields->getInstructions().get()) : "Enter search terms"); if (fields->getForm()) { fieldsPage_->setFormWidget(new QtFormWidget(fields->getForm(), fieldsPage_)); } else { fieldsPage_->setFormWidget(NULL); bool enabled[8] = {fields->getNick(), fields->getNick(), fields->getFirst(), fields->getFirst(), fields->getLast(), fields->getLast(), fields->getEMail(), fields->getEMail()}; QWidget* legacySearchWidgets[8] = {fieldsPage_->nickInputLabel_, fieldsPage_->nickInput_, fieldsPage_->firstInputLabel_, fieldsPage_->firstInput_, fieldsPage_->lastInputLabel_, fieldsPage_->lastInput_, fieldsPage_->emailInputLabel_, fieldsPage_->emailInput_}; for (int i = 0; i < 8; i++) { legacySearchWidgets[i]->setVisible(enabled[i]); legacySearchWidgets[i]->setEnabled(enabled[i]); } } fieldsPage_->emitCompletenessCheck(); } void QtUserSearchWindow::setNameSuggestions(const std::vector<std::string>& suggestions) { if (detailsPage_) { detailsPage_->setNameSuggestions(suggestions); } } void QtUserSearchWindow::prepopulateJIDAndName(const JID& jid, const std::string& name) { firstPage_->jid_->setText(P2QSTRING(jid.toBare().toString())); detailsPage_->setJID(jid); lastPage_ = 1; restart(); next(); detailsPage_->setName(name); } -void QtUserSearchWindow::setContactSuggestions(const std::vector<Contact>& suggestions) { +void QtUserSearchWindow::setContactSuggestions(const std::vector<Contact::ref>& suggestions) { if (type_ == AddContact) { firstPage_->jid_->setSuggestions(suggestions); } else { firstMultiJIDPage_->jid_->setSuggestions(suggestions); } } void QtUserSearchWindow::setJIDs(const std::vector<JID> &jids) { foreach(JID jid, jids) { addSearchedJIDToList(jid); } onJIDUpdateRequested(jids); } void QtUserSearchWindow::setRoomJID(const JID& roomJID) { roomJID_ = roomJID; } std::string QtUserSearchWindow::getReason() const { return Q2PSTRING(firstMultiJIDPage_->reason_->text()); } std::vector<JID> QtUserSearchWindow::getJIDs() const { std::vector<JID> jids; - foreach (const Contact& contact, contactVector_) { - jids.push_back(contact.jid); + foreach (Contact::ref contact, contactVector_) { + jids.push_back(contact->jid); } return jids; } void QtUserSearchWindow::setCanStartImpromptuChats(bool supportsImpromptu) { supportsImpromptu_ = supportsImpromptu; if (type_ == ChatToContact) { firstMultiJIDPage_->contactList_->setMaximumNoOfContactsToOne(!supportsImpromptu_); } } -void QtUserSearchWindow::updateContacts(const std::vector<Contact>& contacts) { +void QtUserSearchWindow::updateContacts(const std::vector<Contact::ref>& contacts) { if (type_ != AddContact) { firstMultiJIDPage_->contactList_->updateContacts(contacts); } } -void QtUserSearchWindow::addContacts(const std::vector<Contact>& contacts) { +void QtUserSearchWindow::addContacts(const std::vector<Contact::ref>& contacts) { if (type_ != AddContact) { /* prevent duplicate JIDs from appearing in the contact list */ - foreach (const Contact& newContact, contacts) { + foreach (Contact::ref newContact, contacts) { bool found = false; - foreach (const Contact& oldContact, contactVector_) { - if (newContact.jid == oldContact.jid) { + foreach (Contact::ref 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) { +void QtUserSearchWindow::handleListChanged(std::vector<Contact::ref> list) { contactVector_ = list; if (type_ == ChatToContact) { firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1)); } } void QtUserSearchWindow::handleJIDsAdded(std::vector<JID> 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_; model_ = newModel; resultsPage_->setNoResults(model_->rowCount() == 0); resultsPage_->emitCompletenessCheck(); } void QtUserSearchWindow::setResultsForm(Form::ref results) { QtFormResultItemModel *newModel = new QtFormResultItemModel(this); newModel->setForm(results); resultsPage_->results_->setModel(newModel); resultsPage_->results_->setItemDelegate(new QItemDelegate()); resultsPage_->results_->setHeaderHidden(false); #if QT_VERSION >= 0x050000 resultsPage_->results_->header()->setSectionResizeMode(QHeaderView::ResizeToContents); #else resultsPage_->results_->header()->setResizeMode(QHeaderView::ResizeToContents); #endif delete model_; model_ = newModel; resultsPage_->setNoResults(model_->rowCount() == 0); resultsPage_->emitCompletenessCheck(); } void QtUserSearchWindow::setSelectedService(const JID& jid) { myServer_ = jid; } void QtUserSearchWindow::setFirstPage(QString title) { if (page(1) != 0) { removePage(1); } if (type_ == AddContact) { firstPage_ = new QtUserSearchFirstPage(type_, title.isEmpty() ? firstPage_->title() : title, settings_); connect(firstPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleContactSuggestionRequested(QString))); connect(firstPage_->byJID_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange())); connect(firstPage_->byLocalSearch_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange())); connect(firstPage_->byRemoteSearch_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange())); #if QT_VERSION >= 0x040700 firstPage_->jid_->setPlaceholderText(tr("alice@wonderland.lit")); #endif firstPage_->service_->setEnabled(false); 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(onListChanged(std::vector<Contact::ref>)), this, SLOT(handleListChanged(std::vector<Contact::ref>))); 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(); fieldsPage_->fetchingThrobber_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this)); fieldsPage_->fetchingThrobber_->movie()->stop(); setPage(2, fieldsPage_); } void QtUserSearchWindow::setThirdPage() { if (page(3) != 0) { removePage(3); } resultsPage_ = new QtUserSearchResultsPage(); #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(next())); } setPage(3, resultsPage_); } void QtUserSearchWindow::clearForm() { diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.h b/Swift/QtUI/UserSearch/QtUserSearchWindow.h index 941e455..bb89e51 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchWindow.h +++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.h @@ -11,89 +11,89 @@ #include <Swift/QtUI/UserSearch/ui_QtUserSearchWizard.h> #include <Swift/Controllers/UIInterfaces/UserSearchWindow.h> namespace Swift { class UserSearchModel; class UserSearchDelegate; class UserSearchResult; class UIEventStream; class QtUserSearchFirstPage; class QtUserSearchFirstMultiJIDPage; class QtUserSearchFieldsPage; class QtUserSearchResultsPage; class QtUserSearchDetailsPage; class QtFormResultItemModel; class SettingsProvider; class QtUserSearchWindow : public QWizard, public UserSearchWindow, private Ui::QtUserSearchWizard { Q_OBJECT public: QtUserSearchWindow(UIEventStream* eventStream, UserSearchWindow::Type type, const std::set<std::string>& groups, SettingsProvider* settingsProvider); virtual ~QtUserSearchWindow(); virtual void addSavedServices(const std::vector<JID>& services); virtual void clear(); virtual void show(); virtual void setResults(const std::vector<UserSearchResult>& results); virtual void setResultsForm(Form::ref results); virtual void setSelectedService(const JID& jid); virtual void setServerSupportsSearch(bool error); virtual void setSearchError(bool error); virtual void setSearchFields(boost::shared_ptr<SearchPayload> fields); 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 setContactSuggestions(const std::vector<Contact::ref>& 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); + virtual void updateContacts(const std::vector<Contact::ref> &contacts); + virtual void addContacts(const std::vector<Contact::ref>& contacts); protected: virtual int nextId() const; private slots: void handleFirstPageRadioChange(); virtual void handleCurrentChanged(int); virtual void handleAccepted(); void handleContactSuggestionRequested(const QString& text); void addContact(); void handleAddViaSearch(); - void handleListChanged(std::vector<Contact> list); + void handleListChanged(std::vector<Contact::ref> list); void handleJIDsAdded(std::vector<JID> jids); private: void setFirstPage(QString title = ""); void setSecondPage(); void setThirdPage(); private: void clearForm(); void setError(const QString& error); JID getServerToSearch(); void handleSearch(); JID getContactJID() const; void addSearchedJIDToList(const JID& jid); private: UIEventStream* eventStream_; UserSearchWindow::Type type_; QAbstractItemModel* model_; UserSearchDelegate* delegate_; QtUserSearchFirstPage* firstPage_; QtUserSearchFirstMultiJIDPage* firstMultiJIDPage_; QtUserSearchFieldsPage* fieldsPage_; QtUserSearchResultsPage* resultsPage_; QtUserSearchDetailsPage* detailsPage_; JID myServer_; JID roomJID_; int lastPage_; - std::vector<Contact> contactVector_; + std::vector<Contact::ref> contactVector_; SettingsProvider* settings_; bool searchNext_; bool supportsImpromptu_; }; } |
Swift