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 ¤t) 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 ¤t) 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 ¤t) 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 ¤t) 0176 { 0177 QModelIndex sourceIndex = mapToSource(current); 0178 return sourceIndex; // this returns an integer 0179 } 0180 0181 QModelIndex AssetFilter::getProxyIndex(const QModelIndex ¤t) 0182 { 0183 QModelIndex sourceIndex = mapFromSource(current); 0184 return sourceIndex; // this returns an integer 0185 }