Warning, file /multimedia/kdenlive/src/assets/assetlist/model/assetfilter.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2017 Nicolas Carion
0003     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 
0006 #include "assetfilter.hpp"
0007 
0008 #include "abstractmodel/abstracttreemodel.hpp"
0009 #include "abstractmodel/treeitem.hpp"
0010 #include "assettreemodel.hpp"
0011 #include <KLocalizedString>
0012 #include <utility>
0013 
0014 AssetFilter::AssetFilter(QObject *parent)
0015     : QSortFilterProxyModel(parent)
0016 
0017 {
0018     setFilterRole(Qt::DisplayRole);
0019     setSortRole(Qt::DisplayRole);
0020     setDynamicSortFilter(false);
0021 }
0022 
0023 void AssetFilter::setFilterName(bool enabled, const QString &pattern)
0024 {
0025     m_name_enabled = enabled;
0026     m_name_value = pattern;
0027     invalidateFilter();
0028     if (rowCount() > 1) {
0029         sort(0);
0030     }
0031 }
0032 
0033 bool AssetFilter::lessThan(const QModelIndex &left, const QModelIndex &right) const
0034 {
0035     QString leftData = sourceModel()->data(left).toString();
0036     QString rightData = sourceModel()->data(right).toString();
0037     return QString::localeAwareCompare(leftData, rightData) < 0;
0038 }
0039 
0040 bool AssetFilter::filterName(const std::shared_ptr<TreeItem> &item) const
0041 {
0042     if (!m_name_enabled) {
0043         return true;
0044     }
0045     const QString itemId = normalizeText(item->dataColumn(AssetTreeModel::IdCol).toString());
0046     QString itemText = i18n(item->dataColumn(AssetTreeModel::NameCol).toString().toUtf8().constData());
0047     itemText = normalizeText(itemText);
0048     QString patt = normalizeText(m_name_value);
0049 
0050     return itemText.contains(patt, Qt::CaseInsensitive) || itemId.contains(patt, Qt::CaseInsensitive);
0051 }
0052 
0053 QString AssetFilter::normalizeText(const QString &text)
0054 {
0055     // NormalizationForm_D decomposes letters with diacritics, and then the
0056     // diacritics are removed by checking isLetterOrNumber().
0057     const QString normalized = text.normalized(QString::NormalizationForm_D);
0058     QString newString;
0059     std::copy_if(normalized.begin(), normalized.end(), std::back_inserter(newString),
0060         [](QChar c){
0061             return c.isLetterOrNumber() || c.isSpace();
0062         });
0063     return newString;
0064 }
0065 
0066 bool AssetFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
0067 {
0068     QModelIndex row = sourceModel()->index(sourceRow, 0, sourceParent);
0069     auto *model = static_cast<AbstractTreeModel *>(sourceModel());
0070     std::shared_ptr<TreeItem> item = model->getItemById(int(row.internalId()));
0071 
0072     if (item->dataColumn(AssetTreeModel::IdCol) == QStringLiteral("root")) {
0073         // In that case, we have a category. We hide it if it does not have children.
0074         QModelIndex category = sourceModel()->index(sourceRow, 0, sourceParent);
0075         if (!category.isValid()) {
0076             return false;
0077         }
0078         bool accepted = false;
0079         for (int i = 0; i < sourceModel()->rowCount(category) && !accepted; ++i) {
0080             accepted = filterAcceptsRow(i, category);
0081         }
0082         return accepted;
0083     }
0084     return applyAll(item);
0085 }
0086 
0087 bool AssetFilter::isVisible(const QModelIndex &sourceIndex)
0088 {
0089     auto parent = sourceModel()->parent(sourceIndex);
0090     if (sourceIndex.row() < 0) {
0091         return false;
0092     }
0093     return filterAcceptsRow(sourceIndex.row(), parent);
0094 }
0095 
0096 bool AssetFilter::applyAll(std::shared_ptr<TreeItem> item) const
0097 {
0098     return filterName(item);
0099 }
0100 
0101 QModelIndex AssetFilter::getNextChild(const QModelIndex &current)
0102 {
0103     QModelIndex nextItem = current.sibling(current.row() + 1, current.column());
0104     if (!nextItem.isValid()) {
0105         QModelIndex folder = index(current.parent().row() + 1, 0, QModelIndex());
0106         if (!folder.isValid()) {
0107             return current;
0108         }
0109         while (folder.isValid() && rowCount(folder) == 0) {
0110             folder = folder.sibling(folder.row() + 1, folder.column());
0111         }
0112         if (folder.isValid() && rowCount(folder) > 0) {
0113             return index(0, current.column(), folder);
0114         }
0115         nextItem = current;
0116     }
0117     return nextItem;
0118 }
0119 
0120 QModelIndex AssetFilter::getPreviousChild(const QModelIndex &current)
0121 {
0122     QModelIndex nextItem = current.sibling(current.row() - 1, current.column());
0123     if (!nextItem.isValid()) {
0124         QModelIndex folder = index(current.parent().row() - 1, 0, QModelIndex());
0125         if (!folder.isValid()) {
0126             return current;
0127         }
0128         while (folder.isValid() && rowCount(folder) == 0) {
0129             folder = folder.sibling(folder.row() - 1, folder.column());
0130         }
0131         if (folder.isValid() && rowCount(folder) > 0) {
0132             return index(rowCount(folder) - 1, current.column(), folder);
0133         }
0134         nextItem = current;
0135     }
0136     return nextItem;
0137 }
0138 
0139 QModelIndex AssetFilter::firstVisibleItem(const QModelIndex &current)
0140 {
0141     if (current.isValid() && isVisible(mapToSource(current))) {
0142         return current;
0143     }
0144     QModelIndex folder = index(0, 0, QModelIndex());
0145     if (!folder.isValid()) {
0146         return current;
0147     }
0148     while (folder.isValid() && rowCount(folder) == 0) {
0149         folder = index(folder.row() + 1, 0, QModelIndex());
0150     }
0151     if (rowCount(folder) > 0) {
0152         return index(0, 0, folder);
0153     }
0154     return current;
0155 }
0156 
0157 QModelIndex AssetFilter::getCategory(int catRow)
0158 {
0159     QModelIndex cat = index(catRow, 0, QModelIndex());
0160     return cat;
0161 }
0162 
0163 QVariantList AssetFilter::getCategories()
0164 {
0165     QVariantList list;
0166     for (int i = 0; i < sourceModel()->rowCount(); i++) {
0167         QModelIndex cat = getCategory(i);
0168         if (cat.isValid()) {
0169             list << cat;
0170         }
0171     }
0172     return list;
0173 }
0174 
0175 QModelIndex AssetFilter::getModelIndex(const QModelIndex &current)
0176 {
0177     QModelIndex sourceIndex = mapToSource(current);
0178     return sourceIndex; // this returns an integer
0179 }
0180 
0181 QModelIndex AssetFilter::getProxyIndex(const QModelIndex &current)
0182 {
0183     QModelIndex sourceIndex = mapFromSource(current);
0184     return sourceIndex; // this returns an integer
0185 }