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