File indexing completed on 2024-05-05 03:56:42
0001 /* 0002 SPDX-FileCopyrightText: 2009 Stephen Kelly <steveire@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KDESCENDANTSPROXYMODEL_P_H 0008 #define KDESCENDANTSPROXYMODEL_P_H 0009 0010 #include <QAbstractProxyModel> 0011 0012 #include "kitemmodels_export.h" 0013 0014 #include <memory> 0015 0016 class KDescendantsProxyModelPrivate; 0017 0018 /** 0019 @class KDescendantsProxyModel kdescendantsproxymodel.h KDescendantsProxyModel 0020 0021 @brief Proxy Model for restructuring a Tree into a list. 0022 0023 A KDescendantsProxyModel may be used to alter how the items in the tree are presented. 0024 0025 Given a model which is represented as a tree: 0026 0027 \image html entitytreemodel.png "A plain EntityTreeModel in a view" 0028 0029 The KDescendantsProxyModel restructures the sourceModel to represent it as a flat list. 0030 0031 @code 0032 // ... Create an entityTreeModel 0033 KDescendantsProxyModel *descProxy = new KDescendantsProxyModel(this); 0034 descProxy->setSourceModel(entityTree); 0035 view->setModel(descProxy); 0036 @endcode 0037 0038 \image html descendantentitiesproxymodel.png "A KDescendantsProxyModel." 0039 0040 KDescendantEntitiesProxyModel can also display the ancestors of the index in the source model as part of its display. 0041 0042 @code 0043 // ... Create an entityTreeModel 0044 KDescendantsProxyModel *descProxy = new KDescendantsProxyModel(this); 0045 descProxy->setSourceModel(entityTree); 0046 0047 // #### This is new 0048 descProxy->setDisplayAncestorData(true); 0049 descProxy->setAncestorSeparator(QString(" / ")); 0050 0051 view->setModel(descProxy); 0052 0053 @endcode 0054 0055 \image html descendantentitiesproxymodel-withansecnames.png "A KDescendantsProxyModel with ancestor names." 0056 0057 @since 4.6 0058 @author Stephen Kelly <steveire@gmail.com> 0059 */ 0060 class KITEMMODELS_EXPORT KDescendantsProxyModel : public QAbstractProxyModel 0061 { 0062 Q_OBJECT 0063 0064 /** 0065 * @since 5.62 0066 */ 0067 Q_PROPERTY(QAbstractItemModel *model READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged) 0068 /** 0069 * @since 5.62 0070 */ 0071 Q_PROPERTY(bool displayAncestorData READ displayAncestorData WRITE setDisplayAncestorData NOTIFY displayAncestorDataChanged) 0072 /** 0073 * @since 5.62 0074 */ 0075 Q_PROPERTY(QString ancestorSeparator READ ancestorSeparator WRITE setAncestorSeparator NOTIFY ancestorSeparatorChanged) 0076 0077 /** 0078 * If true, all the nodes in the whole tree will be expanded upon loading and all items 0079 * of the source model will be shown in the proxy. 0080 * The default value is true. 0081 * @since 5.74 0082 */ 0083 Q_PROPERTY(bool expandsByDefault READ expandsByDefault WRITE setExpandsByDefault NOTIFY expandsByDefaultChanged) 0084 0085 public: 0086 enum AdditionalRoles { 0087 // Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM)) 0088 // to define additional roles. 0089 LevelRole = 0x14823F9A, 0090 ExpandableRole = 0x1CA894AD, 0091 ExpandedRole = 0x1E413DA4, 0092 HasSiblingsRole = 0x1633CE0C, 0093 }; 0094 0095 /** 0096 * Creates a new descendant entities proxy model. 0097 * 0098 * @param parent The parent object. 0099 */ 0100 explicit KDescendantsProxyModel(QObject *parent = nullptr); 0101 0102 /** 0103 * Destroys the descendant entities proxy model. 0104 */ 0105 ~KDescendantsProxyModel() override; 0106 0107 /** 0108 * Sets the source @p model of the proxy. 0109 */ 0110 void setSourceModel(QAbstractItemModel *model) override; 0111 0112 /** 0113 * Set whether to show ancestor data in the model. If @p display is true, then 0114 * a source model which is displayed as 0115 * 0116 * @code 0117 * -> "Item 0-0" (this is row-depth) 0118 * -> -> "Item 0-1" 0119 * -> -> "Item 1-1" 0120 * -> -> -> "Item 0-2" 0121 * -> -> -> "Item 1-2" 0122 * -> "Item 1-0" 0123 * @endcode 0124 * 0125 * will be displayed as 0126 * 0127 * @code 0128 * -> *Item 0-0" 0129 * -> "Item 0-0 / Item 0-1" 0130 * -> "Item 0-0 / Item 1-1" 0131 * -> "Item 0-0 / Item 1-1 / Item 0-2" 0132 * -> "Item 0-0 / Item 1-1 / Item 1-2" 0133 * -> "Item 1-0" 0134 * @endcode 0135 * 0136 * If @p display is false, the proxy will show 0137 * 0138 * @code 0139 * -> *Item 0-0" 0140 * -> "Item 0-1" 0141 * -> "Item 1-1" 0142 * -> "Item 0-2" 0143 * -> "Item 1-2" 0144 * -> "Item 1-0" 0145 * @endcode 0146 * 0147 * Default is false. 0148 */ 0149 void setDisplayAncestorData(bool display); 0150 0151 /** 0152 * Whether ancestor data will be displayed. 0153 */ 0154 bool displayAncestorData() const; 0155 0156 /** 0157 * Sets the ancestor @p separator used between data of ancestors. 0158 */ 0159 void setAncestorSeparator(const QString &separator); 0160 0161 /** 0162 * Separator used between data of ancestors. 0163 */ 0164 QString ancestorSeparator() const; 0165 0166 QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; 0167 QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; 0168 0169 Qt::ItemFlags flags(const QModelIndex &index) const override; 0170 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 0171 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0172 QVariant headerData(int section, Qt::Orientation orientation, int role) const override; 0173 0174 QMimeData *mimeData(const QModelIndexList &indexes) const override; 0175 QStringList mimeTypes() const override; 0176 0177 bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; 0178 QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const override; 0179 QModelIndex parent(const QModelIndex &) const override; 0180 int columnCount(const QModelIndex &index = QModelIndex()) const override; 0181 QHash<int, QByteArray> roleNames() const override; 0182 0183 /** 0184 * If true, all the nodes in the whole tree will be expanded upon loading (default) 0185 * @param expand whether we want everything expanded upon load 0186 * @since 5.74 0187 */ 0188 void setExpandsByDefault(bool expand); 0189 0190 /** 0191 * @returns true if all the tree nodes are expanded by default upon loading 0192 * @since 5.74 0193 */ 0194 bool expandsByDefault() const; 0195 0196 /** 0197 * @returns true if the source index is mapped in the proxy as expanded, therefore it will show its children 0198 * @since 5.74 0199 */ 0200 bool isSourceIndexExpanded(const QModelIndex &sourceIndex) const; 0201 0202 /** 0203 * @returns true if the source index is visible in the proxy, meaning all its parent hierarchy is expanded. 0204 * @since 5.74 0205 */ 0206 bool isSourceIndexVisible(const QModelIndex &sourceIndex) const; 0207 0208 /** 0209 * Maps a source index as expanded in the proxy, all its children will become visible. 0210 * @param sourceIndex an idex of the source model. 0211 * @since 5.74 0212 */ 0213 void expandSourceIndex(const QModelIndex &sourceIndex); 0214 0215 /** 0216 * Maps a source index as collapsed in the proxy, all its children will be hidden. 0217 * @param sourceIndex an idex of the source model. 0218 * @since 5.74 0219 */ 0220 void collapseSourceIndex(const QModelIndex &sourceIndex); 0221 0222 Qt::DropActions supportedDropActions() const override; 0223 0224 /** 0225 Reimplemented to match all descendants. 0226 */ 0227 virtual QModelIndexList match(const QModelIndex &start, 0228 int role, 0229 const QVariant &value, 0230 int hits = 1, 0231 Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const override; 0232 0233 Q_SIGNALS: 0234 void sourceModelChanged(); 0235 void displayAncestorDataChanged(); 0236 void ancestorSeparatorChanged(); 0237 void expandsByDefaultChanged(bool expands); 0238 void sourceIndexExpanded(const QModelIndex &sourceIndex); 0239 void sourceIndexCollapsed(const QModelIndex &sourceIndex); 0240 0241 private: 0242 Q_DECLARE_PRIVATE(KDescendantsProxyModel) 0243 //@cond PRIVATE 0244 std::unique_ptr<KDescendantsProxyModelPrivate> const d_ptr; 0245 0246 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeInserted(const QModelIndex &, int, int)) 0247 Q_PRIVATE_SLOT(d_func(), void sourceRowsInserted(const QModelIndex &, int, int)) 0248 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)) 0249 Q_PRIVATE_SLOT(d_func(), void sourceRowsRemoved(const QModelIndex &, int, int)) 0250 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)) 0251 Q_PRIVATE_SLOT(d_func(), void sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)) 0252 Q_PRIVATE_SLOT(d_func(), void sourceModelAboutToBeReset()) 0253 Q_PRIVATE_SLOT(d_func(), void sourceModelReset()) 0254 Q_PRIVATE_SLOT(d_func(), void sourceLayoutAboutToBeChanged()) 0255 Q_PRIVATE_SLOT(d_func(), void sourceLayoutChanged()) 0256 Q_PRIVATE_SLOT(d_func(), void sourceDataChanged(const QModelIndex &, const QModelIndex &)) 0257 Q_PRIVATE_SLOT(d_func(), void sourceModelDestroyed()) 0258 0259 Q_PRIVATE_SLOT(d_func(), void processPendingParents()) 0260 0261 // Make these private, they shouldn't be called by applications 0262 // virtual bool insertRows(int , int, const QModelIndex & = QModelIndex()); 0263 // virtual bool insertColumns(int, int, const QModelIndex & = QModelIndex()); 0264 // virtual bool removeRows(int, int, const QModelIndex & = QModelIndex()); 0265 // virtual bool removeColumns(int, int, const QModelIndex & = QModelIndex()); 0266 0267 //@endcond 0268 }; 0269 0270 #endif