File indexing completed on 2024-06-02 05:33:04

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org>
0003    SPDX-FileCopyrightText: 2015 Franck Arrecot <franck.arrecot@gmail.com>
0004    * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005    */
0006 
0007 
0008 #include "quickselectdialog.h"
0009 
0010 #include <QDialogButtonBox>
0011 #include <QEvent>
0012 #include <QHeaderView>
0013 #include <QKeyEvent>
0014 #include <QLabel>
0015 #include <QSortFilterProxyModel>
0016 #include <QTreeView>
0017 #include <QVBoxLayout>
0018 
0019 #include <KLocalizedString>
0020 
0021 using namespace Widgets;
0022 
0023 QuickSelectDialog::QuickSelectDialog(QWidget *parent)
0024     : QDialog(parent),
0025       m_model(nullptr),
0026       m_filterProxyModel(new QSortFilterProxyModel(this)),
0027       m_label(new QLabel(this)),
0028       m_tree(new QTreeView(this))
0029 {
0030     setWindowTitle(i18nc("@title:window", "Quick Select Dialog"));
0031 
0032     m_label->setText(i18n("You can start typing to filter the list of available pages"));
0033     m_filterProxyModel->setRecursiveFilteringEnabled(true);
0034 
0035     m_tree->setModel(m_filterProxyModel);
0036     m_tree->setObjectName(QLatin1StringView("pagesView"));
0037     m_tree->header()->hide();
0038     m_tree->expandAll();
0039     m_tree->setFocus();
0040     m_tree->setSelectionMode(QAbstractItemView::SingleSelection);
0041     m_tree->setSortingEnabled(false);
0042     m_tree->installEventFilter(this);
0043 
0044     auto buttonBox = new QDialogButtonBox(this);
0045     buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0046 
0047     auto mainLayout = new QVBoxLayout(this);
0048     mainLayout->addWidget(m_label);
0049     mainLayout->addWidget(m_tree);
0050     mainLayout->addWidget(buttonBox);
0051 
0052     connect(buttonBox, &QDialogButtonBox::accepted, this, &QuickSelectDialog::accept);
0053     connect(buttonBox, &QDialogButtonBox::rejected, this, &QuickSelectDialog::reject);
0054 }
0055 
0056 int QuickSelectDialog::exec()
0057 {
0058     return QDialog::exec();
0059 }
0060 
0061 QPersistentModelIndex QuickSelectDialog::selectedIndex() const
0062 {
0063     QModelIndex selected = m_tree->currentIndex();
0064     return m_filterProxyModel->mapToSource(selected);
0065 }
0066 
0067 void QuickSelectDialog::applyFilterChanged(const QString &textFilter)
0068 {
0069     if (textFilter.isEmpty())
0070         m_label->setText(i18n("You can start typing to filter the list of available pages"));
0071     else
0072         m_label->setText(i18n("Path: %1", textFilter));
0073 
0074     m_filterProxyModel->setFilterRegularExpression(QRegularExpression(textFilter, QRegularExpression::CaseInsensitiveOption));
0075     m_tree->expandAll();
0076 }
0077 
0078 bool QuickSelectDialog::eventFilter(QObject *, QEvent *ev)
0079 {
0080     if (ev->type() == QEvent::KeyPress) {
0081         auto event = static_cast<QKeyEvent*>(ev);
0082         auto filter = m_filterProxyModel->filterRegularExpression().pattern();
0083 
0084         switch (event->key()) {
0085         case Qt::Key_Backspace:
0086             filter.chop(1);
0087             break;
0088         case Qt::Key_Delete:
0089             filter = QString();
0090             break;
0091         default:
0092             if (event->text().contains(QRegularExpression(QStringLiteral("^(\\w| )+$")))) {
0093                 filter += event->text();
0094             }
0095             break;
0096         }
0097 
0098         applyFilterChanged(filter);
0099     }
0100     return false;
0101 }
0102 
0103 void QuickSelectDialog::setModel(QAbstractItemModel *model)
0104 {
0105     if (model == m_model)
0106         return;
0107 
0108     m_model = model;
0109     m_filterProxyModel->setSourceModel(m_model);
0110     m_tree->expandAll();
0111 }
0112 
0113 #include "moc_quickselectdialog.cpp"