X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/080498368502bfbdc4e13427ba3a9a21cefcafdf..0446c768675f0a11f887378681eb1f01b3e2c575:/src/search/dolphinfacetswidget.cpp diff --git a/src/search/dolphinfacetswidget.cpp b/src/search/dolphinfacetswidget.cpp index c0b6c5243..cc125a2d9 100644 --- a/src/search/dolphinfacetswidget.cpp +++ b/src/search/dolphinfacetswidget.cpp @@ -1,26 +1,14 @@ -/*************************************************************************** -* Copyright (C) 2012 by Peter Penz * -* Copyright (C) 2019 by Ismael Asensio * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program; if not, write to the * -* Free Software Foundation, Inc., * -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * -* **************************************************************************/ +/* + * SPDX-FileCopyrightText: 2012 Peter Penz + * SPDX-FileCopyrightText: 2019 Ismael Asensio + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "dolphinfacetswidget.h" #include +#include #include #include @@ -66,6 +54,12 @@ DolphinFacetsWidget::DolphinFacetsWidget(QWidget* parent) : m_ratingSelector->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "Highest Rating"), 5); initComboBox(m_ratingSelector); + m_clearTagsAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-clear-all")), i18nc("@action:inmenu", "Clear Selection"), this); + connect(m_clearTagsAction, &QAction::triggered, this, [this]() { + resetSearchTags(); + Q_EMIT facetChanged(); + }); + m_tagsSelector = new QToolButton(this); m_tagsSelector->setIcon(QIcon::fromTheme(QStringLiteral("tag"))); m_tagsSelector->setMenu(new QMenu(this)); @@ -86,7 +80,7 @@ DolphinFacetsWidget::DolphinFacetsWidget(QWidget* parent) : topLayout->addWidget(m_ratingSelector); topLayout->addWidget(m_tagsSelector); - resetOptions(); + resetSearchTerms(); } DolphinFacetsWidget::~DolphinFacetsWidget() @@ -99,23 +93,21 @@ void DolphinFacetsWidget::changeEvent(QEvent *event) if (isEnabled()) { updateTagsSelector(); } else { - resetOptions(); + resetSearchTerms(); } } } -void DolphinFacetsWidget::resetOptions() +void DolphinFacetsWidget::resetSearchTerms() { m_typeSelector->setCurrentIndex(0); m_dateSelector->setCurrentIndex(0); m_ratingSelector->setCurrentIndex(0); - m_searchTags = QStringList(); - updateTagsSelector(); - updateTagsMenu(); + resetSearchTags(); } -QString DolphinFacetsWidget::ratingTerm() const +QStringList DolphinFacetsWidget::searchTerms() const { QStringList terms; @@ -131,11 +123,15 @@ QString DolphinFacetsWidget::ratingTerm() const if (!m_searchTags.isEmpty()) { for (auto const &tag : m_searchTags) { - terms << QStringLiteral("tag:%1").arg(tag); + if (tag.contains(QLatin1Char(' '))) { + terms << QStringLiteral("tag:\"%1\"").arg(tag); + } else { + terms << QStringLiteral("tag:%1").arg(tag); + } } } - return terms.join(QLatin1String(" AND ")); + return terms; } QString DolphinFacetsWidget::facetType() const @@ -143,50 +139,36 @@ QString DolphinFacetsWidget::facetType() const return m_typeSelector->currentData().toString(); } -bool DolphinFacetsWidget::isRatingTerm(const QString& term) const +bool DolphinFacetsWidget::isSearchTerm(const QString& term) const { - const QStringList subTerms = term.split(' ', QString::SkipEmptyParts); - - // If term has sub terms, then sone of the sub terms are always "rating" and "modified" terms. - bool containsRating = false; - bool containsModified = false; - bool containsTag = false; - - foreach (const QString& subTerm, subTerms) { - if (subTerm.startsWith(QLatin1String("rating>="))) { - containsRating = true; - } else if (subTerm.startsWith(QLatin1String("modified>="))) { - containsModified = true; - } else if (subTerm.startsWith(QLatin1String("tag:")) || - subTerm.startsWith(QLatin1String("tag="))) { - containsTag = true; + static const QLatin1String searchTokens[] { + QLatin1String("modified>="), + QLatin1String("rating>="), + QLatin1String("tag:"), QLatin1String("tag=") + }; + + for (const auto &searchToken : searchTokens) { + if (term.startsWith(searchToken)) { + return true; } } - - return containsModified || containsRating || containsTag; + return false; } -void DolphinFacetsWidget::setRatingTerm(const QString& term) +void DolphinFacetsWidget::setSearchTerm(const QString& term) { - // If term has sub terms, then the sub terms are always "rating" and "modified" terms. - // If term has no sub terms, then the term itself is either a "rating" term or a "modified" - // term. To avoid code duplication we add term to subTerms list, if the list is empty. - QStringList subTerms = term.split(' ', QString::SkipEmptyParts); - - foreach (const QString& subTerm, subTerms) { - if (subTerm.startsWith(QLatin1String("modified>="))) { - const QString value = subTerm.mid(10); - const QDate date = QDate::fromString(value, Qt::ISODate); - setTimespan(date); - } else if (subTerm.startsWith(QLatin1String("rating>="))) { - const QString value = subTerm.mid(8); - const int stars = value.toInt() / 2; - setRating(stars); - } else if (subTerm.startsWith(QLatin1String("tag:")) || - subTerm.startsWith(QLatin1String("tag="))) { - const QString value = subTerm.mid(4); - addSearchTag(value); - } + if (term.startsWith(QLatin1String("modified>="))) { + const QString value = term.mid(10); + const QDate date = QDate::fromString(value, Qt::ISODate); + setTimespan(date); + } else if (term.startsWith(QLatin1String("rating>="))) { + const QString value = term.mid(8); + const int stars = value.toInt() / 2; + setRating(stars); + } else if (term.startsWith(QLatin1String("tag:")) || + term.startsWith(QLatin1String("tag="))) { + const QString value = term.mid(4); + addSearchTag(value); } } @@ -241,12 +223,19 @@ void DolphinFacetsWidget::removeSearchTag(const QString& tag) updateTagsSelector(); } +void DolphinFacetsWidget::resetSearchTags() +{ + m_searchTags = QStringList(); + updateTagsSelector(); + updateTagsMenu(); +} + void DolphinFacetsWidget::initComboBox(QComboBox* combo) { combo->setFrame(false); combo->setMinimumHeight(parentWidget()->height()); combo->setCurrentIndex(0); - connect(combo, QOverload::of(&QComboBox::activated), this, &DolphinFacetsWidget::facetChanged); + connect(combo, &QComboBox::activated, this, &DolphinFacetsWidget::facetChanged); } void DolphinFacetsWidget::updateTagsSelector() @@ -263,17 +252,21 @@ void DolphinFacetsWidget::updateTagsSelector() } m_tagsSelector->setEnabled(isEnabled() && (hasListedTags || hasSelectedTags)); + m_clearTagsAction->setEnabled(hasSelectedTags); } void DolphinFacetsWidget::updateTagsMenu() { updateTagsMenuItems({}, {}); - m_tagsLister.openUrl(QUrl(QStringLiteral("tags:/")), KCoreDirLister::OpenUrlFlag::Reload); + if (KProtocolInfo::isKnownProtocol(QStringLiteral("tags"))) { + m_tagsLister.openUrl(QUrl(QStringLiteral("tags:/")), KCoreDirLister::OpenUrlFlag::Reload); + } } void DolphinFacetsWidget::updateTagsMenuItems(const QUrl&, const KFileItemList& items) { - m_tagsSelector->menu()->clear(); + QMenu *tagsMenu = m_tagsSelector->menu(); + tagsMenu->clear(); QStringList allTags = QStringList(m_searchTags); for (const KFileItem &item: items) { @@ -282,20 +275,31 @@ void DolphinFacetsWidget::updateTagsMenuItems(const QUrl&, const KFileItemList& allTags.sort(Qt::CaseInsensitive); allTags.removeDuplicates(); + const bool onlyOneTag = allTags.count() == 1; + for (const QString& tagName : qAsConst(allTags)) { - QAction* action = m_tagsSelector->menu()->addAction(QIcon::fromTheme(QStringLiteral("tag")), tagName); + QAction *action = tagsMenu->addAction(QIcon::fromTheme(QStringLiteral("tag")), tagName); action->setCheckable(true); action->setChecked(m_searchTags.contains(tagName)); - connect(action, &QAction::triggered, this, [this, tagName](bool isChecked) { + connect(action, &QAction::triggered, this, [this, tagName, onlyOneTag](bool isChecked) { if (isChecked) { addSearchTag(tagName); } else { removeSearchTag(tagName); } - emit facetChanged(); + Q_EMIT facetChanged(); + + if (!onlyOneTag) { + m_tagsSelector->menu()->show(); + } }); } + if (allTags.count() > 1) { + tagsMenu->addSeparator(); + tagsMenu->addAction(m_clearTagsAction); + } + updateTagsSelector(); }