Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qqmltreerow.cpp
Go to the documentation of this file.
1
// Copyright (C) 2025 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
// Qt-Security score:significant reason:default
4
5
#
include
"qqmltreerow_p.h"
6
7
#
include
<
QtCore
/
qjsonobject
.
h
>
8
9
QT_BEGIN_NAMESPACE
10
11
using
namespace
Qt::Literals::StringLiterals;
12
13
QQmlTreeRow
::
QQmlTreeRow
(
QQmlTreeRow
*parentItem)
14
: m_parent(parentItem)
15
{
16
17
}
18
19
QQmlTreeRow
::
QQmlTreeRow
(
const
QVariant &data,
QQmlTreeRow
*parentItem)
20
: m_parent(parentItem)
21
{
22
QVariantMap variantMap = data.toMap();
23
unpackVariantMap(variantMap);
24
}
25
26
QQmlTreeRow
::
QQmlTreeRow
(
const
QVariantMap &data,
QQmlTreeRow
*parentItem)
27
: m_parent(parentItem)
28
{
29
unpackVariantMap(data);
30
}
31
32
QQmlTreeRow
::~
QQmlTreeRow
()
33
{
34
// Letting m_children destroy the subtree would recurse once per level of
35
// the tree, which can be arbitrarily deep. Detach the children level by
36
// level instead, so that every row is destroyed without any children left.
37
std::vector<std::unique_ptr<QQmlTreeRow>> pending =
std
::move(m_children);
38
m_children.clear();
39
40
while
(!pending.empty()) {
41
std::unique_ptr<QQmlTreeRow> row =
std
::move(pending.back());
42
pending.pop_back();
43
44
for
(
auto
&child : row->m_children)
45
pending.push_back(std::move(child));
46
row->m_children.clear();
47
}
48
}
49
50
void
QQmlTreeRow
::
addChild
(
QQmlTreeRow
*child)
51
{
52
m_children.push_back(std::unique_ptr<QQmlTreeRow>(child));
53
child
->
setParent
(
this
)
;
54
}
55
56
void
QQmlTreeRow
::
insertChild
(
int
index, std::unique_ptr<QQmlTreeRow> child)
57
{
58
child->setParent(
this
);
59
m_children.insert(m_children.begin() + index, std::move(child));
60
}
61
62
void
QQmlTreeRow
::unpackVariantMap(
const
QVariantMap &variantMap)
63
{
64
// Building the children through the constructor would recurse once per
65
// level of the nested rows, which can be arbitrarily deep. Use an explicit
66
// stack instead: each entry is a row whose data and children still have to
67
// be filled in from the given map.
68
std::vector<std::pair<QQmlTreeRow *, QVariantMap>> pending;
69
pending.emplace_back(
this
, variantMap);
70
71
while
(!pending.empty()) {
72
auto
[row, map] =
std
::move(pending.back());
73
pending.pop_back();
74
75
for
(
auto
it = map.cbegin(); it != map.cend(); ++it) {
76
const
QString& key = it.key();
77
const
QVariant& value = it.value();
78
79
if
((value.typeId() == QMetaType::Type::QVariantList) && (key == ROWS_PROPERTY_NAME)) {
80
const
QList<QVariant> variantList = value.toList();
81
for
(
const
QVariant &rowAsVariant : variantList) {
82
auto
child = std::make_unique<QQmlTreeRow>(row);
83
pending.emplace_back(child.get(), rowAsVariant.toMap());
84
row->m_children.push_back(std::move(child));
85
}
86
}
else
{
87
row->dataMap.insert(key, value);
88
}
89
}
90
}
91
}
92
93
void
QQmlTreeRow
::
removeChild
(std::vector<std::unique_ptr<QQmlTreeRow>>::const_iterator &child)
94
{
95
m_children.erase(child);
96
}
97
98
void
QQmlTreeRow
::
removeChildAt
(
int
i)
99
{
100
m_children.erase(std::next(m_children.begin(), i));
101
}
102
103
std
::
unique_ptr
<
QQmlTreeRow
>
QQmlTreeRow
::
takeChild
(
int
i)
104
{
105
auto
it =
std
::next(m_children.begin(), i);
106
std::unique_ptr<QQmlTreeRow> child =
std
::move(*it);
107
m_children.erase(it);
108
return
child;
109
}
110
111
void
QQmlTreeRow
::
setData
(
const
QVariant &data)
112
{
113
dataMap.clear();
114
const
QVariantMap variantMap = data.toJsonObject().toVariantMap();
115
unpackVariantMap(variantMap);
116
}
117
118
void
QQmlTreeRow
::
setData
(
const
QVariantMap &data)
119
{
120
dataMap.clear();
121
unpackVariantMap(data);
122
}
123
124
void
QQmlTreeRow
::
setField
(
const
QString &key,
const
QVariant &value)
125
{
126
if
(dataMap.contains(key))
127
dataMap[key] = value;
128
}
129
130
QVariant
QQmlTreeRow
::
toVariant
()
const
131
{
132
// Recursing into the children would recurse once per level of the tree,
133
// which can be arbitrarily deep. Use an explicit stack instead, in
134
// post-order: a row's variant is complete once the variants of all its
135
// children have been collected.
136
struct
Frame
137
{
138
const
QQmlTreeRow
*row;
139
size_t nextChild = 0;
140
QVariantList children = {};
141
};
142
143
std::vector<Frame> pending;
144
pending.push_back({
this
});
145
146
QVariant result;
147
while
(!pending.empty()) {
148
Frame &top = pending.back();
149
if
(top.nextChild < top.row->m_children.size()) {
150
const
QQmlTreeRow
*child = top.row->m_children[top.nextChild++].get();
151
pending.push_back({ child });
// invalidates top
152
continue
;
153
}
154
155
QVariantMap variantMap(top.row->dataMap);
156
if
(!top.row->m_children.empty())
157
variantMap[ROWS_PROPERTY_NAME] = top.children;
158
pending.pop_back();
// invalidates top
159
if
(pending.empty())
160
result = variantMap;
161
else
162
pending.back().children.append(QVariant(variantMap));
163
}
164
165
return
result;
166
}
167
168
int
QQmlTreeRow
::
subTreeSize
()
const
169
{
170
// Recursing into the children would recurse once per level of the tree,
171
// which can be arbitrarily deep. Count the rows using an explicit stack.
172
int
size = 0;
173
174
std::vector<
const
QQmlTreeRow *> pending{
this
};
175
while
(!pending.empty()) {
176
const
QQmlTreeRow
*row = pending.back();
177
pending.pop_back();
178
179
++size;
180
for
(
const
auto
&child : row->m_children)
181
pending.push_back(child.get());
182
}
183
184
return
size;
185
}
186
187
QT_END_NAMESPACE
QQmlTreeRow
Definition
qqmltreerow_p.h:34
QQmlTreeRow::addChild
void addChild(QQmlTreeRow *child)
Definition
qqmltreerow.cpp:50
QQmlTreeRow::toVariant
QVariant toVariant() const
Definition
qqmltreerow.cpp:130
QQmlTreeRow::takeChild
std::unique_ptr< QQmlTreeRow > takeChild(int i)
Definition
qqmltreerow.cpp:103
QQmlTreeRow::setData
void setData(const QVariant &data)
Definition
qqmltreerow.cpp:111
QQmlTreeRow::setParent
void setParent(QQmlTreeRow *parent)
Definition
qqmltreerow_p.h:42
QQmlTreeRow::setField
void setField(const QString &key, const QVariant &value)
Definition
qqmltreerow.cpp:124
QQmlTreeRow::removeChild
void removeChild(std::vector< std::unique_ptr< QQmlTreeRow > >::const_iterator &child)
Definition
qqmltreerow.cpp:93
QQmlTreeRow::QQmlTreeRow
QQmlTreeRow(QQmlTreeRow *parentItem=nullptr)
Definition
qqmltreerow.cpp:13
QQmlTreeRow::~QQmlTreeRow
~QQmlTreeRow()
Definition
qqmltreerow.cpp:32
QQmlTreeRow::subTreeSize
int subTreeSize() const
Definition
qqmltreerow.cpp:168
QQmlTreeRow::QQmlTreeRow
QQmlTreeRow(const QVariant &data, QQmlTreeRow *parentItem=nullptr)
Definition
qqmltreerow.cpp:19
QQmlTreeRow::insertChild
void insertChild(int index, std::unique_ptr< QQmlTreeRow > child)
Definition
qqmltreerow.cpp:56
QQmlTreeRow::removeChildAt
void removeChildAt(int i)
Definition
qqmltreerow.cpp:98
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qtdeclarative
src
labs
models
qqmltreerow.cpp
Generated on
for Qt by
1.18.0