diff options
Diffstat (limited to 'src/filterbar')
| -rw-r--r-- | src/filterbar/filterbar.cpp | 100 | ||||
| -rw-r--r-- | src/filterbar/filterbar.h | 22 |
2 files changed, 118 insertions, 4 deletions
diff --git a/src/filterbar/filterbar.cpp b/src/filterbar/filterbar.cpp index 6cb8d5e2a..08bff24fc 100644 --- a/src/filterbar/filterbar.cpp +++ b/src/filterbar/filterbar.cpp @@ -2,18 +2,25 @@ * SPDX-FileCopyrightText: 2006-2010 Peter Penz <[email protected]> * SPDX-FileCopyrightText: 2006 Gregor Kališnik <[email protected]> * SPDX-FileCopyrightText: 2012 Stuart Citrin <[email protected]> + * SPDX-FileCopyrightText: 2026 Alessio Bonfiglio <[email protected]> * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "filterbar.h" +#include <KConfigGroup> #include <KLocalizedString> +#include <KSharedConfig> +#include <KColorScheme> +#include <QAction> #include <QApplication> +#include <QComboBox> #include <QHBoxLayout> #include <QKeyEvent> #include <QLineEdit> +#include <QPalette> #include <QToolButton> FilterBar::FilterBar(QWidget *parent) @@ -35,8 +42,35 @@ FilterBar::FilterBar(QWidget *parent) m_filterInput->setClearButtonEnabled(true); m_filterInput->setPlaceholderText(i18n("Filter…")); connect(m_filterInput, &QLineEdit::textChanged, this, &FilterBar::filterChanged); + connect(m_filterInput, &QLineEdit::textChanged, this, &FilterBar::updateInvalidPatternView); setFocusProxy(m_filterInput); + m_invalidPatternAction = new QAction(m_filterInput); + m_invalidPatternAction->setCheckable(false); + m_invalidPatternAction->setIcon(QIcon::fromTheme(QStringLiteral("error-symbolic"))); + m_invalidPatternAction->setToolTip(i18n("Invalid expression")); + m_filterInput->addAction(m_invalidPatternAction, QLineEdit::TrailingPosition); + m_invalidPatternAction->setVisible(false); + + // Create case sensitive button + m_caseSensitiveButton = new QToolButton(contentsContainer); + m_caseSensitiveButton->setAutoRaise(true); + m_caseSensitiveButton->setCheckable(true); + m_caseSensitiveButton->setIcon(QIcon::fromTheme(QStringLiteral("format-text-superscript"), QIcon::fromTheme(QStringLiteral("format-text-bold")))); + m_caseSensitiveButton->setToolTip(i18nc("@info:tooltip", "Match case")); + connect(m_caseSensitiveButton, &QToolButton::toggled, this, &FilterBar::caseSensitiveChanged); + connect(m_caseSensitiveButton, &QToolButton::toggled, this, &FilterBar::updateInvalidPatternView); + + // Create filter mode combobox + m_filterModeComboBox = new QComboBox(contentsContainer); + m_filterModeComboBox->addItem(i18nc("@item:inlistbox", "Plain Text"), KFileItemModelFilter::FilterMode::PlainText); + m_filterModeComboBox->addItem(i18nc("@item:inlistbox", "Glob Pattern"), KFileItemModelFilter::FilterMode::Glob); + m_filterModeComboBox->addItem(i18nc("@item:inlistbox", "Regular Expression"), KFileItemModelFilter::FilterMode::Regex); + connect(m_filterModeComboBox, &QComboBox::currentIndexChanged, this, [this](int index) { + Q_EMIT filterModeChanged(m_filterModeComboBox->itemData(index).value<KFileItemModelFilter::FilterMode>()); + }); + connect(m_filterModeComboBox, &QComboBox::currentIndexChanged, this, &FilterBar::updateInvalidPatternView); + // Create close button QToolButton *closeButton = new QToolButton(contentsContainer); closeButton->setAutoRaise(true); @@ -49,13 +83,25 @@ FilterBar::FilterBar(QWidget *parent) hLayout->setContentsMargins(0, 0, 0, 0); hLayout->addWidget(m_lockButton); hLayout->addWidget(m_filterInput); + hLayout->addWidget(m_caseSensitiveButton); + hLayout->addWidget(m_filterModeComboBox); hLayout->addWidget(closeButton); - setTabOrder(m_lockButton, closeButton); - setTabOrder(closeButton, m_filterInput); + setTabOrder({m_lockButton, m_caseSensitiveButton, m_filterModeComboBox, closeButton, m_filterInput}); + + KConfigGroup filterBarConfig(KSharedConfig::openStateConfig(), QStringLiteral("FilterBar")); + bool caseSensitiveEnabled = filterBarConfig.readEntry("caseSensitive", false); + int filterModeComboBoxIndex = filterBarConfig.readEntry("filterMode", m_filterModeComboBox->findData(KFileItemModelFilter::FilterMode::Glob)); + m_caseSensitiveButton->setChecked(caseSensitiveEnabled); + m_filterModeComboBox->setCurrentIndex(filterModeComboBoxIndex); } -FilterBar::~FilterBar() = default; +FilterBar::~FilterBar() +{ + KConfigGroup filterBarConfig(KSharedConfig::openStateConfig(), QStringLiteral("FilterBar")); + filterBarConfig.writeEntry("caseSensitive", this->m_caseSensitiveButton->isChecked()); + filterBarConfig.writeEntry("filterMode", this->m_filterModeComboBox->currentIndex()); +} void FilterBar::closeFilterBar() { @@ -71,6 +117,16 @@ void FilterBar::selectAll() m_filterInput->selectAll(); } +KFileItemModelFilter::FilterMode FilterBar::filterMode() const +{ + return m_filterModeComboBox->itemData(m_filterModeComboBox->currentIndex()).value<KFileItemModelFilter::FilterMode>(); +} + +bool FilterBar::isCaseSensitive() const +{ + return m_caseSensitiveButton->isChecked(); +} + void FilterBar::clear() { m_filterInput->clear(); @@ -93,6 +149,39 @@ void FilterBar::slotToggleLockButton(bool checked) } } +void FilterBar::updateInvalidPatternView() +{ + bool valid = true; + + KFileItemModelFilter::FilterMode current_filter_mode = filterMode(); + if (current_filter_mode != KFileItemModelFilter::FilterMode::PlainText) { + QRegularExpression regExp = QRegularExpression(); + QString pattern = m_filterInput->text(); + + QRegularExpression::PatternOptions options = + m_caseSensitiveButton->isChecked() ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption; + if (current_filter_mode == KFileItemModelFilter::FilterMode::Regex) { + regExp.setPattern(pattern); + regExp.setPatternOptions(options); + } else if (current_filter_mode == KFileItemModelFilter::FilterMode::Glob) { + regExp.setPattern(QRegularExpression::wildcardToRegularExpression(pattern, QRegularExpression::UnanchoredWildcardConversion)); + regExp.setPatternOptions(options); + } + + valid = regExp.isValid(); + } + + if (valid) { + m_filterInput->setPalette(QPalette()); + m_invalidPatternAction->setVisible(false); + } else { + auto pal = m_filterInput->palette(); + KColorScheme::adjustBackground(pal, KColorScheme::NegativeBackground); + m_filterInput->setPalette(pal); + m_invalidPatternAction->setVisible(true); + } +} + void FilterBar::showEvent(QShowEvent *event) { if (!event->spontaneous()) { @@ -137,7 +226,10 @@ void FilterBar::keyPressEvent(QKeyEvent *event) int FilterBar::preferredHeight() const { - return std::max(m_filterInput->sizeHint().height(), m_lockButton->sizeHint().height()); + return std::max({m_filterInput->sizeHint().height(), + m_lockButton->sizeHint().height(), + m_caseSensitiveButton->sizeHint().height(), + m_filterModeComboBox->sizeHint().height()}); } #include "moc_filterbar.cpp" diff --git a/src/filterbar/filterbar.h b/src/filterbar/filterbar.h index 1424f4cb8..924c6dba3 100644 --- a/src/filterbar/filterbar.h +++ b/src/filterbar/filterbar.h @@ -10,9 +10,12 @@ #define FILTERBAR_H #include "animatedheightwidget.h" +#include "kitemviews/private/kfileitemmodelfilter.h" class QLineEdit; class QToolButton; +class QComboBox; +class QAction; /** * @brief Provides an input field for filtering the currently shown items. @@ -35,6 +38,9 @@ public: */ void selectAll(); + KFileItemModelFilter::FilterMode filterMode() const; + bool isCaseSensitive() const; + public Q_SLOTS: /** Clears the input field. */ void clear(); @@ -51,6 +57,16 @@ Q_SIGNALS: void filterChanged(const QString &nameFilter); /** + * Emitted when the case sensitive mode has been changed + */ + void caseSensitiveChanged(bool caseSensitive); + + /** + * Emitted when the filter mode has been changed + */ + void filterModeChanged(KFileItemModelFilter::FilterMode mode); + + /** * Emitted as soon as the filterbar should get closed. */ void closeRequest(); @@ -70,6 +86,12 @@ protected: private: QLineEdit *m_filterInput; QToolButton *m_lockButton; + QToolButton *m_caseSensitiveButton; + QComboBox *m_filterModeComboBox; + QAction *m_invalidPatternAction; + + /** Enable or disable the alterative view for when a pattern is invalid */ + void updateInvalidPatternView(); }; #endif |
