1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QTREEWIDGET_P_H
5#define QTREEWIDGET_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. This header file may change
12// from version to version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <QtWidgets/private/qtwidgetsglobal_p.h>
18#include <QtCore/qabstractitemmodel.h>
19#include <private/qabstractitemmodel_p.h>
20#include <QtCore/qbasictimer.h>
21#include <QtWidgets/qtreewidget.h>
22#include <private/qtreeview_p.h>
23#include <QtWidgets/qheaderview.h>
24
25#include <array>
26
27QT_REQUIRE_CONFIG(treewidget);
28
29QT_BEGIN_NAMESPACE
30
31class QTreeWidgetItem;
32class QTreeWidgetItemIterator;
33class QTreeModelPrivate;
34
35class QTreeModel : public QAbstractItemModel
36{
37 Q_OBJECT
38 friend class QTreeWidget;
39 friend class QTreeWidgetPrivate;
40 friend class QTreeWidgetItem;
41 friend class QTreeWidgetItemPrivate;
42 friend class QTreeWidgetItemIterator;
43 friend class QTreeWidgetItemIteratorPrivate;
44
45public:
46 explicit QTreeModel(int columns = 0, QTreeWidget *parent = nullptr);
47 ~QTreeModel();
48
49 inline QTreeWidget *view() const
50 { return qobject_cast<QTreeWidget*>(object: QObject::parent()); }
51
52 void clear();
53 void setColumnCount(int columns);
54
55 QTreeWidgetItem *item(const QModelIndex &index) const;
56 void itemChanged(QTreeWidgetItem *item);
57
58 QModelIndex index(const QTreeWidgetItem *item, int column) const;
59 QModelIndex index(int row, int column, const QModelIndex &parent) const override;
60 QModelIndex parent(const QModelIndex &child) const override;
61 int rowCount(const QModelIndex &parent) const override;
62 int columnCount(const QModelIndex &parent = QModelIndex()) const override;
63 bool hasChildren(const QModelIndex &parent) const override;
64
65 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
66 bool setData(const QModelIndex &index, const QVariant &value, int role) override;
67 bool clearItemData(const QModelIndex &index) override;
68 QMap<int, QVariant> itemData(const QModelIndex &index) const override;
69
70 QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
71 bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
72 int role) override;
73
74 Qt::ItemFlags flags(const QModelIndex &index) const override;
75
76 void sort(int column, Qt::SortOrder order) override;
77 void ensureSorted(int column, Qt::SortOrder order,
78 int start, int end, const QModelIndex &parent);
79 static bool itemLessThan(const std::pair<QTreeWidgetItem*,int> &left,
80 const std::pair<QTreeWidgetItem*,int> &right);
81 static bool itemGreaterThan(const std::pair<QTreeWidgetItem*,int> &left,
82 const std::pair<QTreeWidgetItem*,int> &right);
83 static QList<QTreeWidgetItem*>::iterator sortedInsertionIterator(
84 const QList<QTreeWidgetItem*>::iterator &begin,
85 const QList<QTreeWidgetItem*>::iterator &end,
86 Qt::SortOrder order, QTreeWidgetItem *item);
87
88 bool insertRows(int row, int count, const QModelIndex &) override;
89 bool insertColumns(int column, int count, const QModelIndex &) override;
90
91 bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
92
93 // dnd
94 QStringList mimeTypes() const override;
95 QMimeData *mimeData(const QModelIndexList &indexes) const override;
96 bool dropMimeData(const QMimeData *data, Qt::DropAction action,
97 int row, int column, const QModelIndex &parent) override;
98 Qt::DropActions supportedDropActions() const override;
99
100 QMimeData *internalMimeData() const;
101
102 inline QModelIndex createIndexFromItem(int row, int col, QTreeWidgetItem *item) const
103 { return createIndex(arow: row, acolumn: col, adata: item); }
104
105protected:
106 QTreeModel(QTreeModelPrivate &, QTreeWidget *parent = nullptr);
107 void emitDataChanged(QTreeWidgetItem *item, int column, const QList<int> &roles);
108 void beginInsertItems(QTreeWidgetItem *parent, int row, int count);
109 void endInsertItems();
110 void beginRemoveItems(QTreeWidgetItem *parent, int row, int count);
111 void endRemoveItems();
112 void sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortOrder order);
113 void timerEvent(QTimerEvent *) override;
114
115private:
116 QTreeWidgetItem *rootItem;
117 QTreeWidgetItem *headerItem;
118
119 mutable QModelIndexList cachedIndexes;
120 QList<QTreeWidgetItemIterator*> iterators;
121
122 mutable QBasicTimer sortPendingTimer;
123 mutable bool skipPendingSort = false; // no sorting during internal operations
124 bool inline executePendingSort() const;
125
126 bool isChanging() const;
127
128private:
129 Q_DECLARE_PRIVATE(QTreeModel)
130public:
131 struct SkipSorting
132 {
133 const QTreeModel * const model;
134 const bool previous;
135 SkipSorting(const QTreeModel *m) : model(m), previous(model ? model->skipPendingSort : false)
136 { if (model) model->skipPendingSort = true; }
137 ~SkipSorting() { if (model) model->skipPendingSort = previous; }
138 };
139 friend struct SkipSorting;
140};
141
142QT_BEGIN_INCLUDE_NAMESPACE
143#include "private/qabstractitemmodel_p.h"
144QT_END_INCLUDE_NAMESPACE
145
146class QTreeModelPrivate : public QAbstractItemModelPrivate
147{
148 Q_DECLARE_PUBLIC(QTreeModel)
149 void executePendingOperations() const override;
150};
151
152class QTreeWidgetItemPrivate
153{
154public:
155 QTreeWidgetItemPrivate(QTreeWidgetItem *item)
156 : q(item), disabled(false), selected(false), hidden(false), rowGuess(-1),
157 policy(QTreeWidgetItem::DontShowIndicatorWhenChildless) {}
158 void propagateDisabled(QTreeWidgetItem *item);
159 void updateHiddenStatus(QTreeWidgetItem *item, bool inserting);
160 void sortChildren(int column, Qt::SortOrder order, bool climb);
161 QTreeWidgetItem *q;
162 QVariantList display;
163 uint disabled : 1;
164 uint selected : 1;
165 uint hidden : 1;
166 int rowGuess;
167 QTreeWidgetItem::ChildIndicatorPolicy policy;
168};
169
170
171inline bool QTreeModel::executePendingSort() const
172{
173 if (!skipPendingSort && sortPendingTimer.isActive() && !isChanging()) {
174 sortPendingTimer.stop();
175 int column = view()->header()->sortIndicatorSection();
176 Qt::SortOrder order = view()->header()->sortIndicatorOrder();
177 QTreeModel *that = const_cast<QTreeModel*>(this);
178 that->sort(column, order);
179 return true;
180 }
181 return false;
182}
183
184class QTreeWidgetPrivate : public QTreeViewPrivate
185{
186 friend class QTreeModel;
187 Q_DECLARE_PUBLIC(QTreeWidget)
188public:
189 QTreeWidgetPrivate() : QTreeViewPrivate(), explicitSortColumn(-1) {}
190 void clearConnections();
191 inline QTreeModel *treeModel() const { return qobject_cast<QTreeModel*>(object: model); }
192 inline QModelIndex index(const QTreeWidgetItem *item, int column = 0) const
193 { return treeModel()->index(item, column); }
194 inline QTreeWidgetItem *item(const QModelIndex &index) const
195 { return treeModel()->item(index); }
196 void emitItemPressed(const QModelIndex &index);
197 void emitItemClicked(const QModelIndex &index);
198 void emitItemDoubleClicked(const QModelIndex &index);
199 void emitItemActivated(const QModelIndex &index);
200 void emitItemEntered(const QModelIndex &index);
201 void emitItemChanged(const QModelIndex &index);
202 void emitItemExpanded(const QModelIndex &index);
203 void emitItemCollapsed(const QModelIndex &index);
204 void emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &index);
205 void sort();
206 void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
207 void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
208
209 // used by QTreeWidgetItem::sortChildren to make sure the column argument is used
210 int explicitSortColumn;
211
212 std::array<QMetaObject::Connection, 12> connections;
213};
214
215QT_END_NAMESPACE
216
217#endif // QTREEWIDGET_P_H
218

source code of qtbase/src/widgets/itemviews/qtreewidget_p.h