File indexing completed on 2024-05-05 16:27:57

0001 // SPDX-FileCopyrightText: 2003 - 2010 Jesper K. Pedersen <blackie@kde.org>
0002 // SPDX-FileCopyrightText: 2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0003 //
0004 // SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006 #include "TreeFilter.h"
0007 
0008 #include <Browser/enums.h>
0009 
0010 #include <QCollator>
0011 
0012 Browser::TreeFilter::TreeFilter(QObject *parent)
0013     : QSortFilterProxyModel(parent)
0014     , m_naturalCollator(std::make_unique<QCollator>())
0015 {
0016     m_naturalCollator->setNumericMode(true);
0017     m_naturalCollator->setIgnorePunctuation(true); // only works if Qt is set up to use ICU
0018 }
0019 
0020 bool Browser::TreeFilter::filterAcceptsRow(int row, const QModelIndex &parent) const
0021 {
0022     bool match = false;
0023     bool openAllChildren = false;
0024 
0025     // If parent is open then child should be included.
0026     if (m_matchedMap[parent]) {
0027         match = true;
0028         openAllChildren = true;
0029     }
0030 
0031     // check if the item itself matches
0032     else if (QSortFilterProxyModel::filterAcceptsRow(row, parent)) {
0033         match = true;
0034         openAllChildren = true;
0035     } else {
0036         // Check if any children matches
0037         const QModelIndex myModelIndex = sourceModel()->index(row, 0, parent);
0038         const int childCount = sourceModel()->rowCount(myModelIndex);
0039         for (int i = 0; i < childCount; ++i) {
0040             if (filterAcceptsRow(i, myModelIndex)) {
0041                 match = true;
0042                 break;
0043             }
0044         }
0045     }
0046 
0047     m_matchedMap[sourceModel()->index(row, 0, parent)] = openAllChildren;
0048     return match;
0049 }
0050 
0051 void Browser::TreeFilter::resetCache()
0052 {
0053     m_matchedMap.clear();
0054 }
0055 
0056 bool Browser::TreeFilter::naturalSortOrder() const
0057 {
0058     return m_naturalSortOrder;
0059 }
0060 
0061 void Browser::TreeFilter::setNaturalSortOrder(bool naturalSortOrder)
0062 {
0063     m_naturalSortOrder = naturalSortOrder;
0064 }
0065 
0066 bool Browser::TreeFilter::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
0067 {
0068     const int sortPriority_left = source_left.data(SortPriorityRole).toInt();
0069     const int sortPriority_right = source_right.data(SortPriorityRole).toInt();
0070     // if items have different priorities, sort according to priority. Otherwise sort normally...
0071     if (sortPriority_left != sortPriority_right) {
0072         return sortPriority_left < sortPriority_right;
0073     }
0074     if (m_naturalSortOrder) {
0075         // numeric sort
0076         const QString &string_left = source_left.data(sortRole()).toString();
0077         const QString &string_right = source_right.data(sortRole()).toString();
0078         return m_naturalCollator->compare(string_left, string_right) < 0;
0079     } else {
0080         return QSortFilterProxyModel::lessThan(source_left, source_right);
0081     }
0082 }
0083 
0084 // vi:expandtab:tabstop=4 shiftwidth=4: