diff --git a/libs/resources/KisResourceSearchBoxFilter.cpp b/libs/resources/KisResourceSearchBoxFilter.cpp index 9a733c5138..4a46a9782f 100644 --- a/libs/resources/KisResourceSearchBoxFilter.cpp +++ b/libs/resources/KisResourceSearchBoxFilter.cpp @@ -1,153 +1,158 @@ /* * Copyright (c) 2019 Agata Cacko * * 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. */ #include "KisResourceSearchBoxFilter.h" #include #include #include #include class Q_DECL_HIDDEN KisResourceSearchBoxFilter::Private { public: Private() : searchTokenizer("\\s*,+\\s*") {} QRegularExpression searchTokenizer; QChar tagBegin {'['}; QChar tagEnd {']'}; QChar exactMatchBeginEnd {'"'}; QSet tagNamesIncluded; QSet tagNamesExcluded; QList resourceNamesPartsIncluded; QList resourceNamesPartsExcluded; QSet resourceExactMatchesIncluded; QSet resourceExactMatchesExcluded; QString filter; }; KisResourceSearchBoxFilter::KisResourceSearchBoxFilter() : d(new Private()) { } QString cutOutDelimeters(QString text) { QString response(text); response = response.remove(0, 1); response = response.left(response.length() - 1); return response; } void KisResourceSearchBoxFilter::setFilter(const QString& filter) { d->filter = QString(filter); initializeFilterData(); } bool KisResourceSearchBoxFilter::matchesResource(const QString &resourceName) { // exact matches if (d->resourceExactMatchesIncluded.count() > 0 && !d->resourceExactMatchesIncluded.contains(resourceName)) { return false; } if (d->resourceExactMatchesExcluded.contains(resourceName)) { return false; } // partial name matches if (d->resourceNamesPartsIncluded.count() > 0) { Q_FOREACH(const QString& partialName, d->resourceNamesPartsIncluded) { if (!resourceName.contains(partialName)) { return false; } } } Q_FOREACH(const QString& partialName, d->resourceNamesPartsExcluded) { if (resourceName.contains(partialName)) { return false; } } // tags matches return true; } +bool KisResourceSearchBoxFilter::isEmpty() +{ + return d->filter.isEmpty(); +} + void KisResourceSearchBoxFilter::clearFilterData() { d->tagNamesIncluded.clear(); d->tagNamesExcluded.clear(); d->resourceNamesPartsIncluded.clear(); d->resourceNamesPartsExcluded.clear(); d->resourceExactMatchesIncluded.clear(); d->resourceExactMatchesExcluded.clear(); } void KisResourceSearchBoxFilter::initializeFilterData() { clearFilterData(); QString tempFilter(d->filter); QStringList parts = tempFilter.split(d->searchTokenizer, QString::SkipEmptyParts); Q_FOREACH(const QString& partFor, parts) { QString part(partFor); bool included = true; if (part.startsWith('!')) { part.remove(0, 1); included = false; } if (part.startsWith(d->tagBegin) && part.endsWith(d->tagEnd)) { QString tagMatchCaptured = cutOutDelimeters(part); if (included) { d->tagNamesIncluded.insert(tagMatchCaptured); } else { d->tagNamesExcluded.insert(tagMatchCaptured); } } else if (part.startsWith(d->exactMatchBeginEnd) && part.endsWith(d->exactMatchBeginEnd)) { QString exactMatchCaptured = cutOutDelimeters(part); if (included) { d->resourceExactMatchesIncluded.insert(exactMatchCaptured); } else { d->resourceExactMatchesExcluded.insert(exactMatchCaptured); } } else { if (included) { d->resourceNamesPartsIncluded.append(part); } else { d->resourceNamesPartsExcluded.append(part); } } } } diff --git a/libs/resources/KisResourceSearchBoxFilter.h b/libs/resources/KisResourceSearchBoxFilter.h index d91f7e265d..6dc8f19f14 100644 --- a/libs/resources/KisResourceSearchBoxFilter.h +++ b/libs/resources/KisResourceSearchBoxFilter.h @@ -1,46 +1,47 @@ /* * Copyright (c) 2019 Agata Cacko * * 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. */ #ifndef KIS_RESOURCE_SEARCH_BOX_FILTER_H #define KIS_RESOURCE_SEARCH_BOX_FILTER_H #include "kritaresources_export.h" #include class KRITARESOURCES_EXPORT KisResourceSearchBoxFilter { public: KisResourceSearchBoxFilter(); void setFilter(const QString& filter); bool matchesResource(const QString& resourceName); + bool isEmpty(); private: void initializeFilterData(); void clearFilterData(); class Private; Private * d; }; #endif diff --git a/libs/resources/KisTagFilterResourceProxyModel.cpp b/libs/resources/KisTagFilterResourceProxyModel.cpp index 513f145a98..1be4fe2731 100644 --- a/libs/resources/KisTagFilterResourceProxyModel.cpp +++ b/libs/resources/KisTagFilterResourceProxyModel.cpp @@ -1,214 +1,224 @@ /* * Copyright (C) 2018 Boudewijn Rempt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KisTagFilterResourceProxyModel.h" #include #include #include #include struct KisTagFilterResourceProxyModel::Private { Private() : filter(new KisResourceSearchBoxFilter()) { } QList tags; KisTagModel* tagModel; QScopedPointer filter; + bool filterInCurrentTag; }; KisTagFilterResourceProxyModel::KisTagFilterResourceProxyModel(KisTagModel* model, QObject *parent) : QSortFilterProxyModel(parent) , d(new Private) { d->tagModel = model; //connect(model, SIGNAL(modelReset()), this, SLOT(slotModelReset())); } KisTagFilterResourceProxyModel::~KisTagFilterResourceProxyModel() { delete d; } KoResourceSP KisTagFilterResourceProxyModel::resourceForIndex(QModelIndex index) const { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->resourceForIndex(mapToSource(index)); } return 0; } QModelIndex KisTagFilterResourceProxyModel::indexFromResource(KoResourceSP resource) const { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return mapFromSource(source->indexFromResource(resource)); } return QModelIndex(); } bool KisTagFilterResourceProxyModel::removeResource(const QModelIndex &index) { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->removeResource(mapToSource(index)); } return false; } bool KisTagFilterResourceProxyModel::importResourceFile(const QString &filename) { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->importResourceFile(filename); } return false; } bool KisTagFilterResourceProxyModel::addResource(KoResourceSP resource, const QString &storageId) { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->addResource(resource, storageId); } return false; } bool KisTagFilterResourceProxyModel::updateResource(KoResourceSP resource) { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->updateResource(resource); } return false; } bool KisTagFilterResourceProxyModel::renameResource(KoResourceSP resource, const QString &name) { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->renameResource(resource, name); } return false; } bool KisTagFilterResourceProxyModel::removeResource(KoResourceSP resource) { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->removeResource(resource); } return false; } bool KisTagFilterResourceProxyModel::setResourceMetaData(KoResourceSP resource, QMap metadata) { KisAbstractResourceModel *source = dynamic_cast(sourceModel()); if (source) { return source->setResourceMetaData(resource, metadata); } return false; } void KisTagFilterResourceProxyModel::setTag(const KisTagSP tag) { d->tags.clear(); if (!tag.isNull()) { d->tags << tag; } invalidateFilter(); } void KisTagFilterResourceProxyModel::setSearchBoxText(const QString& seatchBoxText) { d->filter->setFilter(seatchBoxText); invalidateFilter(); } +void KisTagFilterResourceProxyModel::setFilterByCurrentTag(const bool filterInCurrentTag) +{ + d->filterInCurrentTag = filterInCurrentTag; + invalidateFilter(); +} + bool KisTagFilterResourceProxyModel::filterAcceptsColumn(int /*source_column*/, const QModelIndex &/*source_parent*/) const { return true; } -bool resourceHasCurrentTag(KisTagSP currentTag, QVector tagsForResource) +bool KisTagFilterResourceProxyModel::resourceHasCurrentTag(KisTagSP currentTag, QVector tagsForResource) const { - bool hasCurrentTag = false; - // no tag set; all resources are allowed + + if (!d->filterInCurrentTag && !d->filter->isEmpty()) { + // we don't need to check anything else because the user wants to search in all resources + // but if the filter text is empty, we do need to filter by the current tag + return true; + } + if (currentTag.isNull()) { - hasCurrentTag = true; + // no tag set; all resources are allowed + return true; } else { if (currentTag->id() == KisTagModel::All) { // current tag is "All", all resources are allowed - hasCurrentTag = true; + return true; } else if (currentTag->id() == KisTagModel::AllUntagged) { // current tag is "All untagged", all resources without any tags are allowed - if (tagsForResource.size() == 0) { - hasCurrentTag = true; - } + return tagsForResource.size() == 0; } else { // checking whether the current tag is on the list of tags assigned to the resource Q_FOREACH(KisTagSP temp, tagsForResource) { if (temp->id() == currentTag->id()) { - hasCurrentTag = true; - break; + return true; } } } } - return hasCurrentTag; + return false; } bool KisTagFilterResourceProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { if (d->tagModel == 0) { return true; } QModelIndex idx = sourceModel()->index(source_row, KisResourceModel::Name, source_parent); int resourceId = sourceModel()->data(idx, Qt::UserRole + KisResourceModel::Id).toInt(); QString resourceName = sourceModel()->data(idx, Qt::UserRole + KisResourceModel::Name).toString(); QVector tagsForResource = d->tagModel->tagsForResource(resourceId); KisTagSP tag = d->tags.isEmpty() ? KisTagSP() : d->tags.first(); bool hasCurrentTag = resourceHasCurrentTag(tag, tagsForResource); if (!hasCurrentTag) { return false; } bool currentFilterMatches = d->filter->matchesResource(resourceName); return currentFilterMatches; } bool KisTagFilterResourceProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { QString nameLeft = sourceModel()->data(source_left, Qt::UserRole + KisResourceModel::Name).toString(); QString nameRight = sourceModel()->data(source_right, Qt::UserRole + KisResourceModel::Name).toString(); return nameLeft < nameRight; } void KisTagFilterResourceProxyModel::slotModelReset() { invalidateFilter(); } diff --git a/libs/resources/KisTagFilterResourceProxyModel.h b/libs/resources/KisTagFilterResourceProxyModel.h index 383e73ebf1..7585c7e608 100644 --- a/libs/resources/KisTagFilterResourceProxyModel.h +++ b/libs/resources/KisTagFilterResourceProxyModel.h @@ -1,77 +1,78 @@ /* * Copyright (C) 2018 Boudewijn Rempt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KISTAGFILTERRESOURCEPROXYMODEL_H #define KISTAGFILTERRESOURCEPROXYMODEL_H #include #include #include #include #include #include #include "kritaresources_export.h" class KRITARESOURCES_EXPORT KisTagFilterResourceProxyModel : public QSortFilterProxyModel, public KisAbstractResourceModel { Q_OBJECT public: KisTagFilterResourceProxyModel(KisTagModel* model = 0, QObject *parent = 0); ~KisTagFilterResourceProxyModel() override; // KisAbstractResourceModel interface public: KoResourceSP resourceForIndex(QModelIndex index = QModelIndex()) const override; QModelIndex indexFromResource(KoResourceSP resource) const override; bool removeResource(const QModelIndex &index) override; bool importResourceFile(const QString &filename) override; bool addResource(KoResourceSP resource, const QString &storageId = QString()) override; bool updateResource(KoResourceSP resource) override; bool renameResource(KoResourceSP resource, const QString &name) override; bool removeResource(KoResourceSP resource) override; bool setResourceMetaData(KoResourceSP resource, QMap metadata) override; /** * @brief setTag * @param tag */ void setTag(const KisTagSP tag); void setSearchBoxText(const QString& seatchBoxText); + void setFilterByCurrentTag(bool filterInCurrentTag); protected: - - bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override; bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; + bool resourceHasCurrentTag(KisTagSP currentTag, QVector tagsForResource) const; + private Q_SLOTS: void slotModelReset(); private: struct Private; Private *const d; Q_DISABLE_COPY(KisTagFilterResourceProxyModel) }; #endif // KISTAGFILTERRESOURCEPROXYMODEL_H diff --git a/libs/resourcewidgets/KisResourceTaggingManager.cpp b/libs/resourcewidgets/KisResourceTaggingManager.cpp index dd5d31e659..d5bf75fa3a 100644 --- a/libs/resourcewidgets/KisResourceTaggingManager.cpp +++ b/libs/resourcewidgets/KisResourceTaggingManager.cpp @@ -1,185 +1,190 @@ /* * This file is part of the KDE project * Copyright (c) 2002 Patrick Julien * Copyright (c) 2007 Jan Hambrecht * Copyright (c) 2007 Sven Langkamp * Copyright (C) 2011 Srikanth Tiyyagura * Copyright (c) 2011 José Luis Vergara * Copyright (c) 2013 Sascha Suelzer * Copyright (c) 2020 Agata Cacko * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KisResourceTaggingManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KisTagFilterWidget.h" #include "KisTagChooserWidget.h" #include "KisResourceItemChooserContextMenu.h" #include "kis_debug.h" #include "KisTag.h" class TaggedResourceSet { public: TaggedResourceSet() {} TaggedResourceSet(const QString& tagName, const QList& resources) : tagName(tagName) , resources(resources) {} QString tagName; QList resources; }; class KisResourceTaggingManager::Private { public: KisTagSP currentTag; KisTagChooserWidget *tagChooser; KisTagFilterWidget *tagFilter; QCompleter *tagCompleter; QPointer model; KisTagModel* tagModel; KisResourceModel* resourceSourceModel; }; KisResourceTaggingManager::KisResourceTaggingManager(QString resourceType, KisTagFilterResourceProxyModel *model, QWidget *parent) : QObject(parent) , d(new Private()) { d->model = model; d->tagModel = KisTagModelProvider::tagModel(resourceType); d->resourceSourceModel = KisResourceModelProvider::resourceModel(resourceType); d->tagChooser = new KisTagChooserWidget(d->tagModel, parent); d->tagFilter = new KisTagFilterWidget(d->tagModel, parent); connect(d->tagChooser, SIGNAL(sigTagChosen(KisTagSP)), this, SLOT(tagChooserIndexChanged(KisTagSP))); - connect(d->tagFilter, SIGNAL(saveButtonClicked()), this, SLOT(tagSaveButtonPressed())); + connect(d->tagFilter, SIGNAL(filterByTagChanged(bool)), this, SLOT(slotFilterByTagChanged(bool))); connect(d->tagFilter, SIGNAL(filterTextChanged(QString)), this, SLOT(tagSearchLineEditTextChanged(QString))); + } KisResourceTaggingManager::~KisResourceTaggingManager() { delete d; } void KisResourceTaggingManager::showTaggingBar(bool show) { show ? d->tagFilter->show() : d->tagFilter->hide(); show ? d->tagChooser->show() : d->tagChooser->hide(); } void KisResourceTaggingManager::tagChooserIndexChanged(const KisTagSP tag) { ENTER_FUNCTION(); d->model->setTag(tag); d->currentTag = tag; d->tagFilter->clear(); - d->tagFilter->allowSave(tag->id() >= 0); // disallow save if the chosen tag has negative id (i.e. 'All' tag) } void KisResourceTaggingManager::tagSearchLineEditTextChanged(const QString& lineEditText) { fprintf(stderr, "void KisResourceTaggingManager::tagSearchLineEditTextChanged(const QString& lineEditText): %s \n", lineEditText.toStdString().c_str()); d->model->setSearchBoxText(lineEditText); ENTER_FUNCTION() << ppVar(lineEditText); } +void KisResourceTaggingManager::slotFilterByTagChanged(const bool filterByTag) +{ + d->model->setFilterByCurrentTag(filterByTag); +} + void KisResourceTaggingManager::tagSaveButtonPressed() { fprintf(stderr, "void KisResourceTaggingManager::tagSaveButtonPressed()\n"); KisTagSP tag = d->tagChooser->currentlySelectedTag(); // untag all previous resources int allResources = d->resourceSourceModel->rowCount(); for (int i = 0; i < allResources; i++) { QModelIndex index = d->resourceSourceModel->index(i, 0); KoResourceSP resource = d->resourceSourceModel->resourceForIndex(index); QVector tags = d->resourceSourceModel->tagsForResource(resource->resourceId()); QVector::iterator iter = std::find_if(tags.begin(), tags.end(), [tag](KisTagSP tagFromResource) { return tagFromResource->url() == tag->url(); }); if (iter != tags.end()) { d->tagModel->untagResource(tag, resource); } } // tag all resources that are here now int rows = d->model->rowCount(); for (int i = 0; i < rows; i++) { QModelIndex index = d->model->index(i, 0); KoResourceSP resource = d->model->resourceForIndex(index); if (!tag.isNull() && !resource.isNull()) { d->tagModel->tagResource(tag, resource); } } ENTER_FUNCTION(); } void KisResourceTaggingManager::contextMenuRequested(KoResourceSP resource, QPoint pos) { ENTER_FUNCTION(); // No visible tag chooser usually means no intended tag interaction, // context menu makes no sense then either fprintf(stderr, "context menu requested!"); if (!resource || !d->tagChooser->isVisible()) return; KisResourceItemChooserContextMenu menu(resource, d->tagChooser->currentlySelectedTag()); menu.exec(pos); } KisTagChooserWidget *KisResourceTaggingManager::tagChooserWidget() { return d->tagChooser; } KisTagFilterWidget *KisResourceTaggingManager::tagFilterWidget() { return d->tagFilter; } diff --git a/libs/resourcewidgets/KisResourceTaggingManager.h b/libs/resourcewidgets/KisResourceTaggingManager.h index 35ce012312..3fda86e4c7 100644 --- a/libs/resourcewidgets/KisResourceTaggingManager.h +++ b/libs/resourcewidgets/KisResourceTaggingManager.h @@ -1,83 +1,84 @@ /* * This file is part of the KDE project * Copyright (c) 2002 Patrick Julien * Copyright (c) 2007 Jan Hambrecht * Copyright (c) 2007 Sven Langkamp * Copyright (C) 2011 Srikanth Tiyyagura * Copyright (c) 2011 José Luis Vergara * Copyright (c) 2013 Sascha Suelzer * Copyright (c) 2019 Boudewijn Rempt * Copyright (c) 2020 Agata Cacko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KISRESOURCETAGGINGMANAGER_H #define KISRESOURCETAGGINGMANAGER_H #include #include #include #include #include #include class QWidget; class QStringList; class QString; class QPoint; class KisTagFilterWidget; class KisTagChooserWidget; class KisTagFilterResourceProxyModel; /** * @brief The KisResourceTaggingManager class is ... * * XXX: this needs to be documented! */ class KisResourceTaggingManager : public QObject { Q_OBJECT public: explicit KisResourceTaggingManager(QString resourceType, KisTagFilterResourceProxyModel *model, QWidget *parent); ~KisResourceTaggingManager() override; void showTaggingBar(bool show); void contextMenuRequested(KoResourceSP currentResource, QPoint pos); KisTagFilterWidget *tagFilterWidget(); KisTagChooserWidget *tagChooserWidget(); private Q_SLOTS: void tagSaveButtonPressed(); void tagChooserIndexChanged(const KisTagSP lineEditText); void tagSearchLineEditTextChanged(const QString &lineEditText); + void slotFilterByTagChanged(const bool filterByTag); private: void enableContextMenu(bool enable); class Private; Private* const d; }; #endif // KORESOURCETAGGINGINTERFACE_H diff --git a/libs/resourcewidgets/KisTagFilterWidget.cpp b/libs/resourcewidgets/KisTagFilterWidget.cpp index 2ed858ab27..e9fd84da71 100644 --- a/libs/resourcewidgets/KisTagFilterWidget.cpp +++ b/libs/resourcewidgets/KisTagFilterWidget.cpp @@ -1,147 +1,126 @@ /* * This file is part of the KDE project * Copyright (c) 2002 Patrick Julien * Copyright (c) 2007 Jan Hambrecht * Copyright (c) 2007 Sven Langkamp * Copyright (C) 2011 Srikanth Tiyyagura * Copyright (c) 2011 José Luis Vergara * Copyright (c) 2013 Sascha Suelzer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KisTagFilterWidget.h" #include #include #include #include #include +#include #include #include #include class KisTagFilterWidget::Private { public: QString tagSearchBarTooltip_saving_disabled; QString tagSearchBarTooltip_saving_enabled; QLineEdit* tagSearchLineEdit; - QPushButton* tagSearchSaveButton; QGridLayout* filterBarLayout; QCompleter* completer; + QCheckBox* filterByTagCheckbox; + }; KisTagFilterWidget::KisTagFilterWidget(KisTagModel* model, QWidget* parent) : QWidget(parent) , d(new Private()) { QString searchTooltipMaintext = i18nc( "@info:tooltip", "

