1/****************************************************************************
2**
3** Copyright (C) 2016 Ford Motor Company
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQMLCHILDRENPRIVATE_H
41#define QQMLCHILDRENPRIVATE_H
42
43#include <QAbstractState>
44#include <QAbstractTransition>
45#include <QStateMachine>
46#include <QQmlInfo>
47#include <QQmlListProperty>
48
49enum class ChildrenMode {
50 None = 0x0,
51 State = 0x1,
52 Transition = 0x2,
53 StateOrTransition = State | Transition
54};
55
56template<typename T>
57static T *parentObject(QQmlListProperty<QObject> *prop) { return static_cast<T *>(prop->object); }
58
59template<class T, ChildrenMode Mode>
60struct ParentHandler
61{
62 static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem);
63 static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item);
64};
65
66template<class T>
67struct ParentHandler<T, ChildrenMode::None>
68{
69 static bool unparentItem(QQmlListProperty<QObject> *, QObject *) { return true; }
70 static bool parentItem(QQmlListProperty<QObject> *, QObject *) { return true; }
71};
72
73template<class T>
74struct ParentHandler<T, ChildrenMode::State>
75{
76 static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item)
77 {
78 if (QAbstractState *state = qobject_cast<QAbstractState *>(object: item)) {
79 state->setParent(parentObject<T>(prop));
80 return true;
81 }
82 return false;
83 }
84
85 static bool unparentItem(QQmlListProperty<QObject> *, QObject *oldItem)
86 {
87 if (QAbstractState *state = qobject_cast<QAbstractState *>(object: oldItem)) {
88 state->setParent(nullptr);
89 return true;
90 }
91 return false;
92 }
93};
94
95template<class T>
96struct ParentHandler<T, ChildrenMode::Transition>
97{
98 static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item)
99 {
100 if (QAbstractTransition *trans = qobject_cast<QAbstractTransition *>(object: item)) {
101 parentObject<T>(prop)->addTransition(trans);
102 return true;
103 }
104 return false;
105 }
106
107 static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
108 {
109 if (QAbstractTransition *trans = qobject_cast<QAbstractTransition *>(object: oldItem)) {
110 parentObject<T>(prop)->removeTransition(trans);
111 return true;
112 }
113 return false;
114 }
115};
116
117template<class T>
118struct ParentHandler<T, ChildrenMode::StateOrTransition>
119{
120 static bool parentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
121 {
122 return ParentHandler<T, ChildrenMode::State>::parentItem(prop, oldItem)
123 || ParentHandler<T, ChildrenMode::Transition>::parentItem(prop, oldItem);
124 }
125
126 static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
127 {
128 return ParentHandler<T, ChildrenMode::State>::unparentItem(prop, oldItem)
129 || ParentHandler<T, ChildrenMode::Transition>::unparentItem(prop, oldItem);
130 }
131};
132
133template <class T, ChildrenMode Mode>
134class ChildrenPrivate
135{
136public:
137 static void append(QQmlListProperty<QObject> *prop, QObject *item)
138 {
139 Handler::parentItem(prop, item);
140 static_cast<Self *>(prop->data)->children.append(item);
141 emit parentObject<T>(prop)->childrenChanged();
142 }
143
144 static int count(QQmlListProperty<QObject> *prop)
145 {
146 return static_cast<Self *>(prop->data)->children.count();
147 }
148
149 static QObject *at(QQmlListProperty<QObject> *prop, int index)
150 {
151 return static_cast<Self *>(prop->data)->children.at(index);
152 }
153
154 static void clear(QQmlListProperty<QObject> *prop)
155 {
156 auto &children = static_cast<Self *>(prop->data)->children;
157 for (QObject *oldItem : qAsConst(children))
158 Handler::unparentItem(prop, oldItem);
159
160 children.clear();
161 emit parentObject<T>(prop)->childrenChanged();
162 }
163
164 static void replace(QQmlListProperty<QObject> *prop, int index, QObject *item)
165 {
166 auto &children = static_cast<Self *>(prop->data)->children;
167
168 Handler::unparentItem(prop, children.at(index));
169 Handler::parentItem(prop, item);
170
171 children.replace(index, item);
172 emit parentObject<T>(prop)->childrenChanged();
173 }
174
175 static void removeLast(QQmlListProperty<QObject> *prop)
176 {
177 Handler::unparentItem(prop, static_cast<Self *>(prop->data)->children.takeLast());
178 emit parentObject<T>(prop)->childrenChanged();
179 }
180
181private:
182 using Self = ChildrenPrivate<T, Mode>;
183 using Handler = ParentHandler<T, Mode>;
184
185 QList<QObject *> children;
186};
187
188#endif
189

source code of qtdeclarative/src/imports/statemachine/childrenprivate.h