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 = p?p->rawMetaObjectForType(listType):QQmlMetaType::qmlType(listType)->baseMetaObject();
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().
117 Constructs an invalid instance.
119 QQmlListReference::QQmlListReference()
125 Constructs a QQmlListReference for \a object's \a property. If \a property is not a list
126 property, an invalid QQmlListReference is created. If \a object is destroyed after
127 the reference is constructed, it will automatically become invalid. That is, it is safe to hold
128 QQmlListReference instances even after \a object is deleted.
130 Passing \a engine is required to access some QML created list properties. If in doubt, and an engine
131 is available, pass it.
133 QQmlListReference::QQmlListReference(QObject *object, const char *property, QQmlEngine *engine)
136 if (!object || !property) return;
138 QQmlPropertyData local;
139 QQmlPropertyData *data =
140 QQmlPropertyCache::property(engine, object, QLatin1String(property), local);
142 if (!data || !data->isQList()) return;
144 QQmlEnginePrivate *p = engine?QQmlEnginePrivate::get(engine):0;
146 int listType = p?p->listType(data->propType):QQmlMetaType::listType(data->propType);
147 if (listType == -1) return;
149 d = new QQmlListReferencePrivate;
151 d->elementType = p?p->rawMetaObjectForType(listType):QQmlMetaType::qmlType(listType)->baseMetaObject();
152 d->propertyType = data->propType;
154 void *args[] = { &d->property, 0 };
155 QMetaObject::metacall(object, QMetaObject::ReadProperty, data->coreIndex, args);
159 QQmlListReference::QQmlListReference(const QQmlListReference &o)
166 QQmlListReference &QQmlListReference::operator=(const QQmlListReference &o)
168 if (o.d) o.d->addref();
175 QQmlListReference::~QQmlListReference()
181 Returns true if the instance refers to a valid list property, otherwise false.
183 bool QQmlListReference::isValid() const
185 return d && d->object;
189 Returns the list property's object. Returns 0 if the reference is invalid.
191 QObject *QQmlListReference::object() const
193 if (isValid()) return d->object;
198 Returns the QMetaObject for the elements stored in the list property. Returns 0 if the reference
201 The QMetaObject can be used ahead of time to determine whether a given instance can be added
204 const QMetaObject *QQmlListReference::listElementType() const
206 if (isValid()) return d->elementType;
211 Returns true if the list property can be appended to, otherwise false. Returns false if the
212 reference is invalid.
216 bool QQmlListReference::canAppend() const
218 return (isValid() && d->property.append);
222 Returns true if the list property can queried by index, otherwise false. Returns false if the
223 reference is invalid.
227 bool QQmlListReference::canAt() const
229 return (isValid() && d->property.at);
233 Returns true if the list property can be cleared, otherwise false. Returns false if the
234 reference is invalid.
238 bool QQmlListReference::canClear() const
240 return (isValid() && d->property.clear);
244 Returns true if the list property can be queried for its element count, otherwise false.
245 Returns false if the reference is invalid.
249 bool QQmlListReference::canCount() const
251 return (isValid() && d->property.count);
255 Appends \a object to the list. Returns true if the operation succeeded, otherwise false.
259 bool QQmlListReference::append(QObject *object) const
261 if (!canAppend()) return false;
263 if (object && !QQmlPropertyPrivate::canConvert(object->metaObject(), d->elementType))
266 d->property.append(&d->property, object);
272 Returns the list element at \a index, or 0 if the operation failed.
276 QObject *QQmlListReference::at(int index) const
278 if (!canAt()) return 0;
280 return d->property.at(&d->property, index);
284 Clears the list. Returns true if the operation succeeded, otherwise false.
288 bool QQmlListReference::clear() const
290 if (!canClear()) return false;
292 d->property.clear(&d->property);
298 Returns the number of objects in the list, or 0 if the operation failed.
300 int QQmlListReference::count() const
302 if (!canCount()) return 0;
304 return d->property.count(&d->property);
308 \class QQmlListProperty
310 \brief The QQmlListProperty class allows applications to expose list-like
313 QML has many list properties, where more than one object value can be assigned.
314 The use of a list property from QML looks like this:
326 The QQmlListProperty encapsulates a group of function pointers that represet the
327 set of actions QML can perform on the list - adding items, retrieving items and
328 clearing the list. In the future, additional operations may be supported. All
329 list properties must implement the append operation, but the rest are optional.
331 To provide a list property, a C++ class must implement the operation callbacks,
332 and then return an appropriate QQmlListProperty value from the property getter.
333 List properties should have no setter. In the example above, the Q_PROPERTY()
334 declarative will look like this:
337 Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit);
340 QML list properties are typesafe - in this case \c {Fruit} is a QObject type that
341 \c {Apple}, \c {Orange} and \c {Banana} all derive from.
343 \note QQmlListProperty can only be used for lists of QObject-derived object pointers.
345 \sa {Object and List Property Types}
350 \fn QQmlListProperty::QQmlListProperty()
355 \fn QQmlListProperty::QQmlListProperty(QObject *object, QList<T *> &list)
357 Convenience constructor for making a QQmlListProperty value from an existing
358 QList \a list. The \a list reference must remain valid for as long as \a object
359 exists. \a object must be provided.
361 Generally this constructor should not be used in production code, as a
362 writable QList violates QML's memory management rules. However, this constructor
363 can very useful while prototyping.
367 \fn QQmlListProperty::QQmlListProperty(QObject *object, void *data, AppendFunction append,
368 CountFunction count = 0, AtFunction at = 0,
369 ClearFunction clear = 0)
371 Construct a QQmlListProperty from a set of operation functions. An opaque \a data handle
372 may be passed which can be accessed from within the operation functions. The list property
373 remains valid while \a object exists.
375 The \a append operation is compulsory and must be provided, while the \a count, \a at and
376 \a clear methods are optional.
380 \typedef QQmlListProperty::AppendFunction
382 Synonym for \c {void (*)(QQmlListProperty<T> *property, T *value)}.
384 Append the \a value to the list \a property.
388 \typedef QQmlListProperty::CountFunction
390 Synonym for \c {int (*)(QQmlListProperty<T> *property)}.
392 Return the number of elements in the list \a property.
396 \fn bool QQmlListProperty::operator==(const QQmlListProperty &other) const
398 Returns true if this QQmlListProperty is equal to \a other, otherwise false.
402 \typedef QQmlListProperty::AtFunction
404 Synonym for \c {T *(*)(QQmlListProperty<T> *property, int index)}.
406 Return the element at position \a index in the list \a property.
410 \typedef QQmlListProperty::ClearFunction
412 Synonym for \c {void (*)(QQmlListProperty<T> *property)}.
414 Clear the list \a property.