aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmllist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmllist.cpp')
-rw-r--r--src/qml/qml/qqmllist.cpp417
1 files changed, 417 insertions, 0 deletions
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
new file mode 100644
index 0000000000..00fd805ee0
--- /dev/null
+++ b/src/qml/qml/qqmllist.cpp
@@ -0,0 +1,417 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmllist.h"
+#include "qqmllist_p.h"
+#include "qqmlengine_p.h"
+#include "qqmlproperty_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QQmlListReferencePrivate::QQmlListReferencePrivate()
+: propertyType(-1), refCount(1)
+{
+}
+
+QQmlListReference QQmlListReferencePrivate::init(const QQmlListProperty<QObject> &prop, int propType, QQmlEngine *engine)
+{
+ QQmlListReference rv;
+
+ if (!prop.object) return rv;
+
+ QQmlEnginePrivate *p = engine?QQmlEnginePrivate::get(engine):0;
+
+ int listType = p?p->listType(propType):QQmlMetaType::listType(propType);
+ if (listType == -1) return rv;
+
+ rv.d = new QQmlListReferencePrivate;
+ rv.d->object = prop.object;
+ rv.d->elementType = p?p->rawMetaObjectForType(listType):QQmlMetaType::qmlType(listType)->baseMetaObject();
+ rv.d->property = prop;
+ rv.d->propertyType = propType;
+
+ return rv;
+}
+
+void QQmlListReferencePrivate::addref()
+{
+ Q_ASSERT(refCount > 0);
+ ++refCount;
+}
+
+void QQmlListReferencePrivate::release()
+{
+ Q_ASSERT(refCount > 0);
+ --refCount;
+ if (!refCount)
+ delete this;
+}
+
+/*!
+\class QQmlListReference
+\since 4.7
+\module QtQml
+\brief The QQmlListReference class allows the manipulation of QQmlListProperty properties.
+
+QQmlListReference allows C++ programs to read from, and assign values to a QML list property in a
+simple and type safe way. A QQmlListReference can be created by passing an object and property
+name or through a QQmlProperty instance. These two are equivalant:
+
+\code
+QQmlListReference ref1(object, "children");
+
+QQmlProperty ref2(object, "children");
+QQmlListReference ref2 = qvariant_cast<QQmlListReference>(ref2.read());
+\endcode
+
+Not all QML list properties support all operations. A set of methods, canAppend(), canAt(), canClear() and
+canCount() allow programs to query whether an operation is supported on a given property.
+
+QML list properties are typesafe. Only QObject's that derive from the correct base class can be assigned to
+the list. The listElementType() method can be used to query the QMetaObject of the QObject type supported.
+Attempting to add objects of the incorrect type to a list property will fail.
+
+Like with normal lists, when accessing a list element by index, it is the callers responsibility to ensure
+that it does not request an out of range element using the count() method before calling at().
+*/
+
+/*!
+Constructs an invalid instance.
+*/
+QQmlListReference::QQmlListReference()
+: d(0)
+{
+}
+
+/*!
+Constructs a QQmlListReference for \a object's \a property. If \a property is not a list
+property, an invalid QQmlListReference is created. If \a object is destroyed after
+the reference is constructed, it will automatically become invalid. That is, it is safe to hold
+QQmlListReference instances even after \a object is deleted.
+
+Passing \a engine is required to access some QML created list properties. If in doubt, and an engine
+is available, pass it.
+*/
+QQmlListReference::QQmlListReference(QObject *object, const char *property, QQmlEngine *engine)
+: d(0)
+{
+ if (!object || !property) return;
+
+ QQmlPropertyData local;
+ QQmlPropertyData *data =
+ QQmlPropertyCache::property(engine, object, QLatin1String(property), local);
+
+ if (!data || !data->isQList()) return;
+
+ QQmlEnginePrivate *p = engine?QQmlEnginePrivate::get(engine):0;
+
+ int listType = p?p->listType(data->propType):QQmlMetaType::listType(data->propType);
+ if (listType == -1) return;
+
+ d = new QQmlListReferencePrivate;
+ d->object = object;
+ d->elementType = p?p->rawMetaObjectForType(listType):QQmlMetaType::qmlType(listType)->baseMetaObject();
+ d->propertyType = data->propType;
+
+ void *args[] = { &d->property, 0 };
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, data->coreIndex, args);
+}
+
+/*! \internal */
+QQmlListReference::QQmlListReference(const QQmlListReference &o)
+: d(o.d)
+{
+ if (d) d->addref();
+}
+
+/*! \internal */
+QQmlListReference &QQmlListReference::operator=(const QQmlListReference &o)
+{
+ if (o.d) o.d->addref();
+ if (d) d->release();
+ d = o.d;
+ return *this;
+}
+
+/*! \internal */
+QQmlListReference::~QQmlListReference()
+{
+ if (d) d->release();
+}
+
+/*!
+Returns true if the instance refers to a valid list property, otherwise false.
+*/
+bool QQmlListReference::isValid() const
+{
+ return d && d->object;
+}
+
+/*!
+Returns the list property's object. Returns 0 if the reference is invalid.
+*/
+QObject *QQmlListReference::object() const
+{
+ if (isValid()) return d->object;
+ else return 0;
+}
+
+/*!
+Returns the QMetaObject for the elements stored in the list property. Returns 0 if the reference
+is invalid.
+
+The QMetaObject can be used ahead of time to determine whether a given instance can be added
+to a list.
+*/
+const QMetaObject *QQmlListReference::listElementType() const
+{
+ if (isValid()) return d->elementType;
+ else return 0;
+}
+
+/*!
+Returns true if the list property can be appended to, otherwise false. Returns false if the
+reference is invalid.
+
+\sa append()
+*/
+bool QQmlListReference::canAppend() const
+{
+ return (isValid() && d->property.append);
+}
+
+/*!
+Returns true if the list property can queried by index, otherwise false. Returns false if the
+reference is invalid.
+
+\sa at()
+*/
+bool QQmlListReference::canAt() const
+{
+ return (isValid() && d->property.at);
+}
+
+/*!
+Returns true if the list property can be cleared, otherwise false. Returns false if the
+reference is invalid.
+
+\sa clear()
+*/
+bool QQmlListReference::canClear() const
+{
+ return (isValid() && d->property.clear);
+}
+
+/*!
+Returns true if the list property can be queried for its element count, otherwise false.
+Returns false if the reference is invalid.
+
+\sa count()
+*/
+bool QQmlListReference::canCount() const
+{
+ return (isValid() && d->property.count);
+}
+
+/*!
+Appends \a object to the list. Returns true if the operation succeeded, otherwise false.
+
+\sa canAppend()
+*/
+bool QQmlListReference::append(QObject *object) const
+{
+ if (!canAppend()) return false;
+
+ if (object && !QQmlPropertyPrivate::canConvert(object->metaObject(), d->elementType))
+ return false;
+
+ d->property.append(&d->property, object);
+
+ return true;
+}
+
+/*!
+Returns the list element at \a index, or 0 if the operation failed.
+
+\sa canAt()
+*/
+QObject *QQmlListReference::at(int index) const
+{
+ if (!canAt()) return 0;
+
+ return d->property.at(&d->property, index);
+}
+
+/*!
+Clears the list. Returns true if the operation succeeded, otherwise false.
+
+\sa canClear()
+*/
+bool QQmlListReference::clear() const
+{
+ if (!canClear()) return false;
+
+ d->property.clear(&d->property);
+
+ return true;
+}
+
+/*!
+Returns the number of objects in the list, or 0 if the operation failed.
+*/
+int QQmlListReference::count() const
+{
+ if (!canCount()) return 0;
+
+ return d->property.count(&d->property);
+}
+
+/*!
+\class QQmlListProperty
+\since 4.7
+\brief The QQmlListProperty class allows applications to expose list-like
+properties to QML.
+
+QML has many list properties, where more than one object value can be assigned.
+The use of a list property from QML looks like this:
+
+\code
+FruitBasket {
+ fruit: [
+ Apple {},
+ Orange{},
+ Banana{}
+ ]
+}
+\endcode
+
+The QQmlListProperty encapsulates a group of function pointers that represet the
+set of actions QML can perform on the list - adding items, retrieving items and
+clearing the list. In the future, additional operations may be supported. All
+list properties must implement the append operation, but the rest are optional.
+
+To provide a list property, a C++ class must implement the operation callbacks,
+and then return an appropriate QQmlListProperty value from the property getter.
+List properties should have no setter. In the example above, the Q_PROPERTY()
+declarative will look like this:
+
+\code
+Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit);
+\endcode
+
+QML list properties are typesafe - in this case \c {Fruit} is a QObject type that
+\c {Apple}, \c {Orange} and \c {Banana} all derive from.
+
+\note QQmlListProperty can only be used for lists of QObject-derived object pointers.
+
+\sa {Object and List Property Types}
+
+*/
+
+/*!
+\fn QQmlListProperty::QQmlListProperty()
+\internal
+*/
+
+/*!
+\fn QQmlListProperty::QQmlListProperty(QObject *object, QList<T *> &list)
+
+Convenience constructor for making a QQmlListProperty value from an existing
+QList \a list. The \a list reference must remain valid for as long as \a object
+exists. \a object must be provided.
+
+Generally this constructor should not be used in production code, as a
+writable QList violates QML's memory management rules. However, this constructor
+can very useful while prototyping.
+*/
+
+/*!
+\fn QQmlListProperty::QQmlListProperty(QObject *object, void *data, AppendFunction append,
+ CountFunction count = 0, AtFunction at = 0,
+ ClearFunction clear = 0)
+
+Construct a QQmlListProperty from a set of operation functions. An opaque \a data handle
+may be passed which can be accessed from within the operation functions. The list property
+remains valid while \a object exists.
+
+The \a append operation is compulsory and must be provided, while the \a count, \a at and
+\a clear methods are optional.
+*/
+
+/*!
+\typedef QQmlListProperty::AppendFunction
+
+Synonym for \c {void (*)(QQmlListProperty<T> *property, T *value)}.
+
+Append the \a value to the list \a property.
+*/
+
+/*!
+\typedef QQmlListProperty::CountFunction
+
+Synonym for \c {int (*)(QQmlListProperty<T> *property)}.
+
+Return the number of elements in the list \a property.
+*/
+
+/*!
+\fn bool QQmlListProperty::operator==(const QQmlListProperty &other) const
+
+Returns true if this QQmlListProperty is equal to \a other, otherwise false.
+*/
+
+/*!
+\typedef QQmlListProperty::AtFunction
+
+Synonym for \c {T *(*)(QQmlListProperty<T> *property, int index)}.
+
+Return the element at position \a index in the list \a property.
+*/
+
+/*!
+\typedef QQmlListProperty::ClearFunction
+
+Synonym for \c {void (*)(QQmlListProperty<T> *property)}.
+
+Clear the list \a property.
+*/
+
+QT_END_NAMESPACE