Enter search terms here to add resources to, or remove them from, the current tag view.

" "

To filter based on the partial, case insensitive name of a resource:
" "partialname or !partialname

" "

To include or exclude other tag sets:
" "[Tagname] or ![Tagname]

" "

For case sensitive and full name matching in-/exclusion:
" "\"ExactMatch\" or !\"ExactMatch\"

"); d->tagSearchBarTooltip_saving_disabled = searchTooltipMaintext + i18nc( "@info:tooltip", "

Filter results cannot be saved for the All Presets view. " "In this view, pressing Enter or clearing the filter box will restore all items. " "Create and/or switch to a different tag if you want to save filtered resources into named sets.

"); d->tagSearchBarTooltip_saving_enabled = searchTooltipMaintext + i18nc( "@info:tooltip", "

Pressing Enter or clicking the Save button will save the changes.

"); QGridLayout* filterBarLayout = new QGridLayout; d->tagSearchLineEdit = new QLineEdit(this); d->tagSearchLineEdit->setClearButtonEnabled(true); d->tagSearchLineEdit->setPlaceholderText(i18n("Search")); d->tagSearchLineEdit->setToolTip(d->tagSearchBarTooltip_saving_disabled); d->tagSearchLineEdit->setEnabled(true); d->completer = new QCompleter(model, this); d->completer->setCompletionRole(Qt::DisplayRole); d->completer->setCaseSensitivity(Qt::CaseInsensitive); d->tagSearchLineEdit->setCompleter(d->completer); - filterBarLayout->setSpacing(0); filterBarLayout->setMargin(0); filterBarLayout->setColumnStretch(0, 1); filterBarLayout->addWidget(d->tagSearchLineEdit, 0, 0); - d->tagSearchSaveButton = new QPushButton(this); - d->tagSearchSaveButton->setIcon(koIcon("media-floppy")); - d->tagSearchSaveButton->setToolTip(i18nc("@info:tooltip", "Save the currently filtered set as the new members of the current tag.")); - d->tagSearchSaveButton->setEnabled(false); - - filterBarLayout->addWidget(d->tagSearchSaveButton, 0, 1); + d->filterByTagCheckbox = new QCheckBox(this); + d->filterByTagCheckbox->setText(i18nc("It appears in the checkbox next to the filter box " + "in resources dockers; must be short.", "filter by tag")); - connect(d->tagSearchSaveButton, SIGNAL(pressed()), - this, SLOT(onSaveButtonClicked())); - connect(d->tagSearchLineEdit, SIGNAL(returnPressed()), - this, SLOT(onSaveButtonClicked())); + filterBarLayout->addWidget(d->filterByTagCheckbox, 0, 1); connect(d->tagSearchLineEdit, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString))); - allowSave(false); + connect(d->filterByTagCheckbox, SIGNAL(stateChanged(int)), this, SLOT(slotFilterByTagChanged(int))); this->setLayout(filterBarLayout); } KisTagFilterWidget::~KisTagFilterWidget() { delete d; } -void KisTagFilterWidget::allowSave(bool allow) -{ - if (allow) { - d->tagSearchSaveButton->show(); - d->tagSearchLineEdit->setToolTip(d->tagSearchBarTooltip_saving_enabled); - } - else { - d->tagSearchSaveButton->hide(); - d->tagSearchLineEdit->setToolTip(d->tagSearchBarTooltip_saving_disabled); - } -} void KisTagFilterWidget::clear() { d->tagSearchLineEdit->clear(); - d->tagSearchSaveButton->setEnabled(false); } void KisTagFilterWidget::onTextChanged(const QString& lineEditText) { - ENTER_FUNCTION() << ppVar(lineEditText); - d->tagSearchSaveButton->setEnabled(!lineEditText.isEmpty()); emit filterTextChanged(lineEditText); } -void KisTagFilterWidget::onSaveButtonClicked() +void KisTagFilterWidget::slotFilterByTagChanged(int filterByTag) { - ENTER_FUNCTION() << ppVar(d->tagSearchLineEdit->text()); - emit saveButtonClicked(); - clear(); + emit filterByTagChanged(filterByTag == Qt::Checked); } diff --git a/libs/resourcewidgets/KisTagFilterWidget.h b/libs/resourcewidgets/KisTagFilterWidget.h index 5daec84f72..f3e000a219 100644 --- a/libs/resourcewidgets/KisTagFilterWidget.h +++ b/libs/resourcewidgets/KisTagFilterWidget.h @@ -1,54 +1,53 @@ /* * This file is part of the KDE project * Copyright (c) 2002 Patrick Julien * Copyright (c) 2007 Jan Hambrecht * Copyright (c) 2007 Sven Langkamp * Copyright (C) 2011 Srikanth Tiyyagura * Copyright (c) 2011 José Luis Vergara * Copyright (c) 2013 Sascha Suelzer * Copyright (c) 2019 Boudewijn Rempt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KISTAGFILTERWIDGET_H #define KISTAGFILTERWIDGET_H #include #include class KisTagFilterWidget : public QWidget { Q_OBJECT public: explicit KisTagFilterWidget(KisTagModel* model, QWidget* parent); ~KisTagFilterWidget() override; - void allowSave(bool allow); void clear(); Q_SIGNALS: void filterTextChanged(const QString &filterText); - void saveButtonClicked(); + void filterByTagChanged(const bool filterByTag); private Q_SLOTS: void onTextChanged(const QString &lineEditText); - void onSaveButtonClicked(); + void slotFilterByTagChanged(int filterByTag); private: class Private; Private* const d; }; #endif // KOTAGFILTERWIDGET_H