diff options
Diffstat (limited to 'Swift/QtUI/MUCSearch')
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp | 111 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchDelegate.h | 26 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp | 46 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h | 23 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchItem.h | 18 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchModel.cpp | 130 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchModel.h | 44 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp | 30 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchRoomItem.h | 30 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchServiceItem.cpp | 78 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/MUCSearchServiceItem.h | 47 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp | 28 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h | 29 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp | 277 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/QtMUCSearchWindow.h | 84 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui | 62 |
16 files changed, 642 insertions, 421 deletions
diff --git a/Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp b/Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp index 828b89a..0163e03 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp +++ b/Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp @@ -1,17 +1,18 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include <QPen> +#include <Swift/QtUI/MUCSearch/MUCSearchDelegate.h> + #include <QPainter> +#include <QPen> -#include "Swift/QtUI/MUCSearch/MUCSearchDelegate.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" +#include <Swift/QtUI/MUCSearch/MUCSearchItem.h> +#include <Swift/QtUI/MUCSearch/MUCSearchRoomItem.h> +#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h> +#include <Swift/QtUI/Roster/GroupItemDelegate.h> namespace Swift { @@ -24,63 +25,63 @@ MUCSearchDelegate::~MUCSearchDelegate() { } // 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); +// // 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); +// 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); -// } +// 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(); +// 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/MUCSearch/MUCSearchDelegate.h b/Swift/QtUI/MUCSearch/MUCSearchDelegate.h index 57dcaee..5bf9646 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchDelegate.h +++ b/Swift/QtUI/MUCSearch/MUCSearchDelegate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -8,21 +8,21 @@ #include <QStyledItemDelegate> -#include "Swift/QtUI/Roster/DelegateCommons.h" +#include <Swift/QtUI/Roster/DelegateCommons.h> namespace Swift { - class MUCSearchDelegate : public QStyledItemDelegate { - public: - MUCSearchDelegate(); - ~MUCSearchDelegate(); - /* QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; */ - /* void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; */ - private: -// void paintMUC(QPainter* painter, const QStyleOptionViewItem& option, MUCSearchMUCItem* item) const; -// QSize mucSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const; + class MUCSearchDelegate : public QStyledItemDelegate { + public: + MUCSearchDelegate(); + ~MUCSearchDelegate(); + /* QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; */ + /* void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; */ + private: +// void paintMUC(QPainter* painter, const QStyleOptionViewItem& option, MUCSearchMUCItem* item) const; +// QSize mucSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const; - DelegateCommons common_; - }; + DelegateCommons common_; + }; } diff --git a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp index 492971a..3a3b841 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp +++ b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp @@ -1,38 +1,44 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h> -#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h> -#include <QFont> +#include <memory> + #include <QColor> +#include <QFont> + +#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h> namespace Swift { -MUCSearchEmptyItem::MUCSearchEmptyItem(MUCSearchServiceItem* parent) : parent(parent) { - parent->addRoom(this); +MUCSearchEmptyItem::MUCSearchEmptyItem() { +} + +void MUCSearchEmptyItem::setParent(std::weak_ptr<MUCSearchServiceItem> parent) { + parent_ = parent; } -MUCSearchServiceItem* MUCSearchEmptyItem::getParent() { - return parent; +std::shared_ptr<MUCSearchServiceItem> MUCSearchEmptyItem::getParent() { + return parent_.lock(); } QVariant MUCSearchEmptyItem::data(int role) { - switch (role) { - case Qt::DisplayRole: - return QVariant(QObject::tr("No rooms found")); - case Qt::FontRole: { - QFont font; - font.setItalic(true); - return font; - } - case Qt::ForegroundRole: - return QColor(Qt::gray); - default: - return QVariant(); - } + switch (role) { + case Qt::DisplayRole: + return QVariant(QObject::tr("No rooms found")); + case Qt::FontRole: { + QFont font; + font.setItalic(true); + return font; + } + case Qt::ForegroundRole: + return QColor(Qt::gray); + default: + return QVariant(); + } } } diff --git a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h index 74e0154..8a5bb06 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h +++ b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h @@ -1,25 +1,28 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once +#include <memory> + #include <Swift/QtUI/MUCSearch/MUCSearchItem.h> namespace Swift { - class MUCSearchServiceItem; + class MUCSearchServiceItem; - class MUCSearchEmptyItem : public MUCSearchItem { - public: - MUCSearchEmptyItem(MUCSearchServiceItem* parent); + class MUCSearchEmptyItem : public MUCSearchItem { + public: + MUCSearchEmptyItem(); - MUCSearchServiceItem* getParent(); + void setParent(std::weak_ptr<MUCSearchServiceItem> parent); + std::shared_ptr<MUCSearchServiceItem> getParent(); - QVariant data(int role); + QVariant data(int role); - private: - MUCSearchServiceItem* parent; - }; + private: + std::weak_ptr<MUCSearchServiceItem> parent_; + }; } diff --git a/Swift/QtUI/MUCSearch/MUCSearchItem.h b/Swift/QtUI/MUCSearch/MUCSearchItem.h index d2a2c2d..08daa21 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchItem.h +++ b/Swift/QtUI/MUCSearch/MUCSearchItem.h @@ -1,17 +1,23 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once +#include <memory> + #include <QVariant> namespace Swift { - class MUCSearchItem { - public: - virtual ~MUCSearchItem() {} - virtual QVariant data(int role) = 0; - }; + +class MUCSearchServiceItem; + +class MUCSearchItem { + public: + virtual ~MUCSearchItem() {} + virtual void setParent(std::weak_ptr<MUCSearchServiceItem>) { } + virtual QVariant data(int role) = 0; + }; } diff --git a/Swift/QtUI/MUCSearch/MUCSearchModel.cpp b/Swift/QtUI/MUCSearch/MUCSearchModel.cpp index adb2a11..cc36f5f 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchModel.cpp +++ b/Swift/QtUI/MUCSearch/MUCSearchModel.cpp @@ -1,11 +1,14 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include "Swift/QtUI/MUCSearch/MUCSearchModel.h" -#include "Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h" +#include <Swift/QtUI/MUCSearch/MUCSearchModel.h> + +#include <memory> + +#include <Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h> namespace Swift { @@ -13,78 +16,91 @@ MUCSearchModel::MUCSearchModel() { } void MUCSearchModel::clear() { - emit layoutAboutToBeChanged(); - services_.clear(); - emit layoutChanged(); + // We need to reset the model, so that model indices containing raw pointers + // to MUCSearchServiceItems are invalaidated before we delete the + // MUCSearchServiceItems. + emit beginResetModel(); + services_.clear(); + emit endResetModel(); } -void MUCSearchModel::addService(MUCSearchServiceItem* service) { - emit layoutAboutToBeChanged(); - services_.push_back(service); - emit layoutChanged(); +void MUCSearchModel::addService(std::shared_ptr<MUCSearchServiceItem> service) { + emit layoutAboutToBeChanged(); + if (sortOrder_) { + service->setSorting(*sortOrder_); + } + services_.push_back(service); + emit layoutChanged(); } int MUCSearchModel::columnCount(const QModelIndex& /*parent*/) const { - return 1; + return 1; } QVariant MUCSearchModel::data(const QModelIndex& index, int role) const { - return index.isValid() ? static_cast<MUCSearchItem*>(index.internalPointer())->data(role) : QVariant(); + return index.isValid() ? static_cast<MUCSearchItem*>(index.internalPointer())->data(role) : QVariant(); } QModelIndex MUCSearchModel::index(int row, int column, const QModelIndex & parent) const { - if (!hasIndex(row, column, parent)) { - return QModelIndex(); - } - - if (parent.isValid()) { - MUCSearchServiceItem* parentItem = static_cast<MUCSearchServiceItem*>(parent.internalPointer()); - return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex(); - } else { - return row < services_.size() ? createIndex(row, column, services_[row]) : QModelIndex(); - } - + if (!hasIndex(row, column, parent)) { + return QModelIndex(); + } + if (parent.isValid()) { + MUCSearchServiceItem* parentItem = static_cast<MUCSearchServiceItem*>(parent.internalPointer()); + return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex(); + } else { + return row < services_.size() ? createIndex(row, column, services_[row].get()) : QModelIndex(); + } } QModelIndex MUCSearchModel::parent(const QModelIndex& index) const { - if (!index.isValid()) { - return QModelIndex(); - } - MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer()); - if (!item) { - return QModelIndex(); - } - else if (dynamic_cast<MUCSearchServiceItem*>(item)) { - return QModelIndex(); - } - - MUCSearchServiceItem* parent = NULL; - if (MUCSearchRoomItem* roomItem = dynamic_cast<MUCSearchRoomItem*>(item)) { - parent = roomItem->getParent(); - } - else if (MUCSearchEmptyItem* emptyItem = dynamic_cast<MUCSearchEmptyItem*>(item)) { - parent = emptyItem->getParent(); - } - if (parent) { - int row = services_.indexOf(parent); - return createIndex(row, 1, parent); - } - else { - return QModelIndex(); - } + if (!index.isValid()) { + return QModelIndex(); + } + MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer()); + if (!item) { + return QModelIndex(); + } + else if (dynamic_cast<MUCSearchServiceItem*>(item)) { + return QModelIndex(); + } + + std::shared_ptr<MUCSearchServiceItem> parent; + if (MUCSearchRoomItem* roomItem = dynamic_cast<MUCSearchRoomItem*>(item)) { + parent = roomItem->getParent(); + } + else if (MUCSearchEmptyItem* emptyItem = dynamic_cast<MUCSearchEmptyItem*>(item)) { + parent = emptyItem->getParent(); + } + if (parent) { + int row = services_.indexOf(parent); + return createIndex(row, 1, parent.get()); + } + else { + return QModelIndex(); + } } int MUCSearchModel::rowCount(const QModelIndex& parentIndex) const { - if (!parentIndex.isValid()) { - return services_.size(); - } - if (dynamic_cast<MUCSearchServiceItem*>(static_cast<MUCSearchItem*>(parentIndex.internalPointer()))) { - return services_[parentIndex.row()]->rowCount(); - } - else { - return 0; - } + if (!parentIndex.isValid()) { + return services_.size(); + } + if (dynamic_cast<MUCSearchServiceItem*>(static_cast<MUCSearchItem*>(parentIndex.internalPointer()))) { + return services_[parentIndex.row()]->rowCount(); + } + else { + return 0; + } +} + +void MUCSearchModel::sort(int column, Qt::SortOrder order) { + sortOrder_ = order; + if (column == 0) { + for (auto&& serviceItem : services_) { + serviceItem->setSorting(*sortOrder_); + } + } } } diff --git a/Swift/QtUI/MUCSearch/MUCSearchModel.h b/Swift/QtUI/MUCSearch/MUCSearchModel.h index e18a1c0..f36d147 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchModel.h +++ b/Swift/QtUI/MUCSearch/MUCSearchModel.h @@ -1,35 +1,37 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once -#include <boost/shared_ptr.hpp> +#include <memory> + +#include <boost/optional.hpp> #include <QAbstractItemModel> -#include <QList> +#include <QVector> -#include "Swift/QtUI/MUCSearch/MUCSearchServiceItem.h" +#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h> namespace Swift { - class MUCSearchModel : public QAbstractItemModel { - Q_OBJECT - public: - MUCSearchModel(); - void clear(); - void addService(MUCSearchServiceItem* service); - 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; -// ChatListItem* getItemForIndex(const QModelIndex& index) const; - private: -// ChatListGroupItem* mucBookmarks_; -// ChatListGroupItem* root_; - QList<MUCSearchServiceItem*> services_; - }; + class MUCSearchModel : public QAbstractItemModel { + Q_OBJECT + public: + MUCSearchModel(); + void clear(); + void addService(std::shared_ptr<MUCSearchServiceItem> service); + 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; + virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); + + private: + QVector<std::shared_ptr<MUCSearchServiceItem>> services_; + boost::optional<Qt::SortOrder> sortOrder_; + }; } diff --git a/Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp b/Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp index a8c7bbe..9c3ef2c 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp +++ b/Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp @@ -1,26 +1,34 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include "Swift/QtUI/MUCSearch/MUCSearchRoomItem.h" +#include <Swift/QtUI/MUCSearch/MUCSearchRoomItem.h> -#include "Swift/QtUI/MUCSearch/MUCSearchServiceItem.h" +#include <memory> + +#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h> namespace Swift { -MUCSearchRoomItem::MUCSearchRoomItem(const QString& node, MUCSearchServiceItem* parent) : parent_(parent), node_(node) { - parent_->addRoom(this); + +MUCSearchRoomItem::MUCSearchRoomItem(const QString& node) : node_(node) { + } -MUCSearchServiceItem* MUCSearchRoomItem::getParent() { - return parent_; +void MUCSearchRoomItem::setParent(std::weak_ptr<MUCSearchServiceItem> parent) { + parent_ = parent; } + +std::shared_ptr<MUCSearchServiceItem> MUCSearchRoomItem::getParent() { + return parent_.lock(); +} + QVariant MUCSearchRoomItem::data(int role) { - switch (role) { - case Qt::DisplayRole: return QVariant(node_); - default: return QVariant(); - } + switch (role) { + case Qt::DisplayRole: return QVariant(node_); + default: return QVariant(); + } } } diff --git a/Swift/QtUI/MUCSearch/MUCSearchRoomItem.h b/Swift/QtUI/MUCSearch/MUCSearchRoomItem.h index d0f8daa..5ecb7d7 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchRoomItem.h +++ b/Swift/QtUI/MUCSearch/MUCSearchRoomItem.h @@ -1,23 +1,27 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once -#include "Swift/QtUI/MUCSearch/MUCSearchItem.h" +#include <memory> + +#include <Swift/QtUI/MUCSearch/MUCSearchItem.h> namespace Swift { - class MUCSearchServiceItem; - class MUCSearchRoomItem : public MUCSearchItem { - public: - MUCSearchRoomItem(const QString& node, MUCSearchServiceItem* parent); - MUCSearchServiceItem* getParent(); - QVariant data(int role); - QString getNode() const {return node_;} - private: - MUCSearchServiceItem* parent_; - QString node_; - }; + class MUCSearchServiceItem; + class MUCSearchRoomItem : public MUCSearchItem { + public: + MUCSearchRoomItem(const QString& node); + void setParent(std::weak_ptr<MUCSearchServiceItem> parent); + std::shared_ptr<MUCSearchServiceItem> getParent(); + QVariant data(int role); + QString getNode() const {return node_;} + + private: + std::weak_ptr<MUCSearchServiceItem> parent_; + QString node_; + }; } diff --git a/Swift/QtUI/MUCSearch/MUCSearchServiceItem.cpp b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.cpp new file mode 100644 index 0000000..57d5aac --- /dev/null +++ b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2010-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h> + +#include <memory> + +#include <QString> +#include <QVector> +#include <QtAlgorithms> + +namespace Swift { + +MUCSearchServiceItem::MUCSearchServiceItem(const QString& jidString) : jidString_(jidString) { + +} + +void MUCSearchServiceItem::addRoom(std::shared_ptr<MUCSearchItem> room) { + room->setParent(shared_from_this()); + rooms_.push_back(room); + if (sortOrder_) { + sort(); + } +} + +void MUCSearchServiceItem::addRooms(const std::vector<std::shared_ptr<MUCSearchItem> >& rooms) { + for (auto&& room: rooms) { + room->setParent(shared_from_this()); + rooms_.push_back(room); + } + if (sortOrder_) { + sort(); + } +} + +int MUCSearchServiceItem::rowCount() { + return rooms_.count(); +} + +MUCSearchItem* MUCSearchServiceItem::getItem(int i) { + return rooms_[i].get(); +} + +QVariant MUCSearchServiceItem::data(int role) { + switch (role) { + case Qt::DisplayRole: + return QVariant(jidString_); + default: + return QVariant(); + } +} + +QString MUCSearchServiceItem::getHost() const { + return jidString_; +} + +void MUCSearchServiceItem::setSorting(Qt::SortOrder sortOrder) { + sortOrder_ = sortOrder; + sort(); +} + +void MUCSearchServiceItem::sort() { + if (*sortOrder_ == Qt::AscendingOrder) { + qStableSort(rooms_.begin(), rooms_.end(), [](const std::shared_ptr<MUCSearchItem>& item1, const std::shared_ptr<MUCSearchItem>& item2) -> bool { + return QString::localeAwareCompare(item1->data(Qt::DisplayRole).toString(), item2->data(Qt::DisplayRole).toString()) < 0; + }); + } + else { + qStableSort(rooms_.begin(), rooms_.end(), [](const std::shared_ptr<MUCSearchItem>& item1, const std::shared_ptr<MUCSearchItem>& item2) -> bool { + return QString::localeAwareCompare(item1->data(Qt::DisplayRole).toString(), item2->data(Qt::DisplayRole).toString()) > 0; + }); + } +} + +} diff --git a/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h index 306e85a..9f5e000 100644 --- a/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h +++ b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h @@ -1,32 +1,39 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once -#include <QList> +#include <memory> + +#include <boost/optional.hpp> + #include <QString> +#include <QVector> -#include "Swift/QtUI/MUCSearch/MUCSearchRoomItem.h" +#include <Swift/QtUI/MUCSearch/MUCSearchRoomItem.h> namespace Swift { - class MUCSearchServiceItem : public MUCSearchItem { - public: - MUCSearchServiceItem(const QString& jidString) : jidString_(jidString) {} - void addRoom(MUCSearchItem* room) {rooms_.push_back(room);} - int rowCount() {return rooms_.count();} - MUCSearchItem* getItem(int i) {return rooms_[i];} - QVariant data(int role) { - switch (role) { - case Qt::DisplayRole: return QVariant(jidString_); - default: return QVariant(); - } - } - QString getHost() const {return jidString_;} - private: - QList<MUCSearchItem*> rooms_; - QString jidString_; - }; + class MUCSearchServiceItem : public MUCSearchItem, public std::enable_shared_from_this<MUCSearchServiceItem> { + public: + MUCSearchServiceItem(const QString& jidString); + + void addRoom(std::shared_ptr<MUCSearchItem> room); + void addRooms(const std::vector<std::shared_ptr<MUCSearchItem>>& rooms); + int rowCount(); + MUCSearchItem* getItem(int i); + QVariant data(int role); + QString getHost() const; + void setSorting(Qt::SortOrder sortOrder); + + private: + void sort(); + + private: + QVector<std::shared_ptr<MUCSearchItem>> rooms_; + QString jidString_; + boost::optional<Qt::SortOrder> sortOrder_; + }; } diff --git a/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp new file mode 100644 index 0000000..b8cf15a --- /dev/null +++ b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h> + +namespace Swift { + +QtLeafSortFilterProxyModel::QtLeafSortFilterProxyModel(QObject* parent) : QSortFilterProxyModel(parent) { + +} + +QtLeafSortFilterProxyModel::~QtLeafSortFilterProxyModel() { + +} + +bool QtLeafSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { + if (!sourceModel()->hasChildren(sourceModel()->index(source_row, 0, source_parent))) { + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); + } + else { + return true; + } +} + +} diff --git a/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h new file mode 100644 index 0000000..b4be622 --- /dev/null +++ b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include <QSortFilterProxyModel> + +namespace Swift { + +/** + * @brief The QtLeafSortFilterProxyModel class is similar to the QSortFilterProxyModel + * class. While the basic QSortFilterProxyModel class filters all hierarchical items, + * the QtLeafSortFilterProxyModel class will only filter on items without children. + */ +class QtLeafSortFilterProxyModel : public QSortFilterProxyModel { + Q_OBJECT + +public: + QtLeafSortFilterProxyModel(QObject* parent = nullptr); + virtual ~QtLeafSortFilterProxyModel(); + +protected: + virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; +}; + +} diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp index bafb958..f69da41 100644 --- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp +++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp @@ -1,58 +1,68 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include "Swift/QtUI/MUCSearch/QtMUCSearchWindow.h" +#include <Swift/QtUI/MUCSearch/QtMUCSearchWindow.h> + +#include <memory> +#include <vector> -#include <qdebug.h> #include <QMovie> +#include <QPushButton> #include <QScrollBar> +#include <QSortFilterProxyModel> #include <QTimer> -#include <QPushButton> -#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h" -#include "Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h" -#include "Swift/QtUI/MUCSearch/MUCSearchModel.h" -#include "Swift/QtUI/MUCSearch/MUCSearchDelegate.h" -#include "Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h" -#include "Swift/QtUI/QtSwiftUtil.h" +#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h> +#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> + +#include <Swift/QtUI/MUCSearch/MUCSearchDelegate.h> +#include <Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h> +#include <Swift/QtUI/MUCSearch/MUCSearchModel.h> +#include <Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h> +#include <Swift/QtUI/QtSwiftUtil.h> namespace Swift { QtMUCSearchWindow::QtMUCSearchWindow() { - ui_.setupUi(this); + ui_.setupUi(this); #ifndef Q_OS_MAC - setWindowIcon(QIcon(":/logo-icon-16.png")); + setWindowIcon(QIcon(":/logo-icon-16.png")); #endif - setModal(true); - ui_.filter_->hide(); - model_ = new MUCSearchModel(); - delegate_ = new MUCSearchDelegate(); - ui_.results_->setModel(model_); - ui_.results_->setItemDelegate(delegate_); - ui_.results_->setHeaderHidden(true); - ui_.results_->setRootIsDecorated(true); - ui_.results_->setAnimated(true); - ui_.results_->setAlternatingRowColors(true); - connect(ui_.searchButton, SIGNAL(clicked()), this, SLOT(handleSearch())); - connect(ui_.service_, SIGNAL(activated(const QString&)), this, SLOT(handleSearch(const QString&))); - connect(ui_.results_->selectionModel(), SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)), this, SLOT(handleSelectionChanged (const QItemSelection&, const QItemSelection&))); - connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&))); - connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&))); - // Not using a button box, because i can't seem to be able to make the ok button non-default (on mac) - connect(ui_.okButton, SIGNAL(clicked()), this, SLOT(accept())); - ui_.okButton->setEnabled(false); - connect(ui_.cancelButton, SIGNAL(clicked()), this, SLOT(reject())); - - throbber_ = new QLabel(tr("Searching"), ui_.results_); - throbber_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), throbber_)); - throbber_->setToolTip(tr("Searching")); - - hasHadScrollBars_ = false; - updateThrobberPosition(); - setSearchInProgress(false); + setModal(true); + model_ = new MUCSearchModel(); + sortFilterProxyModel_ = new QtLeafSortFilterProxyModel(this); + sortFilterProxyModel_->setSourceModel(model_); + sortFilterProxyModel_->setDynamicSortFilter(true); + delegate_ = new MUCSearchDelegate(); + ui_.results_->setModel(sortFilterProxyModel_); + ui_.results_->setItemDelegate(delegate_); + ui_.results_->setHeaderHidden(true); + ui_.results_->setRootIsDecorated(true); + ui_.results_->setAnimated(true); + ui_.results_->setAlternatingRowColors(true); + ui_.results_->setSortingEnabled(true); + ui_.results_->sortByColumn(0, Qt::AscendingOrder); + connect(ui_.searchButton_, SIGNAL(clicked()), this, SLOT(handleSearch())); + connect(ui_.service_, SIGNAL(activated(const QString&)), this, SLOT(handleSearch(const QString&))); + connect(ui_.results_->selectionModel(), SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)), this, SLOT(handleSelectionChanged (const QItemSelection&, const QItemSelection&))); + connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&))); + connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&))); + // Not using a button box, because i can't seem to be able to make the ok button non-default (on mac) + connect(ui_.okButton, SIGNAL(clicked()), this, SLOT(accept())); + ui_.okButton->setEnabled(false); + connect(ui_.cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui_.filter_, SIGNAL(textChanged(const QString&)), this, SLOT(handleFilterStringChanged(const QString&))); + + throbber_ = new QLabel(tr("Searching"), ui_.results_); + throbber_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), throbber_)); + throbber_->setToolTip(tr("Searching")); + + hasHadScrollBars_ = false; + updateThrobberPosition(); + setSearchInProgress(false); } QtMUCSearchWindow::~QtMUCSearchWindow() { @@ -60,136 +70,145 @@ QtMUCSearchWindow::~QtMUCSearchWindow() { } void QtMUCSearchWindow::resizeEvent(QResizeEvent* /*event*/) { - updateThrobberPosition(); + updateThrobberPosition(); } void QtMUCSearchWindow::updateThrobberPosition() { - bool isShown = throbber_->isVisible(); - int resultWidth = ui_.results_->width(); - int resultHeight = ui_.results_->height(); - //throbberWidth = throbber_->movie()->scaledSize().width(); - //throbberHeight = throbber_->movie()->scaledSize().height(); - int throbberWidth = 16; /* This is nasty, but the above doesn't work! */ - int throbberHeight = 16; - /* It's difficult (or I spent a while trying) to work out whether the scrollbars are currently shown and their appropriate size, - * because if you listen for the expanded/collapsed signals, you seem to get them before the scrollbars are updated. - * This seems an acceptable workaround. - */ - hasHadScrollBars_ |= ui_.results_->verticalScrollBar()->isVisible(); - int hMargin = hasHadScrollBars_ ? ui_.results_->verticalScrollBar()->width() + 2 : 2; - int vMargin = 2; /* We don't get horizontal scrollbars */ - throbber_->setGeometry(QRect(resultWidth - throbberWidth - hMargin, resultHeight - throbberHeight - vMargin, throbberWidth, throbberHeight)); /* include margins */ - throbber_->setVisible(isShown); + bool isShown = throbber_->isVisible(); + int resultWidth = ui_.results_->width(); + int resultHeight = ui_.results_->height(); + //throbberWidth = throbber_->movie()->scaledSize().width(); + //throbberHeight = throbber_->movie()->scaledSize().height(); + int throbberWidth = 16; /* This is nasty, but the above doesn't work! */ + int throbberHeight = 16; + /* It's difficult (or I spent a while trying) to work out whether the scrollbars are currently shown and their appropriate size, + * because if you listen for the expanded/collapsed signals, you seem to get them before the scrollbars are updated. + * This seems an acceptable workaround. + */ + hasHadScrollBars_ |= ui_.results_->verticalScrollBar()->isVisible(); + int hMargin = hasHadScrollBars_ ? ui_.results_->verticalScrollBar()->width() + 2 : 2; + int vMargin = 2; /* We don't get horizontal scrollbars */ + throbber_->setGeometry(QRect(resultWidth - throbberWidth - hMargin, resultHeight - throbberHeight - vMargin, throbberWidth, throbberHeight)); /* include margins */ + throbber_->setVisible(isShown); } void QtMUCSearchWindow::addSavedServices(const std::list<JID>& services) { - ui_.service_->clear(); - foreach (const JID& jid, services) { - ui_.service_->addItem(P2QSTRING(jid.toString())); - } - if (!services.empty()) { - ui_.service_->setEditText(P2QSTRING(services.begin()->toString())); - } - else { - ui_.service_->clearEditText(); - } + ui_.service_->clear(); + for (const auto& jid : services) { + ui_.service_->addItem(P2QSTRING(jid.toString())); + } + if (!services.empty()) { + ui_.service_->setEditText(P2QSTRING(services.begin()->toString())); + } + else { + ui_.service_->clearEditText(); + } } void QtMUCSearchWindow::handleActivated(const QModelIndex& index) { - if (!index.isValid()) { - return; - } - if (dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(index.internalPointer()))) { - accept(); - } + if (!index.isValid()) { + return; + } + if (dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(sortFilterProxyModel_->mapToSource(index).internalPointer()))) { + accept(); + } } void QtMUCSearchWindow::handleSearch() { - handleSearch(ui_.service_->currentText()); + handleSearch(ui_.service_->currentText()); } void QtMUCSearchWindow::handleSearch(const QString& service) { - if (!service.isEmpty()) { - onSearchService(JID(Q2PSTRING(service))); - } + if (!service.isEmpty()) { + onSearchService(JID(Q2PSTRING(service))); + } +} + +void QtMUCSearchWindow::handleFilterStringChanged(const QString& filterString) { + sortFilterProxyModel_->setFilterRegExp(filterString); } void QtMUCSearchWindow::show() { - QWidget::show(); - QWidget::activateWindow(); + ui_.filter_->clear(); + QWidget::show(); + QWidget::activateWindow(); } void QtMUCSearchWindow::clearList() { - model_->clear(); + model_->clear(); } void QtMUCSearchWindow::addService(const MUCService& service) { - updateThrobberPosition(); - MUCSearchServiceItem* serviceItem = new MUCSearchServiceItem(P2QSTRING(service.getJID().toString())); - if (service.getRooms().size() > 0) { - foreach (MUCService::MUCRoom room, service.getRooms()) { - new MUCSearchRoomItem(P2QSTRING(room.getNode()), serviceItem); - } - } - else { - new MUCSearchEmptyItem(serviceItem); - } - model_->addService(serviceItem); - ui_.results_->expandAll(); + updateThrobberPosition(); + auto serviceItem = std::make_shared<MUCSearchServiceItem>(P2QSTRING(service.getJID().toString())); + if (service.getRooms().size() > 0) { + std::vector<std::shared_ptr<MUCSearchItem>> rooms; + for (auto&& room : service.getRooms()) { + if (!room.getNode().empty()) { + rooms.push_back(std::make_shared<MUCSearchRoomItem>(P2QSTRING(room.getNode()))); + } + } + serviceItem->addRooms(rooms); + } + else { + serviceItem->addRoom(std::make_shared<MUCSearchEmptyItem>()); + } + model_->addService(serviceItem); + ui_.results_->expandAll(); } void QtMUCSearchWindow::setSearchInProgress(bool searching) { - if (searching) { - throbber_->movie()->start(); - } else { - throbber_->movie()->stop(); - } - throbber_->setVisible(searching); + if (searching) { + throbber_->movie()->start(); + } else { + throbber_->movie()->stop(); + } + throbber_->setVisible(searching); } void QtMUCSearchWindow::accept() { - MUCSearchRoomItem* room = getSelectedRoom(); - if (room) { - onFinished(JID(Q2PSTRING(room->getNode()), Q2PSTRING(room->getParent()->getHost()))); - } - else { - onFinished(boost::optional<JID>()); - } - QDialog::accept(); + MUCSearchRoomItem* room = getSelectedRoom(); + if (room) { + onFinished(JID(Q2PSTRING(room->getNode()), Q2PSTRING(room->getParent()->getHost()))); + } + else { + onFinished(boost::optional<JID>()); + } + QDialog::accept(); } void QtMUCSearchWindow::reject() { - onFinished(boost::optional<JID>()); - QDialog::reject(); + onFinished(boost::optional<JID>()); + QDialog::reject(); } void QtMUCSearchWindow::handleSelectionChanged(const QItemSelection&, const QItemSelection&) { - ui_.okButton->setEnabled(getSelectedRoom()); + ui_.okButton->setEnabled(getSelectedRoom()); } MUCSearchRoomItem* QtMUCSearchWindow::getSelectedRoom() const { - // Not using selectedIndexes(), because this seems to cause a crash in Qt (4.7.0) in the - // QModelIndexList destructor. - // This is a workaround posted in http://www.qtcentre.org/threads/16933 (although this case - // was resolved by linking against the debug libs, ours isn't, and we're not alone) - QItemSelection ranges = ui_.results_->selectionModel()->selection(); - QModelIndexList lstIndex; - for (int i = 0; i < ranges.count(); ++i) { - QModelIndex parent = ranges.at(i).parent(); - int right = ranges.at(i).model()->columnCount(parent) - 1; - if (ranges.at(i).left() == 0 && ranges.at(i).right() == right) { - for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r) { - lstIndex.append(ranges.at(i).model()->index(r, 0, parent)); - } - } - } - if (lstIndex.isEmpty()) { - return NULL; - } - else { - return dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(lstIndex.first().internalPointer())); - } + // Not using selectedIndexes(), because this seems to cause a crash in Qt (4.7.0) in the + // QModelIndexList destructor. + // This is a workaround posted in http://www.qtcentre.org/threads/16933 (although this case + // was resolved by linking against the debug libs, ours isn't, and we're not alone) + QItemSelection ranges = ui_.results_->selectionModel()->selection(); + QModelIndexList lstIndex; + for (int i = 0; i < ranges.count(); ++i) { + QModelIndex parent = ranges.at(i).parent(); + int right = ranges.at(i).model()->columnCount(parent) - 1; + if (ranges.at(i).left() == 0 && ranges.at(i).right() == right) { + for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r) { + lstIndex.append(ranges.at(i).model()->index(r, 0, parent)); + } + } + } + if (lstIndex.isEmpty()) { + return nullptr; + } + else { + return dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(sortFilterProxyModel_->mapToSource(lstIndex.first()).internalPointer())); + } } } diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h index bc9fb43..6f38533 100644 --- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h +++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h @@ -1,51 +1,55 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once -#include "Swift/QtUI/MUCSearch/ui_QtMUCSearchWindow.h" +#include <Swift/Controllers/UIInterfaces/MUCSearchWindow.h> -#include "Swift/Controllers/UIInterfaces/MUCSearchWindow.h" +#include <Swift/QtUI/MUCSearch/ui_QtMUCSearchWindow.h> + +class QSortFilterProxyModel; namespace Swift { - class MUCSearchModel; - class MUCSearchDelegate; - class MUCSearchRoomItem; - - class QtMUCSearchWindow : public QDialog, public MUCSearchWindow { - Q_OBJECT - public: - QtMUCSearchWindow(); - virtual ~QtMUCSearchWindow(); - - virtual void clearList(); - virtual void addService(const MUCService& service); - virtual void addSavedServices(const std::list<JID>& services); - virtual void setSearchInProgress(bool searching); - - virtual void show(); - virtual void accept(); - virtual void reject(); - - protected: - virtual void resizeEvent(QResizeEvent* event); - - private slots: - void handleSearch(); - void handleSearch(const QString&); - void handleActivated(const QModelIndex& index); - void updateThrobberPosition(); - void handleSelectionChanged (const QItemSelection&, const QItemSelection&); - MUCSearchRoomItem* getSelectedRoom() const; - - private: - Ui::QtMUCSearchWindow ui_; - MUCSearchModel* model_; - MUCSearchDelegate* delegate_; - QLabel* throbber_; - bool hasHadScrollBars_; - }; + class MUCSearchModel; + class MUCSearchDelegate; + class MUCSearchRoomItem; + + class QtMUCSearchWindow : public QDialog, public MUCSearchWindow { + Q_OBJECT + public: + QtMUCSearchWindow(); + virtual ~QtMUCSearchWindow(); + + virtual void clearList(); + virtual void addService(const MUCService& service); + virtual void addSavedServices(const std::list<JID>& services); + virtual void setSearchInProgress(bool searching); + + virtual void show(); + virtual void accept(); + virtual void reject(); + + protected: + virtual void resizeEvent(QResizeEvent* event); + + private slots: + void handleSearch(); + void handleSearch(const QString&); + void handleFilterStringChanged(const QString&); + void handleActivated(const QModelIndex& index); + void updateThrobberPosition(); + void handleSelectionChanged (const QItemSelection&, const QItemSelection&); + MUCSearchRoomItem* getSelectedRoom() const; + + private: + Ui::QtMUCSearchWindow ui_; + MUCSearchModel* model_; + MUCSearchDelegate* delegate_; + QLabel* throbber_; + bool hasHadScrollBars_; + QSortFilterProxyModel* sortFilterProxyModel_ = nullptr; + }; } diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui index 49460ab..52714c4 100644 --- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui +++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui @@ -6,21 +6,14 @@ <rect> <x>0</x> <y>0</y> - <width>523</width> - <height>368</height> + <width>566</width> + <height>264</height> </rect> </property> <property name="windowTitle"> <string>Search Room</string> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Service:</string> - </property> - </widget> - </item> <item row="0" column="1"> <widget class="QComboBox" name="service_"> <property name="sizePolicy"> @@ -34,26 +27,14 @@ </property> </widget> </item> - <item row="0" column="3"> - <widget class="QLineEdit" name="filter_"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <item row="0" column="0"> + <widget class="QLabel" name="serviceLabel_"> <property name="text"> - <string/> - </property> - <property name="frame"> - <bool>true</bool> + <string>Service:</string> </property> </widget> </item> - <item row="1" column="0" colspan="4"> - <widget class="QTreeView" name="results_"/> - </item> - <item row="2" column="0" colspan="4"> + <item row="2" column="0" colspan="5"> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <spacer name="horizontalSpacer"> @@ -90,13 +71,42 @@ </item> </layout> </item> + <item row="0" column="4"> + <widget class="QLineEdit" name="filter_"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + <property name="frame"> + <bool>true</bool> + </property> + <property name="placeholderText"> + <string/> + </property> + </widget> + </item> <item row="0" column="2"> - <widget class="QToolButton" name="searchButton"> + <widget class="QToolButton" name="searchButton_"> <property name="text"> <string>List rooms</string> </property> </widget> </item> + <item row="1" column="0" colspan="5"> + <widget class="QTreeView" name="results_"/> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="filterLabel_"> + <property name="text"> + <string>Search for</string> + </property> + </widget> + </item> </layout> </widget> <resources/> |