File indexing completed on 2024-05-12 16:01:36
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Boudewijn Rempt <boud@valdyas.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #ifndef KIS_NODE_MODEL 0007 #define KIS_NODE_MODEL 0008 0009 #include "kritaui_export.h" 0010 #include <kis_types.h> 0011 #include <QAbstractItemModel> 0012 #include <QIcon> 0013 #include <QList> 0014 #include <QString> 0015 #include <QVariant> 0016 0017 #include <KisSelectionTags.h> 0018 0019 class KisDummiesFacadeBase; 0020 class KisNodeDummy; 0021 class KisShapeController; 0022 class KisModelIndexConverterBase; 0023 class KisNodeSelectionAdapter; 0024 class KisNodeInsertionAdapter; 0025 class KisSelectionActionsAdapter; 0026 class KisNodeDisplayModeAdapter; 0027 class KisNodeManager; 0028 0029 /** 0030 * KisNodeModel offers a Qt model-view compatible view of the node 0031 * hierarchy. The KisNodeView displays a thumbnail and a row of 0032 * icon properties for every document section. 0033 * 0034 * Note that there's a discrepancy between the krita node tree model 0035 * and the model Qt wants to see: we hide the root node from Qt. 0036 * 0037 * The node model also shows an inverse view of the layer tree: we want 0038 * the first layer to show up at the bottom. 0039 * 0040 * See also the Qt documentation for QAbstractItemModel. 0041 * This class extends that interface to provide a name and set of toggle 0042 * properties (like visible, locked, selected.) 0043 * 0044 */ 0045 class KRITAUI_EXPORT KisNodeModel : public QAbstractItemModel 0046 { 0047 0048 Q_OBJECT 0049 0050 public: 0051 /// Extensions to Qt::ItemDataRole. 0052 enum ItemDataRole 0053 { 0054 /// Whether the section is the active one 0055 ActiveRole = Qt::UserRole + 1, 0056 0057 /// A list of properties the part has. 0058 PropertiesRole, 0059 0060 /// The aspect ratio of the section as a floating point value: width divided by height. 0061 AspectRatioRole, 0062 0063 /// Use to communicate a progress report to the section delegate on an action (a value of -1 or a QVariant() disable the progress bar 0064 ProgressRole, 0065 0066 /// Special activation role which is emitted when the user Atl-clicks on a section 0067 /// The item is first activated with ActiveRole, then a separate AlternateActiveRole comes 0068 AlternateActiveRole, 0069 0070 // When a layer is not (recursively) visible, then it should be gayed out 0071 ShouldGrayOutRole, 0072 0073 // An index of a color label associated with the node 0074 ColorLabelIndexRole, 0075 0076 // Instruct this model to update all its items' Qt::ItemIsDropEnabled flags in order to 0077 // reflect if the item allows an "onto" drop of the given QMimeData*. 0078 DropEnabled, 0079 0080 // Instructs the model to activate "select opaque" action, 0081 // the selection action (of type SelectionAction) value 0082 // is passed via QVariant as integer 0083 SelectOpaqueRole, 0084 0085 // Returns a text explaining why the node has been excluded from 0086 // projection rendering. If the node is not excluded, then empty 0087 // string is returned 0088 DropReasonRole, 0089 0090 // Let's the model quickly determine whether a layer has any 0091 // animated content attached to it. 0092 IsAnimatedRole, 0093 0094 /// This is to ensure that we can extend the data role in the future, since it's not possible to add a role after BeginThumbnailRole (due to "Hack") 0095 ReservedRole = Qt::UserRole + 99, 0096 0097 /** 0098 * For values of BeginThumbnailRole or higher, a thumbnail of the layer of which neither dimension 0099 * is larger than (int) value - (int) BeginThumbnailRole. 0100 * This is a hack to work around the fact that Interview doesn't have a nice way to 0101 * request thumbnails of arbitrary size. 0102 */ 0103 BeginThumbnailRole 0104 }; 0105 0106 public: // from QAbstractItemModel 0107 0108 explicit KisNodeModel(QObject * parent, int clonedColumns = 0); 0109 ~KisNodeModel() override; 0110 0111 void setDummiesFacade(KisDummiesFacadeBase *dummiesFacade, 0112 KisImageWSP image, 0113 KisShapeController *shapeController, 0114 KisSelectionActionsAdapter *selectionActionsAdapter, 0115 KisNodeManager *nodeManager); 0116 KisNodeSP nodeFromIndex(const QModelIndex &index) const; 0117 QModelIndex indexFromNode(KisNodeSP node) const; 0118 0119 bool showGlobalSelection() const; 0120 0121 public Q_SLOTS: 0122 void setShowGlobalSelection(bool value); 0123 0124 public: 0125 0126 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0127 int columnCount(const QModelIndex &parent = QModelIndex()) const override; 0128 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; 0129 QModelIndex parent(const QModelIndex &index) const override; 0130 QModelIndex sibling(int row, int column, const QModelIndex &idx) const override; 0131 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 0132 Qt::ItemFlags flags(const QModelIndex &index) const override; 0133 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; 0134 QStringList mimeTypes() const override; 0135 QMimeData* mimeData(const QModelIndexList & indexes) const override; 0136 bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) override; 0137 bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override; 0138 Qt::DropActions supportedDragActions() const override; 0139 Qt::DropActions supportedDropActions() const override; 0140 bool hasDummiesFacade(); 0141 0142 static bool belongsToIsolatedGroup(KisImageSP image, KisNodeSP node, KisDummiesFacadeBase *dummiesFacade); 0143 0144 Q_SIGNALS: 0145 0146 void toggleIsolateActiveNode(); 0147 void sigBeforeBeginRemoveRows(const QModelIndex &parent, int start, int end); 0148 0149 protected Q_SLOTS: 0150 void slotBeginInsertDummy(KisNodeDummy *parent, int index, const QString &metaObjectType); 0151 void slotEndInsertDummy(KisNodeDummy *dummy); 0152 void slotBeginRemoveDummy(KisNodeDummy *dummy); 0153 void slotEndRemoveDummy(); 0154 void slotDummyChanged(KisNodeDummy *dummy); 0155 0156 void slotIsolatedModeChanged(); 0157 0158 void slotNodeDisplayModeChanged(bool showRootNode, bool showGlobalSelectionMask); 0159 0160 void processUpdateQueue(); 0161 void progressPercentageChanged(int, const KisNodeSP); 0162 0163 protected: 0164 virtual KisModelIndexConverterBase *createIndexConverter(); 0165 KisModelIndexConverterBase *indexConverter() const; 0166 KisDummiesFacadeBase *dummiesFacade() const; 0167 0168 private: 0169 friend class KisModelIndexConverter; 0170 friend class KisModelIndexConverterShowAll; 0171 0172 void connectDummy(KisNodeDummy *dummy, bool needConnect); 0173 void connectDummies(KisNodeDummy *dummy, bool needConnect); 0174 0175 void resetIndexConverter(); 0176 0177 void regenerateItems(KisNodeDummy *dummy); 0178 bool belongsToIsolatedGroup(KisNodeSP node) const; 0179 0180 void setDropEnabled(const QMimeData *data); 0181 void updateDropEnabled(const QList<KisNodeSP> &nodes, QModelIndex parent = QModelIndex()); 0182 0183 private: 0184 0185 struct Private; 0186 Private * const m_d; 0187 }; 0188 0189 #endif