1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "abstractitemmodelhandler_p.h"
5
6QT_BEGIN_NAMESPACE
7
8AbstractItemModelHandler::AbstractItemModelHandler(QObject *parent)
9 : QObject(parent)
10 , resolvePending(0)
11 , m_fullReset(true)
12{
13 m_resolveTimer.setSingleShot(true);
14 QObject::connect(sender: &m_resolveTimer,
15 signal: &QTimer::timeout,
16 context: this,
17 slot: &AbstractItemModelHandler::handlePendingResolve);
18}
19
20AbstractItemModelHandler::~AbstractItemModelHandler() {}
21
22void AbstractItemModelHandler::setItemModel(QAbstractItemModel *itemModel)
23{
24 if (itemModel != m_itemModel.data()) {
25 if (!m_itemModel.isNull())
26 QObject::disconnect(sender: m_itemModel, signal: 0, receiver: this, member: 0);
27
28 m_itemModel = itemModel;
29
30 if (!m_itemModel.isNull()) {
31 QObject::connect(sender: m_itemModel.data(),
32 signal: &QAbstractItemModel::columnsInserted,
33 context: this,
34 slot: &AbstractItemModelHandler::handleColumnsInserted);
35 QObject::connect(sender: m_itemModel.data(),
36 signal: &QAbstractItemModel::columnsMoved,
37 context: this,
38 slot: &AbstractItemModelHandler::handleColumnsMoved);
39 QObject::connect(sender: m_itemModel.data(),
40 signal: &QAbstractItemModel::columnsRemoved,
41 context: this,
42 slot: &AbstractItemModelHandler::handleColumnsRemoved);
43 QObject::connect(sender: m_itemModel.data(),
44 signal: &QAbstractItemModel::dataChanged,
45 context: this,
46 slot: &AbstractItemModelHandler::handleDataChanged);
47 QObject::connect(sender: m_itemModel.data(),
48 signal: &QAbstractItemModel::layoutChanged,
49 context: this,
50 slot: &AbstractItemModelHandler::handleLayoutChanged);
51 QObject::connect(sender: m_itemModel.data(),
52 signal: &QAbstractItemModel::modelReset,
53 context: this,
54 slot: &AbstractItemModelHandler::handleModelReset);
55 QObject::connect(sender: m_itemModel.data(),
56 signal: &QAbstractItemModel::rowsInserted,
57 context: this,
58 slot: &AbstractItemModelHandler::handleRowsInserted);
59 QObject::connect(sender: m_itemModel.data(),
60 signal: &QAbstractItemModel::rowsMoved,
61 context: this,
62 slot: &AbstractItemModelHandler::handleRowsMoved);
63 QObject::connect(sender: m_itemModel.data(),
64 signal: &QAbstractItemModel::rowsRemoved,
65 context: this,
66 slot: &AbstractItemModelHandler::handleRowsRemoved);
67 }
68 if (!m_resolveTimer.isActive())
69 m_resolveTimer.start(msec: 0);
70
71 emit itemModelChanged(itemModel);
72 }
73}
74
75QAbstractItemModel *AbstractItemModelHandler::itemModel() const
76{
77 return m_itemModel.data();
78}
79
80void AbstractItemModelHandler::handleColumnsInserted(const QModelIndex &parent, int start, int end)
81{
82 Q_UNUSED(parent);
83 Q_UNUSED(start);
84 Q_UNUSED(end);
85
86 // Manipulating columns changes all rows in proxies that map rows/columns
87 // directly, and its effects are not clearly defined in others -> always do
88 // full reset.
89 if (!m_resolveTimer.isActive()) {
90 m_fullReset = true;
91 m_resolveTimer.start(msec: 0);
92 }
93}
94
95void AbstractItemModelHandler::handleColumnsMoved(const QModelIndex &sourceParent,
96 int sourceStart,
97 int sourceEnd,
98 const QModelIndex &destinationParent,
99 int destinationColumn)
100{
101 Q_UNUSED(sourceParent);
102 Q_UNUSED(sourceStart);
103 Q_UNUSED(sourceEnd);
104 Q_UNUSED(destinationParent);
105 Q_UNUSED(destinationColumn);
106
107 // Manipulating columns changes all rows in proxies that map rows/columns
108 // directly, and its effects are not clearly defined in others -> always do
109 // full reset.
110 if (!m_resolveTimer.isActive()) {
111 m_fullReset = true;
112 m_resolveTimer.start(msec: 0);
113 }
114}
115
116void AbstractItemModelHandler::handleColumnsRemoved(const QModelIndex &parent, int start, int end)
117{
118 Q_UNUSED(parent);
119 Q_UNUSED(start);
120 Q_UNUSED(end);
121
122 // Manipulating columns changes all rows in proxies that map rows/columns
123 // directly, and its effects are not clearly defined in others -> always do
124 // full reset.
125 if (!m_resolveTimer.isActive()) {
126 m_fullReset = true;
127 m_resolveTimer.start(msec: 0);
128 }
129}
130
131void AbstractItemModelHandler::handleDataChanged(const QModelIndex &topLeft,
132 const QModelIndex &bottomRight,
133 const QList<int> &roles)
134{
135 Q_UNUSED(topLeft);
136 Q_UNUSED(bottomRight);
137 Q_UNUSED(roles);
138
139 // Default handling for dataChanged is to do full reset, as it cannot be
140 // optimized in a general case, where we do not know which row/column/index
141 // the item model item actually ended up to in the proxy.
142 if (!m_resolveTimer.isActive()) {
143 m_fullReset = true;
144 m_resolveTimer.start(msec: 0);
145 }
146}
147
148void AbstractItemModelHandler::handleLayoutChanged(const QList<QPersistentModelIndex> &parents,
149 QAbstractItemModel::LayoutChangeHint hint)
150{
151 Q_UNUSED(parents);
152 Q_UNUSED(hint);
153
154 // Resolve entire model if layout changes
155 if (!m_resolveTimer.isActive()) {
156 m_fullReset = true;
157 m_resolveTimer.start(msec: 0);
158 }
159}
160
161void AbstractItemModelHandler::handleModelReset()
162{
163 // Data cleared, reset array
164 if (!m_resolveTimer.isActive()) {
165 m_fullReset = true;
166 m_resolveTimer.start(msec: 0);
167 }
168}
169
170void AbstractItemModelHandler::handleRowsInserted(const QModelIndex &parent, int start, int end)
171{
172 Q_UNUSED(parent);
173 Q_UNUSED(start);
174 Q_UNUSED(end);
175
176 // Default handling for rowsInserted is to do full reset, as it cannot be
177 // optimized in a general case, where we do not know which row/column/index
178 // the item model item actually ended up to in the proxy.
179 if (!m_resolveTimer.isActive()) {
180 m_fullReset = true;
181 m_resolveTimer.start(msec: 0);
182 }
183}
184
185void AbstractItemModelHandler::handleRowsMoved(const QModelIndex &sourceParent,
186 int sourceStart,
187 int sourceEnd,
188 const QModelIndex &destinationParent,
189 int destinationRow)
190{
191 Q_UNUSED(sourceParent);
192 Q_UNUSED(sourceStart);
193 Q_UNUSED(sourceEnd);
194 Q_UNUSED(destinationParent);
195 Q_UNUSED(destinationRow);
196
197 // Default handling for rowsMoved is to do full reset, as it cannot be
198 // optimized in a general case, where we do not know which row/column/index
199 // the item model item actually ended up to in the proxy.
200 if (!m_resolveTimer.isActive()) {
201 m_fullReset = true;
202 m_resolveTimer.start(msec: 0);
203 }
204}
205
206void AbstractItemModelHandler::handleRowsRemoved(const QModelIndex &parent, int start, int end)
207{
208 Q_UNUSED(parent);
209 Q_UNUSED(start);
210 Q_UNUSED(end);
211
212 // Default handling for rowsRemoved is to do full reset, as it cannot be
213 // optimized in a general case, where we do not know which row/column/index
214 // the item model item actually ended up to in the proxy.
215 if (!m_resolveTimer.isActive()) {
216 m_fullReset = true;
217 m_resolveTimer.start(msec: 0);
218 }
219}
220
221void AbstractItemModelHandler::handleMappingChanged()
222{
223 if (!m_resolveTimer.isActive())
224 m_resolveTimer.start(msec: 0);
225}
226
227void AbstractItemModelHandler::handlePendingResolve()
228{
229 resolveModel();
230 m_fullReset = false;
231}
232
233QT_END_NAMESPACE
234

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtgraphs/src/graphs3d/data/abstractitemmodelhandler.cpp