1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "private/qdeclarativepackage_p.h"
44 #include <private/qobject_p.h>
45 #include <private/qdeclarativeguard_p.h>
50 \qmlclass Package QDeclarativePackage
51 \ingroup qml-working-with-data
52 \brief Package provides a collection of named items.
54 The Package class is used in conjunction with
55 VisualDataModel to enable delegates with a shared context
56 to be provided to multiple views.
58 Any item within a Package may be assigned a name via the
59 \l{Package::name}{Package.name} attached property.
61 The example below creates a Package containing two named items;
62 \e list and \e grid. The third element in the package (the \l Rectangle) is parented to whichever
63 delegate it should appear in. This allows an item to move
66 \snippet examples/declarative/modelviews/package/Delegate.qml 0
68 These named items are used as the delegates by the two views who
69 reference the special \l{VisualDataModel::parts} property to select
70 a model which provides the chosen delegate.
72 \snippet examples/declarative/modelviews/package/view.qml 0
74 \sa {declarative/modelviews/package}{Package example}, {demos/declarative/photoviewer}{Photo Viewer demo}, QtDeclarative
78 \qmlattachedproperty string Package::name
79 This attached property holds the name of an item within a Package.
83 class QDeclarativePackagePrivate : public QObjectPrivate
86 QDeclarativePackagePrivate() {}
88 struct DataGuard : public QDeclarativeGuard<QObject>
90 DataGuard(QObject *obj, QList<DataGuard> *l) : list(l) { (QDeclarativeGuard<QObject>&)*this = obj; }
91 QList<DataGuard> *list;
92 void objectDestroyed(QObject *) {
93 // we assume priv will always be destroyed after objectDestroyed calls
94 list->removeOne(*this);
98 QList<DataGuard> dataList;
99 static void data_append(QDeclarativeListProperty<QObject> *prop, QObject *o) {
100 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
101 list->append(DataGuard(o, list));
103 static void data_clear(QDeclarativeListProperty<QObject> *prop) {
104 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
107 static QObject *data_at(QDeclarativeListProperty<QObject> *prop, int index) {
108 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
109 return list->at(index);
111 static int data_count(QDeclarativeListProperty<QObject> *prop) {
112 QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
113 return list->count();
117 QHash<QObject *, QDeclarativePackageAttached *> QDeclarativePackageAttached::attached;
119 QDeclarativePackageAttached::QDeclarativePackageAttached(QObject *parent)
122 attached.insert(parent, this);
125 QDeclarativePackageAttached::~QDeclarativePackageAttached()
127 attached.remove(parent());
130 QString QDeclarativePackageAttached::name() const
135 void QDeclarativePackageAttached::setName(const QString &n)
140 QDeclarativePackage::QDeclarativePackage(QObject *parent)
141 : QObject(*(new QDeclarativePackagePrivate), parent)
145 QDeclarativePackage::~QDeclarativePackage()
147 Q_D(QDeclarativePackage);
148 for (int ii = 0; ii < d->dataList.count(); ++ii) {
149 QObject *obj = d->dataList.at(ii);
150 obj->setParent(this);
154 QDeclarativeListProperty<QObject> QDeclarativePackage::data()
156 Q_D(QDeclarativePackage);
157 return QDeclarativeListProperty<QObject>(this, &d->dataList, QDeclarativePackagePrivate::data_append,
158 QDeclarativePackagePrivate::data_count,
159 QDeclarativePackagePrivate::data_at,
160 QDeclarativePackagePrivate::data_clear);
163 bool QDeclarativePackage::hasPart(const QString &name)
165 Q_D(QDeclarativePackage);
166 for (int ii = 0; ii < d->dataList.count(); ++ii) {
167 QObject *obj = d->dataList.at(ii);
168 QDeclarativePackageAttached *a = QDeclarativePackageAttached::attached.value(obj);
169 if (a && a->name() == name)
175 QObject *QDeclarativePackage::part(const QString &name)
177 Q_D(QDeclarativePackage);
178 if (name.isEmpty() && !d->dataList.isEmpty())
179 return d->dataList.at(0);
181 for (int ii = 0; ii < d->dataList.count(); ++ii) {
182 QObject *obj = d->dataList.at(ii);
183 QDeclarativePackageAttached *a = QDeclarativePackageAttached::attached.value(obj);
184 if (a && a->name() == name)
188 if (name == QLatin1String("default") && !d->dataList.isEmpty())
189 return d->dataList.at(0);
194 QDeclarativePackageAttached *QDeclarativePackage::qmlAttachedProperties(QObject *o)
196 return new QDeclarativePackageAttached(o);