1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
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#include "qquickpackage_p.h"
41
42#include <private/qobject_p.h>
43#include <private/qqmlguard_p.h>
44
45QT_BEGIN_NAMESPACE
46
47/*!
48 \qmltype Package
49 \instantiates QQuickPackage
50 \inqmlmodule QtQml.Models
51 \ingroup qtquick-models
52 \brief Specifies a collection of named items.
53
54 The Package type is used in conjunction with
55 DelegateModel to enable delegates with a shared context
56 to be provided to multiple views.
57
58 Any item within a Package may be assigned a name via the
59 \l{Package::name}{Package.name} attached property.
60
61 The example below creates a Package containing two named items;
62 \e list and \e grid. The third item in the package (the \l Rectangle) is parented to whichever
63 delegate it should appear in. This allows an item to move
64 between views.
65
66 \snippet package/Delegate.qml 0
67
68 These named items are used as the delegates by the two views who
69 reference the special \l{DelegateModel::parts} property to select
70 a model which provides the chosen delegate.
71
72 \snippet package/view.qml 0
73
74 \note Package is part of QtQml.Models since version 2.14 and part of QtQuick since version 2.0.
75 Importing Package via QtQuick is deprecated since Qt 5.14.
76
77 \sa {Qt Quick Examples - Views}, {Qt Quick Demo - Photo Viewer}, {Qt QML}
78*/
79
80/*!
81 \qmlattachedproperty string QtQuick::Package::name
82 This attached property holds the name of an item within a Package.
83*/
84
85
86class QQuickPackagePrivate : public QObjectPrivate
87{
88public:
89 QQuickPackagePrivate() {}
90
91 struct DataGuard : public QQmlGuard<QObject>
92 {
93 DataGuard(QObject *obj, QList<DataGuard> *l) : list(l) { (QQmlGuard<QObject>&)*this = obj; }
94 QList<DataGuard> *list;
95 void objectDestroyed(QObject *) override {
96 // we assume priv will always be destroyed after objectDestroyed calls
97 list->removeOne(t: *this);
98 }
99 };
100
101 QList<DataGuard> dataList;
102 static void data_append(QQmlListProperty<QObject> *prop, QObject *o) {
103 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
104 list->append(t: DataGuard(o, list));
105 }
106 static void data_clear(QQmlListProperty<QObject> *prop) {
107 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
108 list->clear();
109 }
110 static QObject *data_at(QQmlListProperty<QObject> *prop, int index) {
111 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
112 return list->at(i: index);
113 }
114 static int data_count(QQmlListProperty<QObject> *prop) {
115 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
116 return list->count();
117 }
118 static void data_replace(QQmlListProperty<QObject> *prop, int index, QObject *o) {
119 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
120 list->replace(i: index, t: DataGuard(o, list));
121 }
122 static void data_removeLast(QQmlListProperty<QObject> *prop) {
123 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
124 list->removeLast();
125 }
126};
127
128QHash<QObject *, QQuickPackageAttached *> QQuickPackageAttached::attached;
129
130QQuickPackageAttached::QQuickPackageAttached(QObject *parent)
131: QObject(parent)
132{
133 attached.insert(key: parent, value: this);
134}
135
136QQuickPackageAttached::~QQuickPackageAttached()
137{
138 attached.remove(key: parent());
139}
140
141QString QQuickPackageAttached::name() const
142{
143 return _name;
144}
145
146void QQuickPackageAttached::setName(const QString &n)
147{
148 _name = n;
149}
150
151QQuickPackage::QQuickPackage(QObject *parent)
152 : QObject(*(new QQuickPackagePrivate), parent)
153{
154}
155
156QQuickPackage::~QQuickPackage()
157{
158}
159
160QQmlListProperty<QObject> QQuickPackage::data()
161{
162 Q_D(QQuickPackage);
163 return QQmlListProperty<QObject>(this, &d->dataList,
164 QQuickPackagePrivate::data_append,
165 QQuickPackagePrivate::data_count,
166 QQuickPackagePrivate::data_at,
167 QQuickPackagePrivate::data_clear,
168 QQuickPackagePrivate::data_replace,
169 QQuickPackagePrivate::data_removeLast);
170}
171
172bool QQuickPackage::hasPart(const QString &name)
173{
174 Q_D(QQuickPackage);
175 for (int ii = 0; ii < d->dataList.count(); ++ii) {
176 QObject *obj = d->dataList.at(i: ii);
177 QQuickPackageAttached *a = QQuickPackageAttached::attached.value(key: obj);
178 if (a && a->name() == name)
179 return true;
180 }
181 return false;
182}
183
184QObject *QQuickPackage::part(const QString &name)
185{
186 Q_D(QQuickPackage);
187 if (name.isEmpty() && !d->dataList.isEmpty())
188 return d->dataList.at(i: 0);
189
190 for (int ii = 0; ii < d->dataList.count(); ++ii) {
191 QObject *obj = d->dataList.at(i: ii);
192 QQuickPackageAttached *a = QQuickPackageAttached::attached.value(key: obj);
193 if (a && a->name() == name)
194 return obj;
195 }
196
197 if (name == QLatin1String("default") && !d->dataList.isEmpty())
198 return d->dataList.at(i: 0);
199
200 return nullptr;
201}
202
203QQuickPackageAttached *QQuickPackage::qmlAttachedProperties(QObject *o)
204{
205 return new QQuickPackageAttached(o);
206}
207
208
209
210QT_END_NAMESPACE
211
212#include "moc_qquickpackage_p.cpp"
213

source code of qtdeclarative/src/qmlmodels/qquickpackage.cpp