From 8dfa8af69bed6700f63abf1428afb3fa1ea78597 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Tue, 11 Aug 2009 14:09:32 +0200 Subject: [PATCH] Gitorious Wizard: Add a repository filter field. ... to accommodate for the setup at Nokia. --- .../gitoriousrepositorywizardpage.cpp | 69 +++++++++++++++---- .../gitorious/gitoriousrepositorywizardpage.h | 8 +++ .../gitoriousrepositorywizardpage.ui | 21 ++++++ 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/src/plugins/git/gitorious/gitoriousrepositorywizardpage.cpp b/src/plugins/git/gitorious/gitoriousrepositorywizardpage.cpp index bbe11e5b3ec..555e9707fe0 100644 --- a/src/plugins/git/gitorious/gitoriousrepositorywizardpage.cpp +++ b/src/plugins/git/gitorious/gitoriousrepositorywizardpage.cpp @@ -33,6 +33,7 @@ #include "gitorious.h" #include "ui_gitoriousrepositorywizardpage.h" +#include <coreplugin/coreconstants.h> #include <utils/qtcassert.h> #include <QtCore/QDebug> @@ -40,6 +41,7 @@ #include <QtGui/QStandardItemModel> #include <QtGui/QStandardItem> #include <QtGui/QItemSelectionModel> +#include <QtGui/QSortFilterProxyModel> enum { TypeRole = Qt::UserRole + 1}; enum { HeaderType, RepositoryType }; @@ -49,6 +51,23 @@ enum { debug = 0 }; namespace Gitorious { namespace Internal { +// A filter model that returns true for the parent (category) nodes +// (which by default do not match the search string and are thus collapsed). +class RepositoryFilterModel : public QSortFilterProxyModel { +public: + explicit RepositoryFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {} +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; +}; + +bool RepositoryFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + if (!source_parent.isValid()) + return true; // Always true for parents. + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); +} + +// ----------- GitoriousRepositoryWizardPage enum { RepositoryColumn, OwnerColumn, DescriptionColumn, ColumnCount }; GitoriousRepositoryWizardPage::GitoriousRepositoryWizardPage(const GitoriousProjectWizardPage *projectPage, @@ -57,14 +76,25 @@ GitoriousRepositoryWizardPage::GitoriousRepositoryWizardPage(const GitoriousProj ui(new Ui::GitoriousRepositoryWizardPage), m_projectPage(projectPage), m_model(new QStandardItemModel(0, ColumnCount)), + m_filterModel(new RepositoryFilterModel), m_valid(false) { QStringList headers; headers << tr("Name") << tr("Owner") << tr("Description"); - m_model->setHorizontalHeaderLabels(headers); + m_model->setHorizontalHeaderLabels(headers); + // Filter on all columns + m_filterModel->setSourceModel(m_model); + m_filterModel->setFilterKeyColumn(-1); + m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive); ui->setupUi(this); - ui->repositoryTreeView->setModel(m_model); + // Filter + connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), m_filterModel, SLOT(setFilterFixedString(QString))); + ui->filterClearButton->setIcon(QIcon(Core::Constants::ICON_RESET)); + connect(ui->filterClearButton, SIGNAL(clicked()), ui->filterLineEdit, SLOT(clear())); + // Tree view + ui->repositoryTreeView->setModel(m_filterModel); ui->repositoryTreeView->setUniformRowHeights(true); ui->repositoryTreeView->setAlternatingRowColors(true); ui->repositoryTreeView->setSelectionMode(QAbstractItemView::SingleSelection); @@ -121,6 +151,7 @@ void GitoriousRepositoryWizardPage::initializePage() ui->repositoryTreeView->selectionModel()->clearSelection(); if (const int oldRowCount = m_model->rowCount()) m_model->removeRows(0, oldRowCount); + ui->filterLineEdit->clear(); // fill model const QSharedPointer<GitoriousProject> proj = m_projectPage->project(); setSubTitle(tr("Choose a repository of the project '%1'.").arg(proj->name)); @@ -153,14 +184,32 @@ void GitoriousRepositoryWizardPage::initializePage() ui->repositoryTreeView->resizeColumnToContents(r); // Select first if (firstEntry) { - const QModelIndex idx = m_model->indexFromItem(firstEntry); - ui->repositoryTreeView->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::Select|QItemSelectionModel::Current|QItemSelectionModel::Rows); + const QModelIndex filterIndex = m_filterModel->mapFromSource(m_model->indexFromItem(firstEntry)); + ui->repositoryTreeView->selectionModel()->setCurrentIndex(filterIndex, QItemSelectionModel::Select|QItemSelectionModel::Current|QItemSelectionModel::Rows); + } + ui->repositoryTreeView->setFocus(); +} + +QStandardItem *GitoriousRepositoryWizardPage::currentItem0() const +{ + return item0FromIndex(ui->repositoryTreeView->selectionModel()->currentIndex()); +} + +QStandardItem *GitoriousRepositoryWizardPage::item0FromIndex(const QModelIndex &filterIndex) const +{ + if (filterIndex.isValid()) { + const QModelIndex sourceIndex = m_filterModel->mapToSource(filterIndex); + if (sourceIndex.column() == 0) + return m_model->itemFromIndex(sourceIndex); + const QModelIndex sibling0 = sourceIndex.sibling(sourceIndex.row(), 0); + return m_model->itemFromIndex(sibling0); } + return 0; } void GitoriousRepositoryWizardPage::slotCurrentChanged(const QModelIndex ¤t, const QModelIndex & /*previous */) { - const QStandardItem *item = current.isValid() ? m_model->itemFromIndex(current) : static_cast<const QStandardItem *>(0); + const QStandardItem *item = item0FromIndex(current); const bool isValid = item && item->data(TypeRole).toInt() == RepositoryType; if (isValid != m_valid) { m_valid = isValid; @@ -170,13 +219,9 @@ void GitoriousRepositoryWizardPage::slotCurrentChanged(const QModelIndex ¤ QString GitoriousRepositoryWizardPage::repositoryName() const { - const QModelIndex idx = ui->repositoryTreeView->selectionModel()->currentIndex(); - if (idx.isValid()) { - const QModelIndex sibling0 = idx.column() ? idx.sibling(idx.row(), 0) : idx; - if (const QStandardItem *item = m_model->itemFromIndex(sibling0)) - if (item->data(TypeRole).toInt() == RepositoryType) - return item->text(); - } + if (const QStandardItem *item = currentItem0()) + if (item->data(TypeRole).toInt() == RepositoryType) + return item->text(); return QString(); } diff --git a/src/plugins/git/gitorious/gitoriousrepositorywizardpage.h b/src/plugins/git/gitorious/gitoriousrepositorywizardpage.h index f90f415d020..708e9a7ae8c 100644 --- a/src/plugins/git/gitorious/gitoriousrepositorywizardpage.h +++ b/src/plugins/git/gitorious/gitoriousrepositorywizardpage.h @@ -33,6 +33,7 @@ #include <QtGui/QWizardPage> QT_BEGIN_NAMESPACE +class QSortFilterProxyModel; class QStandardItemModel; class QStandardItem; class QModelIndex; @@ -69,9 +70,16 @@ public slots: protected: void changeEvent(QEvent *e); +private: + // return the repository (column 0) item. + QStandardItem *currentItem0() const; + // return the repository (column 0) item of index. + QStandardItem *item0FromIndex(const QModelIndex &filterIndex) const; + Ui::GitoriousRepositoryWizardPage *ui; const GitoriousProjectWizardPage *m_projectPage; QStandardItemModel *m_model; + QSortFilterProxyModel *m_filterModel; bool m_valid; }; diff --git a/src/plugins/git/gitorious/gitoriousrepositorywizardpage.ui b/src/plugins/git/gitorious/gitoriousrepositorywizardpage.ui index e85f5903892..38f0f2d814a 100644 --- a/src/plugins/git/gitorious/gitoriousrepositorywizardpage.ui +++ b/src/plugins/git/gitorious/gitoriousrepositorywizardpage.ui @@ -14,6 +14,27 @@ <string>WizardPage</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="filterLabel"> + <property name="text"> + <string>Filter:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="filterLineEdit"/> + </item> + <item> + <widget class="QToolButton" name="filterClearButton"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </item> <item> <widget class="QTreeView" name="repositoryTreeView"/> </item> -- GitLab