diff --git a/core/app/filters/filtersidebarwidget.cpp b/core/app/filters/filtersidebarwidget.cpp index 27f01fbb84..adab6ebad5 100644 --- a/core/app/filters/filtersidebarwidget.cpp +++ b/core/app/filters/filtersidebarwidget.cpp @@ -1,529 +1,529 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2000-12-05 * Description : filters view for the right sidebar * * Copyright (C) 2009-2010 by Johannes Wienke * Copyright (C) 2010-2011 by Andi Clemens * Copyright (C) 2011-2020 by Gilles Caulier * Copyright (C) 2011 by Michael G. Hansen * Copyright (C) 2014 by Mohamed_Anwer * * 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, 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. * * ============================================================ */ #include "filtersidebarwidget.h" // Qt includes #include #include #include #include #include #include // KDE includes #include #include // Local includes #include "dlayoutbox.h" #include "dexpanderbox.h" #include "digikam_debug.h" #include "applicationsettings.h" #include "colorlabelfilter.h" #include "geolocationfilter.h" #include "picklabelfilter.h" #include "ratingfilter.h" #include "mimefilter.h" #include "tagfilterview.h" -#include "tagscache.h" +#include "facetags.h" namespace Digikam { class Q_DECL_HIDDEN FilterSideBarWidget::Private { public: explicit Private() : space(nullptr), expanderVlay(nullptr), tagFilterView(nullptr), tagFilterSearchBar(nullptr), tagOptionsBtn(nullptr), tagOptionsMenu(nullptr), tagFilterModel(nullptr), tagOrCondAction(nullptr), tagAndCondAction(nullptr), tagMatchCond(ItemFilterSettings::OrCondition), faceFilterView(nullptr), faceFilterSearchBar(nullptr), faceOptionsBtn(nullptr), faceOptionsMenu(nullptr), faceFilterModel(nullptr), colorLabelFilter(nullptr), geolocationFilter(nullptr), pickLabelFilter(nullptr), ratingFilter(nullptr), mimeFilter(nullptr), textFilter(nullptr), withoutTagCheckBox(nullptr), withoutFaceCheckBox(nullptr), expbox(nullptr) { } static const QString configSearchTextFilterFieldsEntry; static const QString configLastShowUntaggedEntry; static const QString configLastShowWithoutFaceEntry; static const QString configMatchingConditionEntry; QWidget* space; QVBoxLayout* expanderVlay; TagFilterView* tagFilterView; SearchTextBar* tagFilterSearchBar; QToolButton* tagOptionsBtn; QMenu* tagOptionsMenu; TagModel* tagFilterModel; QAction* tagOrCondAction; QAction* tagAndCondAction; ItemFilterSettings::MatchingCondition tagMatchCond; TagFilterView* faceFilterView; SearchTextBar* faceFilterSearchBar; QToolButton* faceOptionsBtn; QMenu* faceOptionsMenu; TagModel* faceFilterModel; ColorLabelFilter* colorLabelFilter; GeolocationFilter* geolocationFilter; PickLabelFilter* pickLabelFilter; RatingFilter* ratingFilter; MimeFilter* mimeFilter; TextFilter* textFilter; QCheckBox* withoutTagCheckBox; QCheckBox* withoutFaceCheckBox; DExpanderBox* expbox; }; const QString FilterSideBarWidget::Private::configSearchTextFilterFieldsEntry(QLatin1String("Search Text Filter Fields")); const QString FilterSideBarWidget::Private::configLastShowUntaggedEntry(QLatin1String("Show Untagged")); const QString FilterSideBarWidget::Private::configLastShowWithoutFaceEntry(QLatin1String("Show Without Face")); const QString FilterSideBarWidget::Private::configMatchingConditionEntry(QLatin1String("Matching Condition")); // --------------------------------------------------------------------------------------------------- FilterSideBarWidget::FilterSideBarWidget(QWidget* const parent, TagModel* const tagFilterModel) : DVBox(parent), StateSavingObject(this), d(new Private) { setObjectName(QLatin1String("TagFilter Sidebar")); d->expbox = new DExpanderBox(this); d->expbox->setObjectName(QLatin1String("FilterSideBarWidget Expander")); // -------------------------------------------------------------------------------------------------------- d->textFilter = new TextFilter(d->expbox); d->expbox->addItem(d->textFilter, QIcon::fromTheme(QLatin1String("text-field")), i18n("Text Filter"), QLatin1String("TextFilter"), true); // -------------------------------------------------------------------------------------------------------- d->mimeFilter = new MimeFilter(d->expbox); d->expbox->addItem(d->mimeFilter, QIcon::fromTheme(QLatin1String("folder-open")), i18n("MIME Type Filter"), QLatin1String("TypeMimeFilter"), true); // -------------------------------------------------------------------------------------------------------- d->geolocationFilter = new GeolocationFilter(d->expbox); d->expbox->addItem(d->geolocationFilter, QIcon::fromTheme(QLatin1String("globe")), i18n("Geolocation Filter"), QLatin1String("TypeGeolocationFilter"), true); // -------------------------------------------------------------------------------------------------------- QWidget* const box3 = new QWidget(d->expbox); d->tagFilterModel = tagFilterModel; d->tagFilterView = new TagFilterView(box3, tagFilterModel); d->tagFilterView->setObjectName(QLatin1String("ItemIconViewTagFilterView")); //d->tagFilterView->filteredModel()->doNotListTagsWithProperty(TagPropertyName::person()); //d->tagFilterView->filteredModel()->setFilterBehavior(AlbumFilterModel::StrictFiltering); d->tagFilterSearchBar = new SearchTextBar(box3, QLatin1String("ItemIconViewTagFilterSearchBar")); d->tagFilterSearchBar->setModel(d->tagFilterView->filteredModel(), AbstractAlbumModel::AlbumIdRole, AbstractAlbumModel::AlbumTitleRole); d->tagFilterSearchBar->setFilterModel(d->tagFilterView->albumFilterModel()); const QString notTaggedTitle = i18n("Images Without Tags"); d->withoutTagCheckBox = new QCheckBox(notTaggedTitle, box3); d->withoutTagCheckBox->setWhatsThis(i18n("Show images without a tag.")); d->tagOptionsBtn = new QToolButton(box3); d->tagOptionsBtn->setToolTip( i18n("Tags Matching Condition")); d->tagOptionsBtn->setIcon(QIcon::fromTheme(QLatin1String("configure"))); d->tagOptionsBtn->setPopupMode(QToolButton::InstantPopup); d->tagOptionsBtn->setWhatsThis(i18n("Defines in which way the selected tags are combined " "to filter the images. This also includes the '%1' check box.", notTaggedTitle)); d->tagOptionsMenu = new QMenu(d->tagOptionsBtn); d->tagOrCondAction = d->tagOptionsMenu->addAction(i18n("OR")); d->tagOrCondAction->setCheckable(true); d->tagAndCondAction = d->tagOptionsMenu->addAction(i18n("AND")); d->tagAndCondAction->setCheckable(true); d->tagOptionsBtn->setMenu(d->tagOptionsMenu); QGridLayout* const lay3 = new QGridLayout(box3); lay3->addWidget(d->tagFilterView, 0, 0, 1, 3); lay3->addWidget(d->tagFilterSearchBar, 1, 0, 1, 3); lay3->addWidget(d->withoutTagCheckBox, 2, 0, 1, 1); lay3->addWidget(d->tagOptionsBtn, 2, 2, 1, 1); lay3->setRowStretch(0, 100); lay3->setColumnStretch(1, 10); lay3->setContentsMargins(QMargins()); lay3->setSpacing(0); d->expbox->addItem(box3, QIcon::fromTheme(QLatin1String("tag-assigned")), i18n("Tags Filter"), QLatin1String("TagsFilter"), true); // -------------------------------------------------------------------------------------------------------- QWidget* const box5 = new QWidget(d->expbox); d->faceFilterModel = tagFilterModel; d->faceFilterView = new TagFilterView(box5, tagFilterModel); d->faceFilterView->setObjectName(QLatin1String("ItemIconViewFaceTagFilterView")); d->faceFilterView->filteredModel()->listOnlyTagsWithProperty(TagPropertyName::person()); d->faceFilterView->filteredModel()->setFilterBehavior(AlbumFilterModel::StrictFiltering); d->faceFilterSearchBar = new SearchTextBar(box5, QLatin1String("ItemIconViewFaceTagFilterSearchBar")); d->faceFilterSearchBar->setModel(d->faceFilterView->filteredModel(), AbstractAlbumModel::AlbumIdRole, AbstractAlbumModel::AlbumTitleRole); d->faceFilterSearchBar->setFilterModel(d->faceFilterView->albumFilterModel()); const QString notfaceTaggedTitle = i18n("Images Without Face tags"); d->withoutFaceCheckBox = new QCheckBox(notfaceTaggedTitle, box5); d->withoutFaceCheckBox->setWhatsThis(i18n("Show images without a face tag.")); d->faceOptionsBtn = new QToolButton(box5); d->faceOptionsBtn->setToolTip( i18n("Face tags Matching Condition")); d->faceOptionsBtn->setIcon(QIcon::fromTheme(QLatin1String("configure"))); d->faceOptionsBtn->setPopupMode(QToolButton::InstantPopup); d->faceOptionsBtn->setWhatsThis(i18n("Defines in which way the selected tags are combined " "to filter the images. This also includes the '%1' check box.", notfaceTaggedTitle)); d->faceOptionsMenu = new QMenu(d->faceOptionsBtn); d->tagOrCondAction = d->faceOptionsMenu->addAction(i18n("OR")); d->tagOrCondAction->setCheckable(true); d->tagAndCondAction = d->faceOptionsMenu->addAction(i18n("AND")); d->tagAndCondAction->setCheckable(true); d->faceOptionsBtn->setMenu(d->faceOptionsMenu); QGridLayout* const lay5 = new QGridLayout(box5); lay5->addWidget(d->faceFilterView, 0, 0, 1, 3); lay5->addWidget(d->faceFilterSearchBar, 1, 0, 1, 3); lay5->addWidget(d->withoutFaceCheckBox, 2, 0, 1, 1); lay5->addWidget(d->faceOptionsBtn, 2, 2, 1, 1); lay5->setRowStretch(0, 100); lay5->setColumnStretch(1, 10); lay5->setContentsMargins(QMargins()); lay5->setSpacing(0); d->expbox->addItem(box5, QIcon::fromTheme(QLatin1String("tag-assigned")), i18n("Face Tags Filter"), QLatin1String("FaceTagsFilter"), true); // -------------------------------------------------------------------------------------------------------- QWidget* const box4 = new QWidget(d->expbox); d->colorLabelFilter = new ColorLabelFilter(box4); d->pickLabelFilter = new PickLabelFilter(box4); d->ratingFilter = new RatingFilter(box4); QGridLayout* const lay4 = new QGridLayout(box4); lay4->addWidget(d->colorLabelFilter, 0, 0, 1, 3); lay4->addWidget(d->pickLabelFilter, 1, 0, 1, 1); lay4->addWidget(d->ratingFilter, 1, 2, 1, 1); lay4->setColumnStretch(2, 1); lay4->setColumnStretch(3, 10); lay4->setContentsMargins(QMargins()); lay4->setSpacing(0); d->expbox->addItem(box4, QIcon::fromTheme(QLatin1String("folder-favorites")), i18n("Labels Filter"), QLatin1String("LabelsFilter"), true); d->expanderVlay = dynamic_cast(dynamic_cast(d->expbox)->widget()->layout()); d->space = new QWidget(); d->expanderVlay->addWidget(d->space); // -------------------------------------------------------------------------------------------------------- connect(d->expbox, SIGNAL(signalItemExpanded(int,bool)), this, SLOT(slotItemExpanded(int,bool))); connect(d->mimeFilter, SIGNAL(activated(int)), this, SIGNAL(signalMimeTypeFilterChanged(int))); connect(d->geolocationFilter, SIGNAL(signalFilterChanged(ItemFilterSettings::GeolocationCondition)), this, SIGNAL(signalGeolocationFilterChanged(ItemFilterSettings::GeolocationCondition))); connect(d->textFilter, SIGNAL(signalSearchTextFilterSettings(SearchTextFilterSettings)), this, SIGNAL(signalSearchTextFilterChanged(SearchTextFilterSettings))); connect(d->tagFilterView, SIGNAL(checkedTagsChanged(QList,QList)), this, SLOT(slotCheckedTagsChanged(QList,QList))); connect(d->colorLabelFilter, SIGNAL(signalColorLabelSelectionChanged(QList)), this, SLOT(slotColorLabelFilterChanged(QList))); connect(d->pickLabelFilter, SIGNAL(signalPickLabelSelectionChanged(QList)), this, SLOT(slotPickLabelFilterChanged(QList))); connect(d->withoutTagCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotWithoutTagChanged(int))); connect(d->withoutFaceCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotWithoutTagChanged(int))); connect(d->tagOptionsMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotTagOptionsTriggered(QAction*))); connect(d->tagOptionsMenu, SIGNAL(aboutToShow()), this, SLOT(slotTagOptionsMenu())); connect(d->ratingFilter, SIGNAL(signalRatingFilterChanged(int,ItemFilterSettings::RatingCondition,bool)), this, SIGNAL(signalRatingFilterChanged(int,ItemFilterSettings::RatingCondition,bool))); } FilterSideBarWidget::~FilterSideBarWidget() { delete d; } void FilterSideBarWidget::slotTagOptionsMenu() { d->tagOrCondAction->setChecked(false); d->tagAndCondAction->setChecked(false); switch (d->tagMatchCond) { case ItemFilterSettings::OrCondition: d->tagOrCondAction->setChecked(true); break; case ItemFilterSettings::AndCondition: d->tagAndCondAction->setChecked(true); break; } } void FilterSideBarWidget::slotItemExpanded(int id, bool b) { if (id == Digikam::TAGS) { d->expanderVlay->setStretchFactor(d->space, b ? 0 : 100); } } void FilterSideBarWidget::setFocusToTextFilter() { d->textFilter->searchTextBar()->setFocus(); } void FilterSideBarWidget::slotFilterMatchesForText(bool match) { d->textFilter->searchTextBar()->slotSearchResult(match); } void FilterSideBarWidget::slotResetFilters() { d->textFilter->reset(); d->mimeFilter->setMimeFilter(MimeFilter::AllFiles); d->geolocationFilter->setGeolocationFilter(ItemFilterSettings::GeolocationNoFilter); d->tagFilterView->slotResetCheckState(); d->withoutTagCheckBox->setChecked(false); d->withoutFaceCheckBox->setChecked(false); d->colorLabelFilter->reset(); d->pickLabelFilter->reset(); d->ratingFilter->setRating(0); d->ratingFilter->setRatingFilterCondition(ItemFilterSettings::GreaterEqualCondition); d->ratingFilter->setExcludeUnratedItems(false); d->tagMatchCond = ItemFilterSettings::OrCondition; } void FilterSideBarWidget::slotTagOptionsTriggered(QAction* action) { if (action) { if (action == d->tagOrCondAction) { d->tagMatchCond = ItemFilterSettings::OrCondition; } else if (action == d->tagAndCondAction) { d->tagMatchCond = ItemFilterSettings::AndCondition; } } filterChanged(); } void FilterSideBarWidget::slotCheckedTagsChanged(const QList& includedTags, const QList& excludedTags) { Q_UNUSED(includedTags); Q_UNUSED(excludedTags); filterChanged(); } void FilterSideBarWidget::slotColorLabelFilterChanged(const QList& list) { Q_UNUSED(list); filterChanged(); } void FilterSideBarWidget::slotPickLabelFilterChanged(const QList& list) { Q_UNUSED(list); filterChanged(); } void FilterSideBarWidget::slotWithoutTagChanged(int newState) { Q_UNUSED(newState); filterChanged(); } void FilterSideBarWidget::filterChanged() { bool showUntagged = d->withoutTagCheckBox->isChecked(); QList includedTagIds; QList excludedTagIds; QList clTagIds; QList plTagIds; if (!showUntagged || (d->tagMatchCond == ItemFilterSettings::OrCondition)) { foreach (TAlbum* tag, d->tagFilterView->getCheckedTags()) { if (tag) { includedTagIds << tag->id(); } } foreach (TAlbum* tag, d->tagFilterView->getPartiallyCheckedTags()) { if (tag) { excludedTagIds << tag->id(); } } foreach (TAlbum* tag, d->colorLabelFilter->getCheckedColorLabelTags()) { if (tag) { clTagIds << tag->id(); } } foreach (TAlbum* tag, d->pickLabelFilter->getCheckedPickLabelTags()) { if (tag) { plTagIds << tag->id(); } } if (d->withoutFaceCheckBox->isChecked()) { - excludedTagIds << TagsCache::instance()->tagsWithProperty(TagPropertyName::person()); + excludedTagIds << FaceTags::allPersonTags(); } } emit signalTagFilterChanged(includedTagIds, excludedTagIds, d->tagMatchCond, showUntagged, clTagIds, plTagIds); } void FilterSideBarWidget::setConfigGroup(const KConfigGroup& group) { StateSavingObject::setConfigGroup(group); d->tagFilterView->setConfigGroup(group); } void FilterSideBarWidget::doLoadState() { /// @todo mime type and geolocation filter states are not loaded/saved KConfigGroup group = getConfigGroup(); d->expbox->readSettings(group); d->textFilter->setsearchTextFields((SearchTextFilterSettings::TextFilterFields) (group.readEntry(entryName(d->configSearchTextFilterFieldsEntry), (int)SearchTextFilterSettings::All))); d->ratingFilter->setRatingFilterCondition((ItemFilterSettings::RatingCondition) (ApplicationSettings::instance()->getRatingFilterCond())); d->tagMatchCond = (ItemFilterSettings::MatchingCondition) (group.readEntry(entryName(d->configMatchingConditionEntry), (int)ItemFilterSettings::OrCondition)); d->tagFilterView->loadState(); d->faceFilterView->loadState(); if (d->tagFilterView->isRestoreCheckState()) { d->withoutTagCheckBox->setChecked(group.readEntry(entryName(d->configLastShowUntaggedEntry), false)); } if (d->faceFilterView->isRestoreCheckState()) { d->withoutFaceCheckBox->setChecked(group.readEntry(entryName(d->configLastShowWithoutFaceEntry), false)); } filterChanged(); } void FilterSideBarWidget::doSaveState() { KConfigGroup group = getConfigGroup(); d->expbox->writeSettings(group); group.writeEntry(entryName(d->configSearchTextFilterFieldsEntry), (int)d->textFilter->searchTextFields()); ApplicationSettings::instance()->setRatingFilterCond(d->ratingFilter->ratingFilterCondition()); group.writeEntry(entryName(d->configMatchingConditionEntry), (int)d->tagMatchCond); d->tagFilterView->saveState(); d->faceFilterView->saveState(); group.writeEntry(entryName(d->configLastShowUntaggedEntry), d->withoutTagCheckBox->isChecked()); group.writeEntry(entryName(d->configLastShowWithoutFaceEntry), d->withoutFaceCheckBox->isChecked()); group.sync(); } } // namespace Digikam