1 /* 2 SPDX-FileCopyrightText: 2009 Stephen Kelly <steveire@gmail.com> 3 4 SPDX-License-Identifier: LGPL-2.0-or-later 5 */ 6 7 #ifndef KDESCENDANTSPROXYMODEL_P_H 8 #define KDESCENDANTSPROXYMODEL_P_H 9 10 #include <QAbstractProxyModel> 11 12 #include "kitemmodels_export.h" 13 14 #include <memory> 15 16 class KDescendantsProxyModelPrivate; 17 18 /** 19 @class KDescendantsProxyModel kdescendantsproxymodel.h KDescendantsProxyModel 20 21 @brief Proxy Model for restructuring a Tree into a list. 22 23 A KDescendantsProxyModel may be used to alter how the items in the tree are presented. 24 25 Given a model which is represented as a tree: 26 27 \image html entitytreemodel.png "A plain EntityTreeModel in a view" 28 29 The KDescendantsProxyModel restructures the sourceModel to represent it as a flat list. 30 31 @code 32 // ... Create an entityTreeModel 33 KDescendantsProxyModel *descProxy = new KDescendantsProxyModel(this); 34 descProxy->setSourceModel(entityTree); 35 view->setModel(descProxy); 36 @endcode 37 38 \image html descendantentitiesproxymodel.png "A KDescendantsProxyModel." 39 40 KDescendantEntitiesProxyModel can also display the ancestors of the index in the source model as part of its display. 41 42 @code 43 // ... Create an entityTreeModel 44 KDescendantsProxyModel *descProxy = new KDescendantsProxyModel(this); 45 descProxy->setSourceModel(entityTree); 46 47 // #### This is new 48 descProxy->setDisplayAncestorData(true); 49 descProxy->setAncestorSeparator(QString(" / ")); 50 51 view->setModel(descProxy); 52 53 @endcode 54 55 \image html descendantentitiesproxymodel-withansecnames.png "A KDescendantsProxyModel with ancestor names." 56 57 @since 4.6 58 @author Stephen Kelly <steveire@gmail.com> 59 */ 60 class KITEMMODELS_EXPORT KDescendantsProxyModel : public QAbstractProxyModel 61 { 62 Q_OBJECT 63 64 /** 65 * @since 5.62 66 */ 67 Q_PROPERTY(QAbstractItemModel *model READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged) 68 /** 69 * @since 5.62 70 */ 71 Q_PROPERTY(bool displayAncestorData READ displayAncestorData WRITE setDisplayAncestorData NOTIFY displayAncestorDataChanged) 72 /** 73 * @since 5.62 74 */ 75 Q_PROPERTY(QString ancestorSeparator READ ancestorSeparator WRITE setAncestorSeparator NOTIFY ancestorSeparatorChanged) 76 77 /** 78 * If true, all the nodes in the whole tree will be expanded upon loading and all items 79 * of the source model will be shown in the proxy. 80 * The default value is true. 81 * @since 5.74 82 */ 83 Q_PROPERTY(bool expandsByDefault READ expandsByDefault WRITE setExpandsByDefault NOTIFY expandsByDefaultChanged) 84 85 public: 86 enum AdditionalRoles { 87 // Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM)) 88 // to define additional roles. 89 LevelRole = 0x14823F9A, 90 ExpandableRole = 0x1CA894AD, 91 ExpandedRole = 0x1E413DA4, 92 HasSiblingsRole = 0x1633CE0C, 93 }; 94 95 /** 96 * Creates a new descendant entities proxy model. 97 * 98 * @param parent The parent object. 99 */ 100 explicit KDescendantsProxyModel(QObject *parent = nullptr); 101 102 /** 103 * Destroys the descendant entities proxy model. 104 */ 105 ~KDescendantsProxyModel() override; 106 107 /** 108 * Sets the source @p model of the proxy. 109 */ 110 void setSourceModel(QAbstractItemModel *model) override; 111 112 #if KITEMMODELS_ENABLE_DEPRECATED_SINCE(4, 8) 113 /** 114 * @deprecated Since 4.8 115 * 116 * This method does nothing. 117 */ 118 KITEMMODELS_DEPRECATED_VERSION(4, 8, "Method is a no-op.") 119 void setRootIndex(const QModelIndex &index); 120 #endif 121 122 /** 123 * Set whether to show ancestor data in the model. If @p display is true, then 124 * a source model which is displayed as 125 * 126 * @code 127 * -> "Item 0-0" (this is row-depth) 128 * -> -> "Item 0-1" 129 * -> -> "Item 1-1" 130 * -> -> -> "Item 0-2" 131 * -> -> -> "Item 1-2" 132 * -> "Item 1-0" 133 * @endcode 134 * 135 * will be displayed as 136 * 137 * @code 138 * -> *Item 0-0" 139 * -> "Item 0-0 / Item 0-1" 140 * -> "Item 0-0 / Item 1-1" 141 * -> "Item 0-0 / Item 1-1 / Item 0-2" 142 * -> "Item 0-0 / Item 1-1 / Item 1-2" 143 * -> "Item 1-0" 144 * @endcode 145 * 146 * If @p display is false, the proxy will show 147 * 148 * @code 149 * -> *Item 0-0" 150 * -> "Item 0-1" 151 * -> "Item 1-1" 152 * -> "Item 0-2" 153 * -> "Item 1-2" 154 * -> "Item 1-0" 155 * @endcode 156 * 157 * Default is false. 158 */ 159 void setDisplayAncestorData(bool display); 160 161 /** 162 * Whether ancestor data will be displayed. 163 */ 164 bool displayAncestorData() const; 165 166 /** 167 * Sets the ancestor @p separator used between data of ancestors. 168 */ 169 void setAncestorSeparator(const QString &separator); 170 171 /** 172 * Separator used between data of ancestors. 173 */ 174 QString ancestorSeparator() const; 175 176 QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; 177 QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; 178 179 Qt::ItemFlags flags(const QModelIndex &index) const override; 180 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 181 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 182 QVariant headerData(int section, Qt::Orientation orientation, int role) const override; 183 184 QMimeData *mimeData(const QModelIndexList &indexes) const override; 185 QStringList mimeTypes() const override; 186 187 bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; 188 QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const override; 189 QModelIndex parent(const QModelIndex &) const override; 190 int columnCount(const QModelIndex &index = QModelIndex()) const override; 191 QHash<int, QByteArray> roleNames() const override; 192 193 /** 194 * If true, all the nodes in the whole tree will be expanded upon loading (default) 195 * @param expand whether we want everything expanded upon load 196 * @since 5.74 197 */ 198 void setExpandsByDefault(bool expand); 199 200 /** 201 * @returns true if all the tree nodes are expanded by default upon loading 202 * @since 5.74 203 */ 204 bool expandsByDefault() const; 205 206 /** 207 * @returns true if the source index is mapped in the proxy as expanded, therefore it will show its children 208 * @since 5.74 209 */ 210 bool isSourceIndexExpanded(const QModelIndex &sourceIndex) const; 211 212 /** 213 * @returns true if the source index is visible in the proxy, meaning all its parent hierarchy is expanded. 214 * @since 5.74 215 */ 216 bool isSourceIndexVisible(const QModelIndex &sourceIndex) const; 217 218 /** 219 * Maps a source index as expanded in the proxy, all its children will become visible. 220 * @param sourceIndex an idex of the source model. 221 * @since 5.74 222 */ 223 void expandSourceIndex(const QModelIndex &sourceIndex); 224 225 /** 226 * Maps a source index as collapsed in the proxy, all its children will be hidden. 227 * @param sourceIndex an idex of the source model. 228 * @since 5.74 229 */ 230 void collapseSourceIndex(const QModelIndex &sourceIndex); 231 232 Qt::DropActions supportedDropActions() const override; 233 234 /** 235 Reimplemented to match all descendants. 236 */ 237 virtual QModelIndexList match(const QModelIndex &start, 238 int role, 239 const QVariant &value, 240 int hits = 1, 241 Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const override; 242 243 Q_SIGNALS: 244 void sourceModelChanged(); 245 void displayAncestorDataChanged(); 246 void ancestorSeparatorChanged(); 247 void expandsByDefaultChanged(bool expands); 248 void sourceIndexExpanded(const QModelIndex &sourceIndex); 249 void sourceIndexCollapsed(const QModelIndex &sourceIndex); 250 251 private: 252 Q_DECLARE_PRIVATE(KDescendantsProxyModel) 253 //@cond PRIVATE 254 std::unique_ptr<KDescendantsProxyModelPrivate> const d_ptr; 255 256 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeInserted(const QModelIndex &, int, int)) 257 Q_PRIVATE_SLOT(d_func(), void sourceRowsInserted(const QModelIndex &, int, int)) 258 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)) 259 Q_PRIVATE_SLOT(d_func(), void sourceRowsRemoved(const QModelIndex &, int, int)) 260 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)) 261 Q_PRIVATE_SLOT(d_func(), void sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)) 262 Q_PRIVATE_SLOT(d_func(), void sourceModelAboutToBeReset()) 263 Q_PRIVATE_SLOT(d_func(), void sourceModelReset()) 264 Q_PRIVATE_SLOT(d_func(), void sourceLayoutAboutToBeChanged()) 265 Q_PRIVATE_SLOT(d_func(), void sourceLayoutChanged()) 266 Q_PRIVATE_SLOT(d_func(), void sourceDataChanged(const QModelIndex &, const QModelIndex &)) 267 Q_PRIVATE_SLOT(d_func(), void sourceModelDestroyed()) 268 269 Q_PRIVATE_SLOT(d_func(), void processPendingParents()) 270 271 // Make these private, they shouldn't be called by applications 272 // virtual bool insertRows(int , int, const QModelIndex & = QModelIndex()); 273 // virtual bool insertColumns(int, int, const QModelIndex & = QModelIndex()); 274 // virtual bool removeRows(int, int, const QModelIndex & = QModelIndex()); 275 // virtual bool removeColumns(int, int, const QModelIndex & = QModelIndex()); 276 277 //@endcond 278 }; 279 280 #endif 281