1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qdeclarativepackage_p.h"
44 #include <private/qobject_p.h>
45 #include <private/qdeclarativeguard_p.h>
50 \qmlclass Package QDeclarativePackage
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}, QtDeclarative
79 \qmlattachedproperty string QtQuick2::Package::name
80 This attached property holds the name of an item within a Package.
84 class QDeclarativePackagePrivate : public QObjectPrivate
87 QDeclarativePackagePrivate() {}
89 struct DataGuard : public QDeclarativeGuard<QObject>
91 DataGuard(QObject *obj, QList<DataGuard> *l) : list(l) { (QDeclarativeGuard<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(QDeclarativeListProperty<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(QDeclarativeListProperty<QObject> *prop) {
105 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
108 static QObject *data_at(QDeclarativeListProperty<QObject> *prop, int index) {
109 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
110 return list->at(index);
112 static int data_count(QDeclarativeListProperty<QObject> *prop) {
113 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
114 return list->count();
118 QHash<QObject *, QDeclarativePackageAttached *> QDeclarativePackageAttached::attached;
120 QDeclarativePackageAttached::QDeclarativePackageAttached(QObject *parent)
123 attached.insert(parent, this);
126 QDeclarativePackageAttached::~QDeclarativePackageAttached()
128 attached.remove(parent());
131 QString QDeclarativePackageAttached::name() const
136 void QDeclarativePackageAttached::setName(const QString &n)
141 QDeclarativePackage::QDeclarativePackage(QObject *parent)
142 : QObject(*(new QDeclarativePackagePrivate), parent)
146 QDeclarativePackage::~QDeclarativePackage()
148 Q_D(QDeclarativePackage);
149 for (int ii = 0; ii < d->dataList.count(); ++ii) {
150 QObject *obj = d->dataList.at(ii);
151 obj->setParent(this);
155 QDeclarativeListProperty<QObject> QDeclarativePackage::data()
157 Q_D(QDeclarativePackage);
158 return QDeclarativeListProperty<QObject>(this, &d->dataList, QDeclarativePackagePrivate::data_append,
159 QDeclarativePackagePrivate::data_count,
160 QDeclarativePackagePrivate::data_at,
161 QDeclarativePackagePrivate::data_clear);
164 bool QDeclarativePackage::hasPart(const QString &name)
166 Q_D(QDeclarativePackage);
167 for (int ii = 0; ii < d->dataList.count(); ++ii) {
168 QObject *obj = d->dataList.at(ii);
169 QDeclarativePackageAttached *a = QDeclarativePackageAttached::attached.value(obj);
170 if (a && a->name() == name)
176 QObject *QDeclarativePackage::part(const QString &name)
178 Q_D(QDeclarativePackage);
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 QDeclarativePackageAttached *a = QDeclarativePackageAttached::attached.value(obj);
185 if (a && a->name() == name)
189 if (name == QLatin1String("default") && !d->dataList.isEmpty())
190 return d->dataList.at(0);
195 QDeclarativePackageAttached *QDeclarativePackage::qmlAttachedProperties(QObject *o)
197 return new QDeclarativePackageAttached(o);