1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickpackage_p.h"
44 #include <private/qobject_p.h>
45 #include <private/qqmlguard_p.h>
50 \qmlclass Package QQuickPackage
51 \inqmlmodule QtQuick 2
52 \ingroup qml-working-with-data
53 \brief Package provides a collection of named items.
55 The Package class is used in conjunction with
56 VisualDataModel to enable delegates with a shared context
57 to be provided to multiple views.
59 Any item within a Package may be assigned a name via the
60 \l{Package::name}{Package.name} attached property.
62 The example below creates a Package containing two named items;
63 \e list and \e grid. The third element in the package (the \l Rectangle) is parented to whichever
64 delegate it should appear in. This allows an item to move
67 \snippet examples/declarative/modelviews/package/Delegate.qml 0
69 These named items are used as the delegates by the two views who
70 reference the special \l{VisualDataModel::parts} property to select
71 a model which provides the chosen delegate.
73 \snippet examples/declarative/modelviews/package/view.qml 0
75 \sa {declarative/modelviews/package}{Package example}, {declarative/photoviewer}{Photo Viewer example}, QtQml
79 \qmlattachedproperty string QtQuick2::Package::name
80 This attached property holds the name of an item within a Package.
84 class QQuickPackagePrivate : public QObjectPrivate
87 QQuickPackagePrivate() {}
89 struct DataGuard : public QQmlGuard<QObject>
91 DataGuard(QObject *obj, QList<DataGuard> *l) : list(l) { (QQmlGuard<QObject>&)*this = obj; }
92 QList<DataGuard> *list;
93 void objectDestroyed(QObject *) {
94 // we assume priv will always be destroyed after objectDestroyed calls
95 list->removeOne(*this);
99 QList<DataGuard> dataList;
100 static void data_append(QQmlListProperty<QObject> *prop, QObject *o) {
101 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
102 list->append(DataGuard(o, list));
104 static void data_clear(QQmlListProperty<QObject> *prop) {
105 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
108 static QObject *data_at(QQmlListProperty<QObject> *prop, int index) {
109 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
110 return list->at(index);
112 static int data_count(QQmlListProperty<QObject> *prop) {
113 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
114 return list->count();
118 QHash<QObject *, QQuickPackageAttached *> QQuickPackageAttached::attached;
120 QQuickPackageAttached::QQuickPackageAttached(QObject *parent)
123 attached.insert(parent, this);
126 QQuickPackageAttached::~QQuickPackageAttached()
128 attached.remove(parent());
131 QString QQuickPackageAttached::name() const
136 void QQuickPackageAttached::setName(const QString &n)
141 QQuickPackage::QQuickPackage(QObject *parent)
142 : QObject(*(new QQuickPackagePrivate), parent)
146 QQuickPackage::~QQuickPackage()
149 for (int ii = 0; ii < d->dataList.count(); ++ii) {
150 QObject *obj = d->dataList.at(ii);
151 obj->setParent(this);
155 QQmlListProperty<QObject> QQuickPackage::data()
158 return QQmlListProperty<QObject>(this, &d->dataList, QQuickPackagePrivate::data_append,
159 QQuickPackagePrivate::data_count,
160 QQuickPackagePrivate::data_at,
161 QQuickPackagePrivate::data_clear);
164 bool QQuickPackage::hasPart(const QString &name)
167 for (int ii = 0; ii < d->dataList.count(); ++ii) {
168 QObject *obj = d->dataList.at(ii);
169 QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj);
170 if (a && a->name() == name)
176 QObject *QQuickPackage::part(const QString &name)
179 if (name.isEmpty() && !d->dataList.isEmpty())
180 return d->dataList.at(0);
182 for (int ii = 0; ii < d->dataList.count(); ++ii) {
183 QObject *obj = d->dataList.at(ii);
184 QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj);
185 if (a && a->name() == name)
189 if (name == QLatin1String("default") && !d->dataList.isEmpty())
190 return d->dataList.at(0);
195 QQuickPackageAttached *QQuickPackage::qmlAttachedProperties(QObject *o)
197 return new QQuickPackageAttached(o);