File indexing completed on 2024-05-12 16:01:31
0001 /* 0002 * This file is part of Krita 0003 * 0004 * SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "kis_filters_model.h" 0010 0011 #include <QPixmap> 0012 0013 #include <filter/kis_filter.h> 0014 #include <filter/kis_filter_registry.h> 0015 #include <kis_paint_device.h> 0016 #include <kis_processing_information.h> 0017 #include <kis_selection.h> 0018 0019 struct KisFiltersModel::Private { 0020 struct Node { 0021 0022 virtual ~Node() {} 0023 0024 QString name; 0025 QString displayRole() { 0026 return name; 0027 } 0028 virtual int childrenCount() = 0; 0029 0030 }; 0031 struct Filter : public Node { 0032 0033 ~Filter() override {} 0034 0035 QString id; 0036 QPixmap icon; 0037 KisFilterSP filter; 0038 int childrenCount() override { 0039 return 0; 0040 } 0041 }; 0042 struct Category : public Node { 0043 0044 ~Category() override {} 0045 0046 QString id; 0047 QList<Filter> filters; 0048 int childrenCount() override { 0049 return filters.count(); 0050 } 0051 }; 0052 0053 QHash<QString, Category> categories; 0054 QList<QString> categoriesKeys; 0055 KisPaintDeviceSP thumb; 0056 }; 0057 0058 KisFiltersModel::KisFiltersModel(bool showAll, KisPaintDeviceSP thumb) 0059 : d(new Private) 0060 { 0061 d->thumb = thumb; 0062 QStringList keys = KisFilterRegistry::instance()->keys(); 0063 keys.sort(); 0064 0065 Q_FOREACH (const QString &filterName, keys) { 0066 KisFilterSP filter = KisFilterRegistry::instance()->get(filterName); 0067 if (!showAll && !filter->supportsAdjustmentLayers()) { 0068 continue; 0069 } 0070 Q_ASSERT(filter); 0071 if (!d->categories.contains(filter->menuCategory().id())) { 0072 Private::Category cat; 0073 cat.id = filter->menuCategory().id(); 0074 cat.name = filter->menuCategory().name(); 0075 d->categories[ cat.id ] = cat; 0076 d->categoriesKeys.append(cat.id); 0077 } 0078 Private::Filter filt; 0079 filt.id = filter->id(); 0080 filt.name = filter->name(); 0081 filt.filter = filter; 0082 d->categories[filter->menuCategory().id()].filters.append(filt); 0083 } 0084 std::sort(d->categoriesKeys.begin(), d->categoriesKeys.end()); 0085 0086 } 0087 0088 KisFiltersModel::~KisFiltersModel() 0089 { 0090 delete d; 0091 } 0092 0093 int KisFiltersModel::rowCount(const QModelIndex &parent) const 0094 { 0095 if (parent.isValid()) { 0096 Private::Node* node = static_cast<Private::Node*>(parent.internalPointer()); 0097 return node->childrenCount(); 0098 } else { 0099 return d->categoriesKeys.count(); 0100 } 0101 } 0102 0103 int KisFiltersModel::columnCount(const QModelIndex &parent) const 0104 { 0105 Q_UNUSED(parent); 0106 return 1; 0107 } 0108 0109 QModelIndex KisFiltersModel::indexForFilter(const QString& id) 0110 { 0111 for (int i = 0; i < d->categoriesKeys.size(); i++) { 0112 KisFiltersModel::Private::Category& category = d->categories[ d->categoriesKeys[ i ] ]; 0113 for (int j = 0; j < category.filters.size(); j++) { 0114 KisFiltersModel::Private::Filter& filter = category.filters[j]; 0115 if (filter.id == id) { 0116 return index(j, i, index(i , 0, QModelIndex())); 0117 } 0118 } 0119 } 0120 return QModelIndex(); 0121 } 0122 0123 const KisFilter* KisFiltersModel::indexToFilter(const QModelIndex& idx) 0124 { 0125 Private::Node* node = static_cast<Private::Node*>(idx.internalPointer()); 0126 Private::Filter* filter = dynamic_cast<Private::Filter*>(node); 0127 if (filter) { 0128 return filter->filter; 0129 } 0130 return 0; 0131 } 0132 0133 QModelIndex KisFiltersModel::index(int row, int column, const QModelIndex &parent) const 0134 { 0135 // dbgKrita << parent.isValid() << row << endl; 0136 if (parent.isValid()) { 0137 Private::Category* category = static_cast<Private::Category*>(parent.internalPointer()); 0138 return createIndex(row, column, &category->filters[row]); 0139 } else { 0140 return createIndex(row, column, &d->categories[ d->categoriesKeys[row] ]); 0141 } 0142 } 0143 0144 QModelIndex KisFiltersModel::parent(const QModelIndex &child) const 0145 { 0146 if (!child.isValid()) 0147 return QModelIndex(); 0148 Private::Node* node = static_cast<Private::Node*>(child.internalPointer()); 0149 Private::Filter* filter = dynamic_cast<Private::Filter*>(node); 0150 if (filter) { 0151 QString catId = filter->filter->menuCategory().id(); 0152 return createIndex(d->categoriesKeys.indexOf(catId) , 0, &d->categories[ catId ]); 0153 } 0154 return QModelIndex(); // categories don't have parents 0155 } 0156 0157 QVariant KisFiltersModel::data(const QModelIndex &index, int role) const 0158 { 0159 if (index.isValid()) { 0160 if (role == Qt::DisplayRole) { 0161 Private::Node* node = static_cast<Private::Node*>(index.internalPointer()); 0162 return QVariant(node->displayRole()); 0163 } 0164 } 0165 return QVariant(); 0166 } 0167 0168 Qt::ItemFlags KisFiltersModel::flags(const QModelIndex & index) const 0169 { 0170 if (!index.isValid()) return QFlags<Qt::ItemFlag>(); 0171 0172 Private::Node* node = static_cast<Private::Node*>(index.internalPointer()); 0173 Private::Filter* filter = dynamic_cast<Private::Filter*>(node); 0174 if (filter) { 0175 return Qt::ItemIsSelectable | Qt::ItemIsEnabled; 0176 } else { 0177 return Qt::ItemIsEnabled; 0178 } 0179 } 0180 0181