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