File indexing completed on 2024-04-28 15:39:47

0001 // SPDX-FileCopyrightText: 2003-2020 Jesper K. Pedersen <blackie@kde.org>
0002 // SPDX-FileCopyrightText: 2022 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0003 //
0004 // SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006 // Qt includes
0007 #include <QTreeWidget>
0008 #include <QTreeWidgetItem>
0009 #include <QTreeWidgetItemIterator>
0010 
0011 // Local includes
0012 #include "ListSelect.h"
0013 #include "ListViewItemHider.h"
0014 
0015 #include <DB/ImageDB.h>
0016 
0017 using namespace Utilities;
0018 
0019 /**
0020  * \class AnnotationDialog::ListViewItemHider
0021  * \brief Helper class, used to hide/show listview items
0022  *
0023  * This is a helper class that is used to hide items in a listview. A leaf
0024  * will be hidden if then subclass implemented method \ref
0025  * shouldItemBeShown returns true for the given item. A parent node is
0026  * hidden if none of the children are shown, and \ref shouldItemBeShown
0027  * also returns false for the parent itself.
0028  */
0029 
0030 /**
0031  * \class AnnotationDialog::ListViewTextMatchHider
0032  * \brief Helper class for showing items matching a given text string.
0033  */
0034 
0035 /**
0036  * \class AnnotationDialog::ListViewCheckedHider
0037  * \brief Helper class for only showing items that are selected.
0038  */
0039 
0040 bool AnnotationDialog::ListViewItemHider::setItemsVisible(QTreeWidgetItem *parentItem)
0041 {
0042     bool anyChildrenVisible = false;
0043     for (int i = 0; i < parentItem->childCount(); ++i) {
0044         QTreeWidgetItem *item = parentItem->child(i);
0045         bool anySubChildrenVisible = setItemsVisible(item);
0046         bool itemVisible = anySubChildrenVisible || shouldItemBeShown(item);
0047         item->setHidden(!itemVisible);
0048         anyChildrenVisible |= itemVisible;
0049     }
0050     return anyChildrenVisible;
0051 }
0052 
0053 AnnotationDialog::ListViewTextMatchHider::ListViewTextMatchHider(const QString &text, const AnnotationDialog::MatchType mt, QTreeWidget *listView)
0054     : m_text(text)
0055     , m_matchType(mt)
0056 {
0057     setItemsVisible(listView->invisibleRootItem());
0058 }
0059 
0060 bool AnnotationDialog::ListViewTextMatchHider::shouldItemBeShown(QTreeWidgetItem *item)
0061 {
0062     // Be sure not to display the "untagged image" tag if configured
0063     if (DB::ImageDB::instance()->untaggedCategoryFeatureConfigured()
0064         && !Settings::SettingsData::instance()->untaggedImagesTagVisible()) {
0065         const auto listSelect = dynamic_cast<ListSelect *>(item->treeWidget()->parent());
0066         Q_ASSERT(listSelect);
0067         if (Settings::SettingsData::instance()->untaggedCategory() == listSelect->category()) {
0068             if (item->text(0) == Settings::SettingsData::instance()->untaggedTag()) {
0069                 return false;
0070             }
0071         }
0072     }
0073 
0074     switch (m_matchType) {
0075     case AnnotationDialog::MatchFromBeginning:
0076         return item->text(0).toLower().startsWith(m_text.toLower());
0077     case AnnotationDialog::MatchFromWordStart: {
0078         const QStringList itemWords = item->text(0).toLower().split(QRegExp(QString::fromUtf8("\\W+")),
0079                                                                     Qt::SkipEmptyParts);
0080         const QStringList searchWords = m_text.toLower().split(QRegExp(QString::fromUtf8("\\W+")),
0081                                                                Qt::SkipEmptyParts);
0082 
0083         // all search words ...
0084         for (const auto &searchWord : searchWords) {
0085             bool found = false;
0086             // ... must match at least one word of the item
0087             for (const auto &itemWord : itemWords) {
0088                 if (itemWord.startsWith(searchWord)) {
0089                     found = true;
0090                     break;
0091                 }
0092             }
0093             if (!found) {
0094                 return false;
0095             }
0096         }
0097         return true;
0098     }
0099     case AnnotationDialog::MatchAnywhere:
0100         return item->text(0).toLower().contains(m_text.toLower());
0101     }
0102     // gcc believes this could be reached
0103     Q_ASSERT(false);
0104     return false;
0105 }
0106 
0107 bool AnnotationDialog::ListViewCheckedHider::shouldItemBeShown(QTreeWidgetItem *item)
0108 {
0109     return item->checkState(0) != Qt::Unchecked;
0110 }
0111 
0112 AnnotationDialog::ListViewCheckedHider::ListViewCheckedHider(QTreeWidget *listView)
0113 {
0114     setItemsVisible(listView->invisibleRootItem());
0115 }
0116 
0117 // vi:expandtab:tabstop=4 shiftwidth=4: