summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2010-11-18 12:09:08 (GMT)
committerKevin Smith <git@kismith.co.uk>2010-12-22 20:19:07 (GMT)
commit9f04a7ec3429303118f12607703b877d8ba43888 (patch)
tree3e868395fa3c4f9cbbf84614094bb0251b425c15 /Swift/QtUI/UserSearch
parent04b99ce8430109d0467c29c85cb6bacb85c54c44 (diff)
downloadswift-9f04a7ec3429303118f12607703b877d8ba43888.zip
swift-9f04a7ec3429303118f12607703b877d8ba43888.tar.bz2
Basic User Search support, and Find Rooms cleanup.
Adds a throbber to the MUC search, turns the Add Contact dialog into something searchy, adds the option to open chats to arbitrary JIDs. Resolves: #614 Resolves: #695 Resolves: #436 Release-Notes: On servers that support it, users can now perform searches for contacts to add or chat to.
Diffstat (limited to 'Swift/QtUI/UserSearch')
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.cpp175
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.h48
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.ui292
-rw-r--r--Swift/QtUI/UserSearch/UserSearchDelegate.cpp86
-rw-r--r--Swift/QtUI/UserSearch/UserSearchDelegate.h21
-rw-r--r--Swift/QtUI/UserSearch/UserSearchModel.cpp60
-rw-r--r--Swift/QtUI/UserSearch/UserSearchModel.h32
7 files changed, 714 insertions, 0 deletions
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
new file mode 100644
index 0000000..c3038d8
--- /dev/null
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2010 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 <qdebug.h>
+#include <QModelIndex>
+
+#include "Swift/Controllers/UIEvents/UIEventStream.h"
+#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
+#include "Swift/Controllers/UIEvents/AddContactUIEvent.h"
+#include "Swift/QtUI/UserSearch/UserSearchModel.h"
+#include "Swift/QtUI/UserSearch/UserSearchDelegate.h"
+#include "Swift/QtUI/QtSwiftUtil.h"
+
+namespace Swift {
+
+QtUserSearchWindow::QtUserSearchWindow(UIEventStream* eventStream) {
+#ifndef Q_WS_MAC
+ setWindowIcon(QIcon(":/logo-icon-16.png"));
+#endif
+ eventStream_ = eventStream;
+ setupUi(this);
+ model_ = new UserSearchModel();
+ delegate_ = new UserSearchDelegate();
+ results_->setModel(model_);
+ results_->setItemDelegate(delegate_);
+ results_->setHeaderHidden(true);
+#ifdef SWIFT_PLATFORM_MACOSX
+ results_->setAlternatingRowColors(true);
+#endif
+ connect(service_, SIGNAL(activated(const QString&)), this, SLOT(handleGetForm()));
+ connect(getSearchForm_, SIGNAL(clicked()), this, SLOT(handleGetForm()));
+ //connect(user_, SIGNAL(returnPressed()), this, SLOT(handleJoin()));
+ //connect(nickName_, SIGNAL(returnPressed()), room_, SLOT(setFocus()));
+ connect(search_, SIGNAL(clicked()), this, SLOT(handleSearch()));
+
+ connect(results_, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleSelected(const QModelIndex&)));
+ connect(results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&)));
+ connect(buttonBox_, SIGNAL(accepted()), this, SLOT(handleOkClicked()));
+ connect(buttonBox_, SIGNAL(rejected()), this, SLOT(handleCancelClicked()));
+ /* When inputs change, check if OK is enabled */
+ connect(jid_, SIGNAL(textChanged(const QString&)), this, SLOT(enableCorrectButtons()));
+ connect(nickName_, SIGNAL(textChanged(const QString&)), this, SLOT(enableCorrectButtons()));
+ connect(startChat_, SIGNAL(stateChanged(int)), this, SLOT(enableCorrectButtons()));
+ connect(addToRoster_, SIGNAL(stateChanged(int)), this, SLOT(enableCorrectButtons()));
+ enableCorrectButtons();
+}
+
+QtUserSearchWindow::~QtUserSearchWindow() {
+
+}
+
+void QtUserSearchWindow::handleGetForm() {
+ lastServiceJID_ = JID(Q2PSTRING(service_->currentText()));
+ onFormRequested(lastServiceJID_);
+}
+
+void QtUserSearchWindow::handleSearch() {
+ boost::shared_ptr<SearchPayload> search(new SearchPayload());
+ if (nickInput_->isEnabled()) {
+ search->setNick(Q2PSTRING(nickInput_->text()));
+ }
+ if (firstInput_->isEnabled()) {
+ search->setFirst(Q2PSTRING(firstInput_->text()));
+ }
+ if (lastInput_->isEnabled()) {
+ search->setLast(Q2PSTRING(lastInput_->text()));
+ }
+ if (emailInput_->isEnabled()) {
+ search->setEMail(Q2PSTRING(emailInput_->text()));
+ }
+ onSearchRequested(search, lastServiceJID_);
+}
+
+void QtUserSearchWindow::show() {
+ clear();
+ enableCorrectButtons();
+ QWidget::show();
+}
+
+void QtUserSearchWindow::enableCorrectButtons() {
+ bool enable = !jid_->text().isEmpty() && (startChat_->isChecked() || (addToRoster_->isChecked() && !nickName_->text().isEmpty()));
+ buttonBox_->button(QDialogButtonBox::Ok)->setEnabled(enable);
+}
+
+void QtUserSearchWindow::handleOkClicked() {
+ JID contact = JID(Q2PSTRING(jid_->text()));
+ String nick = Q2PSTRING(nickName_->text());
+ if (addToRoster_->isChecked()) {
+ boost::shared_ptr<UIEvent> event(new AddContactUIEvent(contact, nick));
+ eventStream_->send(event);
+ }
+ if (startChat_->isChecked()) {
+ boost::shared_ptr<UIEvent> event(new RequestChatUIEvent(contact));
+ eventStream_->send(event);
+ }
+ hide();
+}
+
+void QtUserSearchWindow::handleCancelClicked() {
+ hide();
+}
+
+void QtUserSearchWindow::addSavedServices(const std::vector<JID>& services) {
+ service_->clear();
+ foreach (JID jid, services) {
+ service_->addItem(P2QSTRING(jid.toString()));
+ }
+ service_->clearEditText();
+}
+
+void QtUserSearchWindow::setServerSupportsSearch(bool support) {
+ if (!support) {
+ stack_->setCurrentIndex(0);
+ messageLabel_->setText("This service doesn't support searching for users.");
+ search_->setEnabled(false);
+ }
+}
+
+void QtUserSearchWindow::setSearchFields(boost::shared_ptr<SearchPayload> fields) {
+ bool enabled[8] = {fields->getNick(), fields->getNick(), fields->getFirst(), fields->getFirst(), fields->getLast(), fields->getLast(), fields->getEMail(), fields->getEMail()};
+ QWidget* widget[8] = {nickInputLabel_, nickInput_, firstInputLabel_, firstInput_, lastInputLabel_, lastInput_, emailInputLabel_, emailInput_};
+ for (int i = 0; i < 8; i++) {
+ widget[i]->setVisible(enabled[i]);
+ widget[i]->setEnabled(enabled[i]);
+ }
+ stack_->setCurrentIndex(1);
+ search_->setEnabled(true);
+}
+
+void QtUserSearchWindow::handleActivated(const QModelIndex& index) {
+ if (!index.isValid()) {
+ return;
+ }
+ UserSearchResult* userItem = static_cast<UserSearchResult*>(index.internalPointer());
+ if (userItem) { /* static cast, so always will be, but if we change to be like mucsearch, remember the check.*/
+ handleSelected(index);
+ //handleJoin(); /* Don't do anything automatically on selection.*/
+ }
+}
+
+void QtUserSearchWindow::handleSelected(const QModelIndex& current) {
+ if (!current.isValid()) {
+ return;
+ }
+ UserSearchResult* userItem = static_cast<UserSearchResult*>(current.internalPointer());
+ if (userItem) { /* Remember to leave this if we change to dynamic cast */
+ jid_->setText(P2QSTRING(userItem->getJID().toString()));
+ }
+}
+
+void QtUserSearchWindow::setResults(const std::vector<UserSearchResult>& results) {
+ model_->setResults(results);
+}
+
+void QtUserSearchWindow::setSelectedService(const JID& jid) {
+ service_->setEditText(P2QSTRING(jid.toString()));
+}
+
+void QtUserSearchWindow::clear() {
+ stack_->setCurrentIndex(0);
+ messageLabel_->setText("Please choose a service to search, above");
+ model_->clear();
+ search_->setEnabled(false);
+}
+
+void QtUserSearchWindow::setSearchError(bool error) {
+ //FIXME
+}
+
+}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.h b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
new file mode 100644
index 0000000..dca321a
--- /dev/null
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include "Swift/QtUI/UserSearch/ui_QtUserSearchWindow.h"
+
+#include "Swift/Controllers/UIInterfaces/UserSearchWindow.h"
+
+
+namespace Swift {
+ class UserSearchModel;
+ class UserSearchDelegate;
+ class UserSearchResult;
+ class UIEventStream;
+ class QtUserSearchWindow : public QWidget, public UserSearchWindow, private Ui::QtUserSearchWindow {
+ Q_OBJECT
+ public:
+ QtUserSearchWindow(UIEventStream* eventStream);
+ 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 setSelectedService(const JID& jid);
+ virtual void setServerSupportsSearch(bool error);
+ virtual void setSearchError(bool error);
+ virtual void setSearchFields(boost::shared_ptr<SearchPayload> fields) ;
+ private slots:
+ void handleGetForm();
+ void handleSelected(const QModelIndex& current);
+ void handleSearch();
+ void handleActivated(const QModelIndex& index);
+ void handleOkClicked();
+ void handleCancelClicked();
+ void enableCorrectButtons();
+ private:
+ UserSearchModel* model_;
+ UserSearchDelegate* delegate_;
+ UIEventStream* eventStream_;
+ JID lastServiceJID_;
+ };
+}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.ui b/Swift/QtUI/UserSearch/QtUserSearchWindow.ui
new file mode 100644
index 0000000..56047ce
--- /dev/null
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.ui
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtUserSearchWindow</class>
+ <widget class="QWidget" name="QtUserSearchWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>698</width>
+ <height>569</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Find other users</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetNoConstraint</enum>
+ </property>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Service to search:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="service_">
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="getSearchForm_">
+ <property name="text">
+ <string>Get Search Form</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="stack_">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="display">
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLabel" name="messageLabel_">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignHCenter|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="legacy">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Enter search terms</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="nickInputLabel_">
+ <property name="text">
+ <string>Nickname:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="nickInput_"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="firstInputLabel_">
+ <property name="text">
+ <string>First name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="firstInput_"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="lastInputLabel_">
+ <property name="text">
+ <string>Last name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="lastInput_"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="emailInputLabel_">
+ <property name="text">
+ <string>E-Mail:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLineEdit" name="emailInput_"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="search_">
+ <property name="text">
+ <string>Search</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Results:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeView" name="results_"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Address:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="jid_"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QCheckBox" name="addToRoster_">
+ <property name="text">
+ <string>Add to Roster. Nickname:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="nickName_"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QCheckBox" name="startChat_">
+ <property name="text">
+ <string>Start Chat With Contact</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox_">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/UserSearch/UserSearchDelegate.cpp b/Swift/QtUI/UserSearch/UserSearchDelegate.cpp
new file mode 100644
index 0000000..ff3e766
--- /dev/null
+++ b/Swift/QtUI/UserSearch/UserSearchDelegate.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <QPen>
+#include <QPainter>
+
+#include "Swift/QtUI/UserSearch/UserSearchDelegate.h"
+//#include "Swift/QtUI/Roster/GroupItemDelegate.h"
+//#include "Swift/QtUI/MUCSearch/MUCSearchItem.h"
+//#include "Swift/QtUI/MUCSearch/MUCSearchRoomItem.h"
+//#include "Swift/QtUI/MUCSearch/MUCSearchServiceItem.h"
+
+namespace Swift {
+
+UserSearchDelegate::UserSearchDelegate() {
+
+}
+
+UserSearchDelegate::~UserSearchDelegate() {
+
+}
+
+// QSize MUCSearchDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
+// // MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer());
+// // if (item && dynamic_cast<MUCSearchMUCItem*>(item)) {
+// // return mucSizeHint(option, index);
+// // } else if (item && dynamic_cast<MUCSearchGroupItem*>(item)) {
+// // return groupDelegate_->sizeHint(option, index);
+// // }
+// return QStyledItemDelegate::sizeHint(option, index);
+// }
+
+// QSize MUCSearchDelegate::mucSizeHint(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 MUCSearchDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
+// MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer());
+// if (item && dynamic_cast<MUCSearchMUCItem*>(item)) {
+// paintMUC(painter, option, dynamic_cast<MUCSearchMUCItem*>(item));
+// } else if (item && dynamic_cast<MUCSearchGroupItem*>(item)) {
+// MUCSearchGroupItem* group = dynamic_cast<MUCSearchGroupItem*>(item);
+// groupDelegate_->paint(painter, option, group->data(Qt::DisplayRole).toString(), group->rowCount(), option.state & QStyle::State_Open);
+// } else {
+// QStyledItemDelegate::paint(painter, option, index);
+// }
+// }
+
+// void MUCSearchDelegate::paintMUC(QPainter* painter, const QStyleOptionViewItem& option, MUCSearchMUCItem* item) const {
+// painter->save();
+// QRect fullRegion(option.rect);
+// if ( option.state & QStyle::State_Selected ) {
+// painter->fillRect(fullRegion, option.palette.highlight());
+// painter->setPen(option.palette.highlightedText().color());
+// } else {
+// QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
+// painter->setPen(QPen(nameColor));
+// }
+
+// QFontMetrics nameMetrics(common_.nameFont);
+// painter->setFont(common_.nameFont);
+// int extraFontWidth = nameMetrics.width("H");
+// int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
+// QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
+
+// int nameHeight = nameMetrics.height() + common_.verticalMargin;
+// QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
+
+// painter->drawText(nameRegion, Qt::AlignTop, item->data(Qt::DisplayRole).toString());
+
+// painter->setFont(common_.detailFont);
+// painter->setPen(QPen(QColor(160,160,160)));
+
+// QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
+// painter->drawText(detailRegion, Qt::AlignTop, item->data(DetailTextRole).toString());
+
+// painter->restore();
+// }
+
+}
diff --git a/Swift/QtUI/UserSearch/UserSearchDelegate.h b/Swift/QtUI/UserSearch/UserSearchDelegate.h
new file mode 100644
index 0000000..d046d62
--- /dev/null
+++ b/Swift/QtUI/UserSearch/UserSearchDelegate.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <QStyledItemDelegate>
+
+#include "Swift/QtUI/Roster/DelegateCommons.h"
+
+namespace Swift {
+ class UserSearchDelegate : public QStyledItemDelegate {
+ public:
+ UserSearchDelegate();
+ ~UserSearchDelegate();
+ };
+
+}
+
diff --git a/Swift/QtUI/UserSearch/UserSearchModel.cpp b/Swift/QtUI/UserSearch/UserSearchModel.cpp
new file mode 100644
index 0000000..782d2d0
--- /dev/null
+++ b/Swift/QtUI/UserSearch/UserSearchModel.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swift/QtUI/UserSearch/UserSearchModel.h"
+
+#include "Swift/QtUI/QtSwiftUtil.h"
+
+namespace Swift {
+
+UserSearchModel::UserSearchModel() {
+}
+
+void UserSearchModel::clear() {
+ emit layoutAboutToBeChanged();
+ results_.clear();
+ emit layoutChanged();
+}
+
+void UserSearchModel::setResults(const std::vector<UserSearchResult>& results) {
+ clear();
+ emit layoutAboutToBeChanged();
+ results_ = results;
+ emit layoutChanged();
+}
+
+int UserSearchModel::columnCount(const QModelIndex& /*parent*/) const {
+ return 1;
+}
+
+QVariant UserSearchModel::data(const QModelIndex& index, int role) const {
+ if (!index.isValid()) return QVariant();
+ UserSearchResult* result = static_cast<UserSearchResult*>(index.internalPointer());
+ switch (role) {
+ case Qt::DisplayRole: return QVariant(P2QSTRING(result->getJID().toString()));
+ default: return QVariant();
+ }
+}
+
+QModelIndex UserSearchModel::index(int row, int column, const QModelIndex & parent) const {
+ if (!hasIndex(row, column, parent)) {
+ return QModelIndex();
+ }
+ return row < (int)results_.size() ? createIndex(row, column, (void*)&(results_[row])) : QModelIndex();
+}
+
+QModelIndex UserSearchModel::parent(const QModelIndex& /*index*/) const {
+ return QModelIndex();
+}
+
+int UserSearchModel::rowCount(const QModelIndex& parentIndex) const {
+ if (!parentIndex.isValid()) {
+ return results_.size();
+ }
+ return 0;
+}
+
+}
diff --git a/Swift/QtUI/UserSearch/UserSearchModel.h b/Swift/QtUI/UserSearch/UserSearchModel.h
new file mode 100644
index 0000000..d766d9a
--- /dev/null
+++ b/Swift/QtUI/UserSearch/UserSearchModel.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include <QAbstractItemModel>
+#include <QList>
+
+#include "Swift/Controllers/Chat/UserSearchController.h"
+
+namespace Swift {
+ class UserSearchModel : public QAbstractItemModel {
+ Q_OBJECT
+ public:
+ UserSearchModel();
+ void clear();
+ void setResults(const std::vector<UserSearchResult>& results);
+ 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;
+ private:
+ std::vector<UserSearchResult> results_;
+ };
+
+}