diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp index 7bec48cce1b..c5437c9de32 100644 --- a/src/libs/extensionsystem/pluginview.cpp +++ b/src/libs/extensionsystem/pluginview.cpp @@ -79,6 +79,8 @@ using namespace Utils; namespace ExtensionSystem { +namespace Internal { + enum Columns { NameColumn, LoadedColumn, VersionColumn, VendorColumn, }; enum IconIndex { OkIcon, ErrorIcon, NotLoadedIcon }; @@ -275,6 +277,40 @@ public: PluginView *m_view; // Not owned. }; +class SortFilterModel : public QSortFilterProxyModel +{ +public: + SortFilterModel(QObject *parent) : QSortFilterProxyModel(parent) {} + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override + { + if (!source_parent.isValid()) { + // category items should be visible if any of its children match + const QRegExp ®exp = filterRegExp(); + const QModelIndex &categoryIndex = sourceModel()->index(source_row, 0, source_parent); + if (regexp.indexIn(sourceModel()->data(categoryIndex, filterRole()).toString()) != -1) + return true; + const int rowCount = sourceModel()->rowCount(categoryIndex); + const int columnCount = sourceModel()->columnCount(categoryIndex); + for (int row = 0; row < rowCount; ++row) { + for (int column = 0; column < columnCount; ++column) { + if (regexp.indexIn(sourceModel()->data( + sourceModel()->index(row, column, categoryIndex), + filterRole()).toString()) != -1) + return true; + } + } + return false; + } + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); + } +}; + +} // Internal + +using namespace ExtensionSystem::Internal; + /*! Constructs a PluginView that gets the list of plugins from the given plugin \a manager with a given \a parent widget. @@ -298,9 +334,11 @@ PluginView::PluginView(QWidget *parent) m_model = new TreeModel(this); m_model->setHeader(QStringList() << tr("Name") << tr("Load") << tr("Version") << tr("Vendor")); - m_sortModel = new QSortFilterProxyModel(this); + m_sortModel = new SortFilterModel(this); m_sortModel->setSourceModel(m_model); m_sortModel->setSortRole(SortRole); + m_sortModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + m_sortModel->setFilterKeyColumn(-1/*all*/); m_categoryView->setModel(m_sortModel); QGridLayout *gridLayout = new QGridLayout(this); @@ -338,6 +376,12 @@ PluginSpec *PluginView::currentPlugin() const return pluginForIndex(m_categoryView->currentIndex()); } +void PluginView::setFilter(const QString &filter) +{ + m_sortModel->setFilterFixedString(filter); + m_categoryView->expandAll(); +} + PluginSpec *PluginView::pluginForIndex(const QModelIndex &index) const { const QModelIndex &sourceIndex = m_sortModel->mapToSource(index); diff --git a/src/libs/extensionsystem/pluginview.h b/src/libs/extensionsystem/pluginview.h index 64d2c595e94..34d8db16c69 100644 --- a/src/libs/extensionsystem/pluginview.h +++ b/src/libs/extensionsystem/pluginview.h @@ -51,8 +51,11 @@ namespace ExtensionSystem { class PluginManager; class PluginSpec; + +namespace Internal { class PluginItem; class CollectionItem; +} // Internal class EXTENSIONSYSTEM_EXPORT PluginView : public QWidget { @@ -63,6 +66,7 @@ public: ~PluginView(); PluginSpec *currentPlugin() const; + void setFilter(const QString &filter); signals: void currentPluginChanged(ExtensionSystem::PluginSpec *spec); @@ -78,8 +82,8 @@ private: Utils::TreeModel *m_model; QSortFilterProxyModel *m_sortModel; - friend class CollectionItem; - friend class PluginItem; + friend class Internal::CollectionItem; + friend class Internal::PluginItem; }; } // namespae ExtensionSystem diff --git a/src/plugins/coreplugin/plugindialog.cpp b/src/plugins/coreplugin/plugindialog.cpp index ee7440db14a..59096e7d07b 100644 --- a/src/plugins/coreplugin/plugindialog.cpp +++ b/src/plugins/coreplugin/plugindialog.cpp @@ -36,6 +36,8 @@ #include #include +#include + #include #include #include @@ -54,6 +56,13 @@ PluginDialog::PluginDialog(QWidget *parent) m_view(new ExtensionSystem::PluginView(this)) { QVBoxLayout *vl = new QVBoxLayout(this); + + auto filterEdit = new Utils::FancyLineEdit(this); + filterEdit->setFiltering(true); + connect(filterEdit, &Utils::FancyLineEdit::filterChanged, + m_view, &ExtensionSystem::PluginView::setFilter); + vl->addWidget(filterEdit); + vl->addWidget(m_view); m_detailsButton = new QPushButton(tr("Details"), this);