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 ****************************************************************************/
43 #include "qqmllist_p.h"
44 #include "qqmlengine_p.h"
45 #include "qqmlproperty_p.h"
49 QQmlListReferencePrivate::QQmlListReferencePrivate()
50 : propertyType(-1), refCount(1)
54 QQmlListReference QQmlListReferencePrivate::init(const QQmlListProperty<QObject> &prop, int propType, QQmlEngine *engine)
58 if (!prop.object) return rv;
60 QQmlEnginePrivate *p = engine?QQmlEnginePrivate::get(engine):0;
62 int listType = p?p->listType(propType):QQmlMetaType::listType(propType);
63 if (listType == -1) return rv;
65 rv.d = new QQmlListReferencePrivate;
66 rv.d->object = prop.object;
67 rv.d->elementType = QQmlPropertyPrivate::rawMetaObjectForType(p, listType);
68 rv.d->property = prop;
69 rv.d->propertyType = propType;
74 void QQmlListReferencePrivate::addref()
76 Q_ASSERT(refCount > 0);
80 void QQmlListReferencePrivate::release()
82 Q_ASSERT(refCount > 0);
89 \class QQmlListReference
92 \brief The QQmlListReference class allows the manipulation of QQmlListProperty properties.
94 QQmlListReference allows C++ programs to read from, and assign values to a QML list property in a
95 simple and type safe way. A QQmlListReference can be created by passing an object and property
96 name or through a QQmlProperty instance. These two are equivalant:
99 QQmlListReference ref1(object, "children");
101 QQmlProperty ref2(object, "children");
102 QQmlListReference ref2 = qvariant_cast<QQmlListReference>(ref2.read());
105 Not all QML list properties support all operations. A set of methods, canAppend(), canAt(), canClear() and
106 canCount() allow programs to query whether an operation is supported on a given property.
108 QML list properties are typesafe. Only QObject's that derive from the correct base class can be assigned to
109 the list. The listElementType() method can be used to query the QMetaObject of the QObject type supported.
110 Attempting to add objects of the incorrect type to a list property will fail.
112 Like with normal lists, when accessing a list element by index, it is the callers responsibility to ensure
113 that it does not request an out of range element using the count() method before calling at().
115 The QtQuick 1 version of this class is named QDeclarativeListReference.
119 Constructs an invalid instance.
121 QQmlListReference::QQmlListReference()
127 Constructs a QQmlListReference for \a object's \a property. If \a property is not a list
128 property, an invalid QQmlListReference is created. If \a object is destroyed after
129 the reference is constructed, it will automatically become invalid. That is, it is safe to hold
130 QQmlListReference instances even after \a object is deleted.
132 Passing \a engine is required to access some QML created list properties. If in doubt, and an engine
133 is available, pass it.
135 QQmlListReference::QQmlListReference(QObject *object, const char *property, QQmlEngine *engine)
138 if (!object || !property) return;
140 QQmlPropertyData local;
141 QQmlPropertyData *data =
142 QQmlPropertyCache::property(engine, object, QLatin1String(property), local);
144 if (!data || !data->isQList()) return;
146 QQmlEnginePrivate *p = engine?QQmlEnginePrivate::get(engine):0;
148 int listType = p?p->listType(data->propType):QQmlMetaType::listType(data->propType);
149 if (listType == -1) return;
151 d = new QQmlListReferencePrivate;
153 d->elementType = p?p->rawMetaObjectForType(listType):QQmlMetaType::qmlType(listType)->baseMetaObject();
154 d->propertyType = data->propType;
156 void *args[] = { &d->property, 0 };
157 QMetaObject::metacall(object, QMetaObject::ReadProperty, data->coreIndex, args);
161 QQmlListReference::QQmlListReference(const QQmlListReference &o)
168 QQmlListReference &QQmlListReference::operator=(const QQmlListReference &o)
170 if (o.d) o.d->addref();
177 QQmlListReference::~QQmlListReference()
183 Returns true if the instance refers to a valid list property, otherwise false.
185 bool QQmlListReference::isValid() const
187 return d && d->object;
191 Returns the list property's object. Returns 0 if the reference is invalid.
193 QObject *QQmlListReference::object() const
195 if (isValid()) return d->object;
200 Returns the QMetaObject for the elements stored in the list property. Returns 0 if the reference
203 The QMetaObject can be used ahead of time to determine whether a given instance can be added
206 const QMetaObject *QQmlListReference::listElementType() const
208 if (isValid()) return d->elementType.metaObject();
213 Returns true if the list property can be appended to, otherwise false. Returns false if the
214 reference is invalid.
218 bool QQmlListReference::canAppend() const
220 return (isValid() && d->property.append);
224 Returns true if the list property can queried by index, otherwise false. Returns false if the
225 reference is invalid.
229 bool QQmlListReference::canAt() const
231 return (isValid() && d->property.at);
235 Returns true if the list property can be cleared, otherwise false. Returns false if the
236 reference is invalid.
240 bool QQmlListReference::canClear() const
242 return (isValid() && d->property.clear);
246 Returns true if the list property can be queried for its element count, otherwise false.
247 Returns false if the reference is invalid.
251 bool QQmlListReference::canCount() const
253 return (isValid() && d->property.count);
257 Appends \a object to the list. Returns true if the operation succeeded, otherwise false.
261 bool QQmlListReference::append(QObject *object) const
263 if (!canAppend()) return false;
265 if (object && !QQmlMetaObject::canConvert(object, d->elementType))
268 d->property.append(&d->property, object);
274 Returns the list element at \a index, or 0 if the operation failed.
278 QObject *QQmlListReference::at(int index) const
280 if (!canAt()) return 0;
282 return d->property.at(&d->property, index);
286 Clears the list. Returns true if the operation succeeded, otherwise false.
290 bool QQmlListReference::clear() const
292 if (!canClear()) return false;
294 d->property.clear(&d->property);
300 Returns the number of objects in the list, or 0 if the operation failed.
302 int QQmlListReference::count() const
304 if (!canCount()) return 0;
306 return d->property.count(&d->property);
310 \class QQmlListProperty
313 \brief The QQmlListProperty class allows applications to expose list-like
316 QML has many list properties, where more than one object value can be assigned.
317 The use of a list property from QML looks like this:
329 The QQmlListProperty encapsulates a group of function pointers that represet the
330 set of actions QML can perform on the list - adding items, retrieving items and
331 clearing the list. In the future, additional operations may be supported. All
332 list properties must implement the append operation, but the rest are optional.
334 To provide a list property, a C++ class must implement the operation callbacks,
335 and then return an appropriate QQmlListProperty value from the property getter.
336 List properties should have no setter. In the example above, the Q_PROPERTY()
337 declarative will look like this:
340 Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit);
343 QML list properties are typesafe - in this case \c {Fruit} is a QObject type that
344 \c {Apple}, \c {Orange} and \c {Banana} all derive from.
346 The QtQuick 1 version of this class is named QDeclarativeListProperty.
348 \note QQmlListProperty can only be used for lists of QObject-derived object pointers.
352 \fn QQmlListProperty::QQmlListProperty()
357 \fn QQmlListProperty::QQmlListProperty(QObject *object, QList<T *> &list)
359 Convenience constructor for making a QQmlListProperty value from an existing
360 QList \a list. The \a list reference must remain valid for as long as \a object
361 exists. \a object must be provided.
363 Generally this constructor should not be used in production code, as a
364 writable QList violates QML's memory management rules. However, this constructor
365 can very useful while prototyping.
369 \fn QQmlListProperty::QQmlListProperty(QObject *object, void *data, AppendFunction append,
370 CountFunction count = 0, AtFunction at = 0,
371 ClearFunction clear = 0)
373 Construct a QQmlListProperty from a set of operation functions. An opaque \a data handle
374 may be passed which can be accessed from within the operation functions. The list property
375 remains valid while \a object exists.
377 The \a append operation is compulsory and must be provided, while the \a count, \a at and
378 \a clear methods are optional.
382 \typedef QQmlListProperty::AppendFunction
384 Synonym for \c {void (*)(QQmlListProperty<T> *property, T *value)}.
386 Append the \a value to the list \a property.
390 \typedef QQmlListProperty::CountFunction
392 Synonym for \c {int (*)(QQmlListProperty<T> *property)}.
394 Return the number of elements in the list \a property.
398 \fn bool QQmlListProperty::operator==(const QQmlListProperty &other) const
400 Returns true if this QQmlListProperty is equal to \a other, otherwise false.
404 \typedef QQmlListProperty::AtFunction
406 Synonym for \c {T *(*)(QQmlListProperty<T> *property, int index)}.
408 Return the element at position \a index in the list \a property.
412 \typedef QQmlListProperty::ClearFunction
414 Synonym for \c {void (*)(QQmlListProperty<T> *property)}.
416 Clear the list \a property.