File indexing completed on 2024-05-12 16:01:33

0001 /*
0002  *  SPDX-FileCopyrightText: 2011 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_model_index_converter.h"
0008 
0009 #include "kis_selection_mask.h"
0010 #include "kis_node_dummies_graph.h"
0011 #include "kis_dummies_facade_base.h"
0012 #include "kis_node_model.h"
0013 #include "kis_node_manager.h"
0014 #include "KisReferenceImagesLayer.h"
0015 #include "KisDecorationsWrapperLayer.h"
0016 
0017 
0018 KisModelIndexConverter::KisModelIndexConverter(KisDummiesFacadeBase *dummiesFacade,
0019                                                KisNodeModel *model,
0020                                                bool showGlobalSelection)
0021     : m_dummiesFacade(dummiesFacade),
0022       m_model(model),
0023       m_showGlobalSelection(showGlobalSelection)
0024 {
0025 }
0026 
0027 inline bool KisModelIndexConverter::checkDummyType(KisNodeDummy *dummy)
0028 {
0029     return dummy->isGUIVisible(m_showGlobalSelection);
0030 }
0031 
0032 inline bool KisModelIndexConverter::checkDummyMetaObjectType(const QString &type)
0033 {
0034     const QString selectionMaskType = KisSelectionMask::staticMetaObject.className();
0035     const QString referencesLayerType = KisReferenceImagesLayer::staticMetaObject.className();
0036     const QString decorationsLayerType = KisDecorationsWrapperLayer::staticMetaObject.className();
0037 
0038     return (type != selectionMaskType || m_showGlobalSelection) &&
0039             type != referencesLayerType &&
0040             type != decorationsLayerType;
0041 }
0042 
0043 KisNodeDummy* KisModelIndexConverter::dummyFromRow(int row, QModelIndex parent)
0044 {
0045 
0046     KisNodeDummy *parentDummy = parent.isValid() ?
0047         dummyFromIndex(parent) : m_dummiesFacade->rootDummy();
0048 
0049     if(!parentDummy) return 0;
0050 
0051     KisNodeDummy *resultDummy = 0;
0052 
0053     // a child of the root node
0054     if(!parentDummy->parent()) {
0055         KisNodeDummy *currentDummy = parentDummy->lastChild();
0056         while(currentDummy) {
0057             if(checkDummyType(currentDummy)) {
0058                 if(!row) {
0059                     resultDummy = currentDummy;
0060                     break;
0061                 }
0062                 row--;
0063             }
0064             currentDummy = currentDummy->prevSibling();
0065         }
0066     }
0067     // a child of other layer
0068     else {
0069         int rowCount = parentDummy->childCount();
0070         int index = rowCount - row - 1;
0071         resultDummy = parentDummy->at(index);
0072     }
0073 
0074 
0075     return resultDummy;
0076 }
0077 
0078 KisNodeDummy* KisModelIndexConverter::dummyFromIndex(QModelIndex index)
0079 {
0080     Q_ASSERT(index.isValid());
0081     Q_ASSERT(index.internalPointer());
0082     return static_cast<KisNodeDummy*>(index.internalPointer());
0083 }
0084 
0085 QModelIndex KisModelIndexConverter::indexFromDummy(KisNodeDummy *dummy)
0086 {
0087     Q_ASSERT(dummy);
0088     KisNodeDummy *parentDummy = dummy->parent();
0089 
0090     // a root node
0091     if(!parentDummy) return QModelIndex();
0092 
0093     int row = 0;
0094 
0095     // a child of the root node
0096     if(!parentDummy->parent()) {
0097         if(!checkDummyType(dummy)) return QModelIndex();
0098 
0099         KisNodeDummy *currentDummy = parentDummy->lastChild();
0100         while(currentDummy && currentDummy != dummy) {
0101             if(checkDummyType(currentDummy)) {
0102                 row++;
0103             }
0104             currentDummy = currentDummy->prevSibling();
0105         }
0106     }
0107     // a child of other layer
0108     else {
0109         int rowCount = parentDummy->childCount();
0110         int index = parentDummy->indexOf(dummy);
0111         row = rowCount - index - 1;
0112     }
0113 
0114     return m_model->createIndex(row, 0, (void*)dummy);
0115 }
0116 
0117 bool KisModelIndexConverter::indexFromAddedDummy(KisNodeDummy *parentDummy,
0118                                                  int index,
0119                                                  const QString &newNodeMetaObjectType,
0120                                                  QModelIndex &parentIndex,
0121                                                  int &row)
0122 {
0123     // adding a root node
0124     if(!parentDummy) {
0125         Q_ASSERT(!index);
0126         return false;
0127     }
0128 
0129     // adding a child of the root node
0130     if(!parentDummy->parent()) {
0131         if(!checkDummyMetaObjectType(newNodeMetaObjectType)) {
0132             return false;
0133         }
0134 
0135         row = 0;
0136 
0137         parentIndex = QModelIndex();
0138         KisNodeDummy *dummy = parentDummy->lastChild();
0139         int toScan = parentDummy->childCount() - index;
0140         while(dummy && toScan > 0) {
0141             if(checkDummyType(dummy)) {
0142                 row++;
0143             }
0144             dummy = dummy->prevSibling();
0145             toScan--;
0146         }
0147     }
0148     // everything else
0149     else {
0150         parentIndex = indexFromDummy(parentDummy);
0151         int rowCount = parentDummy->childCount();
0152         row = rowCount - index;
0153     }
0154 
0155     return true;
0156 }
0157 
0158 int KisModelIndexConverter::rowCount(QModelIndex parent)
0159 {
0160     KisNodeDummy *dummy = parent.isValid() ?
0161         dummyFromIndex(parent) : m_dummiesFacade->rootDummy();
0162 
0163     // a root node (hidden)
0164     if(!dummy) return 0;
0165 
0166     int numChildren = 0;
0167 
0168     // children of the root node
0169     if(!dummy->parent()) {
0170         KisNodeDummy *currentDummy = dummy->lastChild();
0171         while(currentDummy) {
0172             if(checkDummyType(currentDummy)) {
0173                 numChildren++;
0174             }
0175 
0176             currentDummy = currentDummy->prevSibling();
0177         }
0178     }
0179     // children of other nodes
0180     else {
0181         numChildren = dummy->childCount();
0182     }
0183 
0184     return numChildren;
0185 }