aboutsummaryrefslogtreecommitdiffstats
path: root/src/qtquick1/util/qdeclarativelistmodel.cpp
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-01-31 16:52:36 +1000
committerQt by Nokia <qt-info@nokia.com>2012-02-03 00:39:18 +0100
commit01dc7e2ea476e0e6dcdce2e72979bbc858f4057d (patch)
treed8796f7695bbf8ad42abf47cd84c1b5e000ef795 /src/qtquick1/util/qdeclarativelistmodel.cpp
parent5e07b57b818326da47a46d384415041fa4cea0ba (diff)
Remove QtQuick1 elements from qtdeclarative
QtQuick1 is now contained in a separate repository. Task-number: QTBUG-23737 Change-Id: I09eae67af5693a22b896b916f816f73ccc3a89b1 Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/qtquick1/util/qdeclarativelistmodel.cpp')
-rw-r--r--src/qtquick1/util/qdeclarativelistmodel.cpp1634
1 files changed, 0 insertions, 1634 deletions
diff --git a/src/qtquick1/util/qdeclarativelistmodel.cpp b/src/qtquick1/util/qdeclarativelistmodel.cpp
deleted file mode 100644
index 12367364f6..0000000000
--- a/src/qtquick1/util/qdeclarativelistmodel.cpp
+++ /dev/null
@@ -1,1634 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtDeclarative 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 "QtQuick1/private/qdeclarativelistmodel_p_p.h"
-#include "QtQuick1/private/qdeclarativelistmodelworkeragent_p.h"
-#include "QtQuick1/private/qdeclarativeopenmetaobject_p.h"
-
-#include <QtDeclarative/private/qdeclarativecustomparser_p.h>
-#include <QtDeclarative/private/qdeclarativescript_p.h>
-#include <QtDeclarative/private/qdeclarativeengine_p.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeinfo.h>
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qstack.h>
-#include <QXmlStreamReader>
-#include <QtDeclarative/qscriptvalueiterator.h>
-
-Q_DECLARE_METATYPE(QListModelInterface *)
-
-QT_BEGIN_NAMESPACE
-
-
-
-template<typename T>
-void qdeclarativelistmodel_move(int from, int to, int n, T *items)
-{
- if (n == 1) {
- items->move(from, to);
- } else {
- T replaced;
- int i=0;
- typename T::ConstIterator it=items->begin(); it += from+n;
- for (; i<to-from; ++i,++it)
- replaced.append(*it);
- i=0;
- it=items->begin(); it += from;
- for (; i<n; ++i,++it)
- replaced.append(*it);
- typename T::ConstIterator f=replaced.begin();
- typename T::Iterator t=items->begin(); t += from;
- for (; f != replaced.end(); ++f, ++t)
- *t = *f;
- }
-}
-
-QDeclarative1ListModelParser::ListInstruction *QDeclarative1ListModelParser::ListModelData::instructions() const
-{
- return (QDeclarative1ListModelParser::ListInstruction *)((char *)this + sizeof(ListModelData));
-}
-
-/*!
- \qmlclass ListModel QDeclarative1ListModel
- \inqmlmodule QtQuick 1
- \ingroup qml-working-with-data
- \since QtQuick 1.0
- \brief The ListModel element defines a free-form list data source.
-
- The ListModel is a simple container of ListElement definitions, each containing data roles.
- The contents can be defined dynamically, or explicitly in QML.
-
- The number of elements in the model can be obtained from its \l count property.
- A number of familiar methods are also provided to manipulate the contents of the
- model, including append(), insert(), move(), remove() and set(). These methods
- accept dictionaries as their arguments; these are translated to ListElement objects
- by the model.
-
- Elements can be manipulated via the model using the setProperty() method, which
- allows the roles of the specified element to be set and changed.
-
- \section1 Example Usage
-
- The following example shows a ListModel containing three elements, with the roles
- "name" and "cost".
-
- \div {class="float-right"}
- \inlineimage listmodel.png
- \enddiv
-
- \snippet doc/src/snippets/qtquick1/listmodel.qml 0
-
- \clearfloat
- Roles (properties) in each element must begin with a lower-case letter and
- should be common to all elements in a model. The ListElement documentation
- provides more guidelines for how elements should be defined.
-
- Since the example model contains an \c id property, it can be referenced
- by views, such as the ListView in this example:
-
- \snippet doc/src/snippets/qtquick1/listmodel-simple.qml 0
- \dots 8
- \snippet doc/src/snippets/qtquick1/listmodel-simple.qml 1
-
- It is possible for roles to contain list data. In the following example we
- create a list of fruit attributes:
-
- \snippet doc/src/snippets/qtquick1/listmodel-nested.qml model
-
- The delegate displays all the fruit attributes:
-
- \div {class="float-right"}
- \inlineimage listmodel-nested.png
- \enddiv
-
- \snippet doc/src/snippets/qtquick1/listmodel-nested.qml delegate
-
- \clearfloat
- \section1 Modifying List Models
-
- The content of a ListModel may be created and modified using the clear(),
- append(), set(), insert() and setProperty() methods. For example:
-
- \snippet doc/src/snippets/qtquick1/listmodel-modify.qml delegate
-
- Note that when creating content dynamically the set of available properties
- cannot be changed once set. Whatever properties are first added to the model
- are the only permitted properties in the model.
-
- \section1 Using Threaded List Models with WorkerScript
-
- ListModel can be used together with WorkerScript access a list model
- from multiple threads. This is useful if list modifications are
- synchronous and take some time: the list operations can be moved to a
- different thread to avoid blocking of the main GUI thread.
-
- Here is an example that uses WorkerScript to periodically append the
- current time to a list model:
-
- \snippet examples/declarative/threading/threadedlistmodel/timedisplay.qml 0
-
- The included file, \tt dataloader.js, looks like this:
-
- \snippet examples/declarative/threading/threadedlistmodel/dataloader.js 0
-
- The timer in the main example sends messages to the worker script by calling
- \l WorkerScript::sendMessage(). When this message is received,
- \l{WorkerScript::onMessage}{WorkerScript.onMessage()} is invoked in \c dataloader.js,
- which appends the current time to the list model.
-
- Note the call to sync() from the \l{WorkerScript::onMessage}{WorkerScript.onMessage()}
- handler. You must call sync() or else the changes made to the list from the external
- thread will not be reflected in the list model in the main thread.
-
- \section1 Restrictions
-
- If a list model is to be accessed from a WorkerScript, it cannot
- contain list-type data. So, the following model cannot be used from a WorkerScript
- because of the list contained in the "attributes" property:
-
- \code
- ListModel {
- id: fruitModel
- ListElement {
- name: "Apple"
- cost: 2.45
- attributes: [
- ListElement { description: "Core" },
- ListElement { description: "Deciduous" }
- ]
- }
- }
- \endcode
-
- In addition, the WorkerScript cannot add list-type data to the model.
-
- \sa {qmlmodels}{Data Models}, {declarative/threading/threadedlistmodel}{Threaded ListModel example}, QtDeclarative
-*/
-
-
-/*
- A ListModel internally uses either a NestedListModel_1 or FlatListModel_1.
-
- A NestedListModel_1 can contain lists of ListElements (which
- when retrieved from get() is accessible as a list model within the list
- model) whereas a FlatListModel_1 cannot.
-
- ListModel uses a NestedListModel_1 to begin with, and if the model is later
- used from a WorkerScript, it changes to use a FlatListModel_1 instead. This
- is because ModelNode (which abstracts the nested list model data) needs
- access to the declarative engine and script engine, which cannot be
- safely used from outside of the main thread.
-*/
-
-QDeclarative1ListModel::QDeclarative1ListModel(QObject *parent)
-: QListModelInterface(parent), m_agent(0), m_nested(new NestedListModel_1(this)), m_flat(0)
-{
-}
-
-QDeclarative1ListModel::QDeclarative1ListModel(const QDeclarative1ListModel *orig, QDeclarative1ListModelWorkerAgent *parent)
-: QListModelInterface(parent), m_agent(0), m_nested(0), m_flat(0)
-{
- m_flat = new FlatListModel_1(this);
- m_flat->m_parentAgent = parent;
-
- if (orig->m_flat) {
- m_flat->m_roles = orig->m_flat->m_roles;
- m_flat->m_strings = orig->m_flat->m_strings;
- m_flat->m_values = orig->m_flat->m_values;
-
- m_flat->m_nodeData.reserve(m_flat->m_values.count());
- for (int i=0; i<m_flat->m_values.count(); i++)
- m_flat->m_nodeData << 0;
- }
-}
-
-QDeclarative1ListModel::~QDeclarative1ListModel()
-{
- if (m_agent)
- m_agent->release();
-
- delete m_nested;
- delete m_flat;
-}
-
-bool QDeclarative1ListModel::flatten()
-{
- if (m_flat)
- return true;
-
- QList<int> roles = m_nested->roles();
-
- QList<QHash<int, QVariant> > values;
- bool hasNested = false;
- for (int i=0; i<m_nested->count(); i++) {
- values.append(m_nested->data(i, roles, &hasNested));
- if (hasNested)
- return false;
- }
-
- FlatListModel_1 *flat = new FlatListModel_1(this);
- flat->m_values = values;
-
- for (int i=0; i<roles.count(); i++) {
- QString s = m_nested->toString(roles[i]);
- flat->m_roles.insert(roles[i], s);
- flat->m_strings.insert(s, roles[i]);
- }
-
- flat->m_nodeData.reserve(flat->m_values.count());
- for (int i=0; i<flat->m_values.count(); i++)
- flat->m_nodeData << 0;
-
- m_flat = flat;
- delete m_nested;
- m_nested = 0;
- return true;
-}
-
-bool QDeclarative1ListModel::inWorkerThread() const
-{
- return m_flat && m_flat->m_parentAgent;
-}
-
-QDeclarative1ListModelWorkerAgent *QDeclarative1ListModel::agent()
-{
- if (m_agent)
- return m_agent;
-
- if (!flatten()) {
- qmlInfo(this) << "List contains list-type data and cannot be used from a worker script";
- return 0;
- }
-
- m_agent = new QDeclarative1ListModelWorkerAgent(this);
- return m_agent;
-}
-
-QList<int> QDeclarative1ListModel::roles() const
-{
- return m_flat ? m_flat->roles() : m_nested->roles();
-}
-
-QString QDeclarative1ListModel::toString(int role) const
-{
- return m_flat ? m_flat->toString(role) : m_nested->toString(role);
-}
-
-QVariant QDeclarative1ListModel::data(int index, int role) const
-{
- if (index >= count() || index < 0)
- return QVariant();
-
- return m_flat ? m_flat->data(index, role) : m_nested->data(index, role);
-}
-
-/*!
- \qmlproperty int QtQuick1::ListModel::count
- The number of data entries in the model.
-*/
-int QDeclarative1ListModel::count() const
-{
- return m_flat ? m_flat->count() : m_nested->count();
-}
-
-/*!
- \qmlmethod QtQuick1::ListModel::clear()
-
- Deletes all content from the model.
-
- \sa append() remove()
-*/
-void QDeclarative1ListModel::clear()
-{
- int cleared = count();
- if (m_flat)
- m_flat->clear();
- else
- m_nested->clear();
-
- if (!inWorkerThread()) {
- emit itemsRemoved(0, cleared);
- emit countChanged();
- }
-}
-
-QDeclarative1ListModel *ModelNode::model(const NestedListModel_1 *model)
-{
- if (!modelCache) {
- modelCache = new QDeclarative1ListModel;
- QDeclarativeEngine::setContextForObject(modelCache,QDeclarativeEngine::contextForObject(model->m_listModel));
- modelCache->m_nested->_root = this; // ListModel defaults to nestable model
-
- for (int i=0; i<values.count(); ++i) {
- ModelNode *subNode = qvariant_cast<ModelNode *>(values.at(i));
- if (subNode)
- subNode->m_model = modelCache->m_nested;
- }
- }
- return modelCache;
-}
-
-ModelObject_1 *ModelNode::object(const NestedListModel_1 *model)
-{
- if (!objectCache) {
- objectCache = new ModelObject_1(this,
- const_cast<NestedListModel_1*>(model),
- QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(model->m_listModel)));
- QHash<QString, ModelNode *>::iterator it;
- for (it = properties.begin(); it != properties.end(); ++it) {
- objectCache->setValue(it.key().toUtf8(), model->valueForNode(*it));
- }
- objectCache->setNodeUpdatesEnabled(true);
- }
- return objectCache;
-}
-
-/*!
- \qmlmethod QtQuick1::ListModel::remove(int index)
-
- Deletes the content at \a index from the model.
-
- \sa clear()
-*/
-void QDeclarative1ListModel::remove(int index)
-{
- if (index < 0 || index >= count()) {
- qmlInfo(this) << tr("remove: index %1 out of range").arg(index);
- return;
- }
-
- if (m_flat)
- m_flat->remove(index);
- else
- m_nested->remove(index);
-
- if (!inWorkerThread()) {
- emit itemsRemoved(index, 1);
- emit countChanged();
- }
-}
-
-/*!
- \qmlmethod QtQuick1::ListModel::insert(int index, jsobject dict)
-
- Adds a new item to the list model at position \a index, with the
- values in \a dict.
-
- \code
- fruitModel.insert(2, {"cost": 5.95, "name":"Pizza"})
- \endcode
-
- The \a index must be to an existing item in the list, or one past
- the end of the list (equivalent to append).
-
- \sa set() append()
-*/
-void QDeclarative1ListModel::insert(int index, const QScriptValue& valuemap)
-{
- if (!valuemap.isObject() || valuemap.isArray()) {
- qmlInfo(this) << tr("insert: value is not an object");
- return;
- }
-
- if (index < 0 || index > count()) {
- qmlInfo(this) << tr("insert: index %1 out of range").arg(index);
- return;
- }
-
- bool ok = m_flat ? m_flat->insert(index, valuemap) : m_nested->insert(index, valuemap);
- if (ok && !inWorkerThread()) {
- emit itemsInserted(index, 1);
- emit countChanged();
- }
-}
-
-/*!
- \qmlmethod QtQuick1::ListModel::move(int from, int to, int n)
-
- Moves \a n items \a from one position \a to another.
-
- The from and to ranges must exist; for example, to move the first 3 items
- to the end of the list:
-
- \code
- fruitModel.move(0, fruitModel.count - 3, 3)
- \endcode
-
- \sa append()
-*/
-void QDeclarative1ListModel::move(int from, int to, int n)
-{
- if (n==0 || from==to)
- return;
- if (!canMove(from, to, n)) {
- qmlInfo(this) << tr("move: out of range");
- return;
- }
-
- int origfrom = from;
- int origto = to;
- int orign = n;
- if (from > to) {
- // Only move forwards - flip if backwards moving
- int tfrom = from;
- int tto = to;
- from = tto;
- to = tto+n;
- n = tfrom-tto;
- }
-
- if (m_flat)
- m_flat->move(from, to, n);
- else
- m_nested->move(from, to, n);
-
- if (!inWorkerThread())
- emit itemsMoved(origfrom, origto, orign);
-}
-
-/*!
- \qmlmethod QtQuick1::ListModel::append(jsobject dict)
-
- Adds a new item to the end of the list model, with the
- values in \a dict.
-
- \code
- fruitModel.append({"cost": 5.95, "name":"Pizza"})
- \endcode
-
- \sa set() remove()
-*/
-void QDeclarative1ListModel::append(const QScriptValue& valuemap)
-{
- if (!valuemap.isObject() || valuemap.isArray()) {
- qmlInfo(this) << tr("append: value is not an object");
- return;
- }
-
- insert(count(), valuemap);
-}
-
-/*!
- \qmlmethod object QtQuick1::ListModel::get(int index)
-
- Returns the item at \a index in the list model. This allows the item
- data to be accessed or modified from JavaScript:
-
- \code
- Component.onCompleted: {
- fruitModel.append({"cost": 5.95, "name":"Jackfruit"});
- console.log(fruitModel.get(0).cost);
- fruitModel.get(0).cost = 10.95;
- }
- \endcode
-
- The \a index must be an element in the list.
-
- Note that properties of the returned object that are themselves objects
- will also be models, and this get() method is used to access elements:
-
- \code
- fruitModel.append(..., "attributes":
- [{"name":"spikes","value":"7mm"},
- {"name":"color","value":"green"}]);
- fruitModel.get(0).attributes.get(1).value; // == "green"
- \endcode
-
- \warning The returned object is not guaranteed to remain valid. It
- should not be used in \l{Property Binding}{property bindings}.
-
- \sa append()
-*/
-QScriptValue QDeclarative1ListModel::get(int index) const
-{
- // the internal flat/nested class checks for bad index
- return m_flat ? m_flat->get(index) : m_nested->get(index);
-}
-
-/*!
- \qmlmethod QtQuick1::ListModel::set(int index, jsobject dict)
-
- Changes the item at \a index in the list model with the
- values in \a dict. Properties not appearing in \a dict
- are left unchanged.
-
- \code
- fruitModel.set(3, {"cost": 5.95, "name":"Pizza"})
- \endcode
-
- If \a index is equal to count() then a new item is appended to the
- list. Otherwise, \a index must be an element in the list.
-
- \sa append()
-*/
-void QDeclarative1ListModel::set(int index, const QScriptValue& valuemap)
-{
- QList<int> roles;
- set(index, valuemap, &roles);
- if (!roles.isEmpty() && !inWorkerThread())
- emit itemsChanged(index, 1, roles);
-}
-
-void QDeclarative1ListModel::set(int index, const QScriptValue& valuemap, QList<int> *roles)
-{
- if (!valuemap.isObject() || valuemap.isArray()) {
- qmlInfo(this) << tr("set: value is not an object");
- return;
- }
- if (index > count() || index < 0) {
- qmlInfo(this) << tr("set: index %1 out of range").arg(index);
- return;
- }
-
- if (index == count()) {
- append(valuemap);
- } else {
- if (m_flat)
- m_flat->set(index, valuemap, roles);
- else
- m_nested->set(index, valuemap, roles);
- }
-}
-
-/*!
- \qmlmethod QtQuick1::ListModel::setProperty(int index, string property, variant value)
-
- Changes the \a property of the item at \a index in the list model to \a value.
-
- \code
- fruitModel.setProperty(3, "cost", 5.95)
- \endcode
-
- The \a index must be an element in the list.
-
- \sa append()
-*/
-void QDeclarative1ListModel::setProperty(int index, const QString& property, const QVariant& value)
-{
- QList<int> roles;
- setProperty(index, property, value, &roles);
- if (!roles.isEmpty() && !inWorkerThread())
- emit itemsChanged(index, 1, roles);
-}
-
-void QDeclarative1ListModel::setProperty(int index, const QString& property, const QVariant& value, QList<int> *roles)
-{
- if (count() == 0 || index >= count() || index < 0) {
- qmlInfo(this) << tr("set: index %1 out of range").arg(index);
- return;
- }
-
- if (m_flat)
- m_flat->setProperty(index, property, value, roles);
- else
- m_nested->setProperty(index, property, value, roles);
-}
-
-/*!
- \qmlmethod QtQuick1::ListModel::sync()
-
- Writes any unsaved changes to the list model after it has been modified
- from a worker script.
-*/
-void QDeclarative1ListModel::sync()
-{
- // This is just a dummy method to make it look like sync() exists in
- // ListModel (and not just QDeclarative1ListModelWorkerAgent) and to let
- // us document sync().
- qmlInfo(this) << "List sync() can only be called from a WorkerScript";
-}
-
-bool QDeclarative1ListModelParser::compileProperty(const QDeclarativeCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data)
-{
- QList<QVariant> values = prop.assignedValues();
- for(int ii = 0; ii < values.count(); ++ii) {
- const QVariant &value = values.at(ii);
-
- if(value.userType() == qMetaTypeId<QDeclarativeCustomParserNode>()) {
- QDeclarativeCustomParserNode node =
- qvariant_cast<QDeclarativeCustomParserNode>(value);
-
- if (node.name() != listElementTypeName) {
- const QMetaObject *mo = resolveType(node.name());
- if (mo != &QDeclarative1ListElement::staticMetaObject) {
- error(node, QDeclarative1ListModel::tr("ListElement: cannot contain nested elements"));
- return false;
- }
- listElementTypeName = node.name(); // cache right name for next time
- }
-
- {
- ListInstruction li;
- li.type = ListInstruction::Push;
- li.dataIdx = -1;
- instr << li;
- }
-
- QList<QDeclarativeCustomParserProperty> props = node.properties();
- for(int jj = 0; jj < props.count(); ++jj) {
- const QDeclarativeCustomParserProperty &nodeProp = props.at(jj);
- if (nodeProp.name().isEmpty()) {
- error(nodeProp, QDeclarative1ListModel::tr("ListElement: cannot contain nested elements"));
- return false;
- }
- if (nodeProp.name() == "id") {
- error(nodeProp, QDeclarative1ListModel::tr("ListElement: cannot use reserved \"id\" property"));
- return false;
- }
-
- ListInstruction li;
- int ref = data.count();
- data.append(nodeProp.name());
- data.append('\0');
- li.type = ListInstruction::Set;
- li.dataIdx = ref;
- instr << li;
-
- if(!compileProperty(nodeProp, instr, data))
- return false;
-
- li.type = ListInstruction::Pop;
- li.dataIdx = -1;
- instr << li;
- }
-
- {
- ListInstruction li;
- li.type = ListInstruction::Pop;
- li.dataIdx = -1;
- instr << li;
- }
-
- } else {
-
- QDeclarativeParser::Variant variant =
- qvariant_cast<QDeclarativeParser::Variant>(value);
-
- int ref = data.count();
-
- QByteArray d;
- d += char(variant.type()); // type tag
- if (variant.isString()) {
- d += variant.asString().toUtf8();
- } else if (variant.isNumber()) {
- d += QByteArray::number(variant.asNumber(),'g',20);
- } else if (variant.isBoolean()) {
- d += char(variant.asBoolean());
- } else if (variant.isScript()) {
- if (definesEmptyList(variant.asScript())) {
- d[0] = char(QDeclarativeParser::Variant::Invalid); // marks empty list
- } else {
- QByteArray script = variant.asScript().toUtf8();
- int v = evaluateEnum(script);
- if (v<0) {
- if (script.startsWith("QT_TR_NOOP(\"") && script.endsWith("\")")) {
- d[0] = char(QDeclarativeParser::Variant::String);
- d += script.mid(12,script.length()-14);
- } else {
- error(prop, QDeclarative1ListModel::tr("ListElement: cannot use script for property value"));
- return false;
- }
- } else {
- d[0] = char(QDeclarativeParser::Variant::Number);
- d += QByteArray::number(v);
- }
- }
- }
- d.append('\0');
- data.append(d);
-
- ListInstruction li;
- li.type = ListInstruction::Value;
- li.dataIdx = ref;
- instr << li;
- }
- }
-
- return true;
-}
-
-QByteArray QDeclarative1ListModelParser::compile(const QList<QDeclarativeCustomParserProperty> &customProps)
-{
- QList<ListInstruction> instr;
- QByteArray data;
- listElementTypeName = QByteArray(); // unknown
-
- for(int ii = 0; ii < customProps.count(); ++ii) {
- const QDeclarativeCustomParserProperty &prop = customProps.at(ii);
- if(!prop.name().isEmpty()) { // isn't default property
- error(prop, QDeclarative1ListModel::tr("ListModel: undefined property '%1'").arg(QString::fromUtf8(prop.name())));
- return QByteArray();
- }
-
- if(!compileProperty(prop, instr, data)) {
- return QByteArray();
- }
- }
-
- int size = sizeof(ListModelData) +
- instr.count() * sizeof(ListInstruction) +
- data.count();
-
- QByteArray rv;
- rv.resize(size);
-
- ListModelData *lmd = (ListModelData *)rv.data();
- lmd->dataOffset = sizeof(ListModelData) +
- instr.count() * sizeof(ListInstruction);
- lmd->instrCount = instr.count();
- for (int ii = 0; ii < instr.count(); ++ii)
- lmd->instructions()[ii] = instr.at(ii);
- ::memcpy(rv.data() + lmd->dataOffset, data.constData(), data.count());
-
- return rv;
-}
-
-void QDeclarative1ListModelParser::setCustomData(QObject *obj, const QByteArray &d)
-{
- QDeclarative1ListModel *rv = static_cast<QDeclarative1ListModel *>(obj);
-
- ModelNode *root = new ModelNode(rv->m_nested);
- rv->m_nested->m_ownsRoot = true;
- rv->m_nested->_root = root;
- QStack<ModelNode *> nodes;
- nodes << root;
-
- bool processingSet = false;
-
- const ListModelData *lmd = (const ListModelData *)d.constData();
- const char *data = ((const char *)lmd) + lmd->dataOffset;
-
- for (int ii = 0; ii < lmd->instrCount; ++ii) {
- const ListInstruction &instr = lmd->instructions()[ii];
-
- switch(instr.type) {
- case ListInstruction::Push:
- {
- ModelNode *n = nodes.top();
- ModelNode *n2 = new ModelNode(rv->m_nested);
- n->values << QVariant::fromValue(n2);
- nodes.push(n2);
- if (processingSet)
- n->isArray = true;
- }
- break;
-
- case ListInstruction::Pop:
- nodes.pop();
- break;
-
- case ListInstruction::Value:
- {
- ModelNode *n = nodes.top();
- switch (QDeclarativeParser::Variant::Type(data[instr.dataIdx])) {
- case QDeclarativeParser::Variant::Invalid:
- n->isArray = true;
- break;
- case QDeclarativeParser::Variant::Boolean:
- n->values.append(bool(data[1 + instr.dataIdx]));
- break;
- case QDeclarativeParser::Variant::Number:
- n->values.append(QByteArray(data + 1 + instr.dataIdx).toDouble());
- break;
- case QDeclarativeParser::Variant::String:
- n->values.append(QString::fromUtf8(data + 1 + instr.dataIdx));
- break;
- default:
- Q_ASSERT("Format error in ListInstruction");
- }
-
- processingSet = false;
- }
- break;
-
- case ListInstruction::Set:
- {
- ModelNode *n = nodes.top();
- ModelNode *n2 = new ModelNode(rv->m_nested);
- n->properties.insert(QString::fromUtf8(data + instr.dataIdx), n2);
- nodes.push(n2);
- processingSet = true;
- }
- break;
- }
- }
-
- ModelNode *rootNode = rv->m_nested->_root;
- for (int i=0; i<rootNode->values.count(); ++i) {
- ModelNode *node = qvariant_cast<ModelNode *>(rootNode->values[i]);
- node->listIndex = i;
- node->updateListIndexes();
- }
-}
-
-bool QDeclarative1ListModelParser::definesEmptyList(const QString &s)
-{
- if (s.startsWith(QLatin1Char('[')) && s.endsWith(QLatin1Char(']'))) {
- for (int i=1; i<s.length()-1; i++) {
- if (!s[i].isSpace())
- return false;
- }
- return true;
- }
- return false;
-}
-
-
-/*!
- \qmlclass ListElement QDeclarative1ListElement
- \inqmlmodule QtQuick 1
- \ingroup qml-working-with-data
- \since QtQuick 1.0
- \brief The ListElement element defines a data item in a ListModel.
-
- List elements are defined inside ListModel definitions, and represent items in a
- list that will be displayed using ListView or \l Repeater items.
-
- List elements are defined like other QML elements except that they contain
- a collection of \e role definitions instead of properties. Using the same
- syntax as property definitions, roles both define how the data is accessed
- and include the data itself.
-
- The names used for roles must begin with a lower-case letter and should be
- common to all elements in a given model. Values must be simple constants; either
- strings (quoted and optionally within a call to QT_TR_NOOP), boolean values
- (true, false), numbers, or enumeration values (such as AlignText.AlignHCenter).
-
- \section1 Referencing Roles
-
- The role names are used by delegates to obtain data from list elements.
- Each role name is accessible in the delegate's scope, and refers to the
- corresponding role in the current element. Where a role name would be
- ambiguous to use, it can be accessed via the \l{ListView::}{model}
- property (e.g., \c{model.cost} instead of \c{cost}).
-
- \section1 Example Usage
-
- The following model defines a series of list elements, each of which
- contain "name" and "cost" roles and their associated values.
-
- \snippet doc/src/snippets/qtquick1/qml-data-models/listelements.qml model
-
- The delegate obtains the name and cost for each element by simply referring
- to \c name and \c cost:
-
- \snippet doc/src/snippets/qtquick1/qml-data-models/listelements.qml view
-
- \sa ListModel
-*/
-
-FlatListModel_1::FlatListModel_1(QDeclarative1ListModel *base)
- : m_scriptEngine(0), m_listModel(base), m_scriptClass(0), m_parentAgent(0)
-{
-}
-
-FlatListModel_1::~FlatListModel_1()
-{
- qDeleteAll(m_nodeData);
-}
-
-QVariant FlatListModel_1::data(int index, int role) const
-{
- Q_ASSERT(index >= 0 && index < m_values.count());
- if (m_values[index].contains(role))
- return m_values[index][role];
- return QVariant();
-}
-
-QList<int> FlatListModel_1::roles() const
-{
- return m_roles.keys();
-}
-
-QString FlatListModel_1::toString(int role) const
-{
- if (m_roles.contains(role))
- return m_roles[role];
- return QString();
-}
-
-int FlatListModel_1::count() const
-{
- return m_values.count();
-}
-
-void FlatListModel_1::clear()
-{
- m_values.clear();
-
- qDeleteAll(m_nodeData);
- m_nodeData.clear();
-}
-
-void FlatListModel_1::remove(int index)
-{
- m_values.removeAt(index);
- removedNode(index);
-}
-
-bool FlatListModel_1::insert(int index, const QScriptValue &value)
-{
- Q_ASSERT(index >= 0 && index <= m_values.count());
-
- QHash<int, QVariant> row;
- if (!addValue(value, &row, 0))
- return false;
-
- m_values.insert(index, row);
- insertedNode(index);
-
- return true;
-}
-
-QScriptValue FlatListModel_1::get(int index) const
-{
- QScriptEngine *scriptEngine = m_scriptEngine ? m_scriptEngine : QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(m_listModel));
-
- if (!scriptEngine)
- return 0;
-
- if (index < 0 || index >= m_values.count())
- return scriptEngine->undefinedValue();
-
- FlatListModel_1 *that = const_cast<FlatListModel_1*>(this);
- if (!m_scriptClass)
- that->m_scriptClass = new FlatListScriptClass_1(that, scriptEngine);
-
- FlatNodeData_1 *data = m_nodeData.value(index);
- if (!data) {
- data = new FlatNodeData_1(index);
- that->m_nodeData.replace(index, data);
- }
-
- return QScriptDeclarativeClass::newObject(scriptEngine, m_scriptClass, new FlatNodeObjectData(data));
-}
-
-void FlatListModel_1::set(int index, const QScriptValue &value, QList<int> *roles)
-{
- Q_ASSERT(index >= 0 && index < m_values.count());
-
- QHash<int, QVariant> row = m_values[index];
- if (addValue(value, &row, roles))
- m_values[index] = row;
-}
-
-void FlatListModel_1::setProperty(int index, const QString& property, const QVariant& value, QList<int> *roles)
-{
- Q_ASSERT(index >= 0 && index < m_values.count());
-
- QHash<QString, int>::Iterator iter = m_strings.find(property);
- int role;
- if (iter == m_strings.end()) {
- role = m_roles.count();
- m_roles.insert(role, property);
- m_strings.insert(property, role);
- } else {
- role = iter.value();
- }
-
- if (m_values[index][role] != value) {
- roles->append(role);
- m_values[index][role] = value;
- }
-}
-
-void FlatListModel_1::move(int from, int to, int n)
-{
- qdeclarativelistmodel_move<QList<QHash<int, QVariant> > >(from, to, n, &m_values);
- moveNodes(from, to, n);
-}
-
-bool FlatListModel_1::addValue(const QScriptValue &value, QHash<int, QVariant> *row, QList<int> *roles)
-{
- QScriptValueIterator it(value);
- while (it.hasNext()) {
- it.next();
- QScriptValue value = it.value();
- if (!value.isVariant() && !value.isRegExp() && !value.isDate() && value.isObject()) {
- qmlInfo(m_listModel) << "Cannot add list-type data when modifying or after modification from a worker script";
- return false;
- }
-
- QString name = it.name();
- QVariant v = it.value().toVariant();
-
- QHash<QString, int>::Iterator iter = m_strings.find(name);
- if (iter == m_strings.end()) {
- int role = m_roles.count();
- m_roles.insert(role, name);
- iter = m_strings.insert(name, role);
- if (roles)
- roles->append(role);
- } else {
- int role = iter.value();
- if (roles && row->contains(role) && row->value(role) != v)
- roles->append(role);
- }
- row->insert(*iter, v);
- }
- return true;
-}
-
-void FlatListModel_1::insertedNode(int index)
-{
- if (index >= 0 && index <= m_values.count()) {
- m_nodeData.insert(index, 0);
-
- for (int i=index + 1; i<m_nodeData.count(); i++) {
- if (m_nodeData[i])
- m_nodeData[i]->index = i;
- }
- }
-}
-
-void FlatListModel_1::removedNode(int index)
-{
- if (index >= 0 && index < m_nodeData.count()) {
- delete m_nodeData.takeAt(index);
-
- for (int i=index; i<m_nodeData.count(); i++) {
- if (m_nodeData[i])
- m_nodeData[i]->index = i;
- }
- }
-}
-
-void FlatListModel_1::moveNodes(int from, int to, int n)
-{
- if (!m_listModel->canMove(from, to, n))
- return;
-
- qdeclarativelistmodel_move<QList<FlatNodeData_1 *> >(from, to, n, &m_nodeData);
-
- for (int i=from; i<from + (to-from); i++) {
- if (m_nodeData[i])
- m_nodeData[i]->index = i;
- }
-}
-
-
-
-FlatNodeData_1::~FlatNodeData_1()
-{
- for (QSet<FlatNodeObjectData *>::Iterator iter = objects.begin(); iter != objects.end(); ++iter) {
- FlatNodeObjectData *data = *iter;
- data->nodeData = 0;
- }
-}
-
-void FlatNodeData_1::addData(FlatNodeObjectData *data)
-{
- objects.insert(data);
-}
-
-void FlatNodeData_1::removeData(FlatNodeObjectData *data)
-{
- objects.remove(data);
-}
-
-
-FlatListScriptClass_1::FlatListScriptClass_1(FlatListModel_1 *model, QScriptEngine *seng)
- : QScriptDeclarativeClass(seng),
- m_model(model)
-{
-}
-
-QScriptDeclarativeClass::Value FlatListScriptClass_1::property(Object *obj, const Identifier &name)
-{
- FlatNodeObjectData *objData = static_cast<FlatNodeObjectData*>(obj);
- if (!objData->nodeData) // item at this index has been deleted
- return QScriptDeclarativeClass::Value(engine(), engine()->undefinedValue());
-
- int index = objData->nodeData->index;
- QString propName = toString(name);
- int role = m_model->m_strings.value(propName, -1);
-
- if (role >= 0 && index >=0 ) {
- const QHash<int, QVariant> &row = m_model->m_values[index];
- QScriptValue sv = engine()->toScriptValue<QVariant>(row[role]);
- return QScriptDeclarativeClass::Value(engine(), sv);
- }
-
- return QScriptDeclarativeClass::Value(engine(), engine()->undefinedValue());
-}
-
-void FlatListScriptClass_1::setProperty(Object *obj, const Identifier &name, const QScriptValue &value)
-{
- if (!value.isVariant() && !value.isRegExp() && !value.isDate() && value.isObject()) {
- qmlInfo(m_model->m_listModel) << "Cannot add list-type data when modifying or after modification from a worker script";
- return;
- }
-
- FlatNodeObjectData *objData = static_cast<FlatNodeObjectData*>(obj);
- if (!objData->nodeData) // item at this index has been deleted
- return;
-
- int index = objData->nodeData->index;
- QString propName = toString(name);
-
- int role = m_model->m_strings.value(propName, -1);
- if (role >= 0 && index >= 0) {
- QHash<int, QVariant> &row = m_model->m_values[index];
- row[role] = value.toVariant();
-
- QList<int> roles;
- roles << role;
- if (m_model->m_parentAgent) {
- // This is the list in the worker thread, so tell the agent to
- // emit itemsChanged() later
- m_model->m_parentAgent->changedData(index, 1, roles);
- } else {
- // This is the list in the main thread, so emit itemsChanged()
- emit m_model->m_listModel->itemsChanged(index, 1, roles);
- }
- }
-}
-
-QScriptClass::QueryFlags FlatListScriptClass_1::queryProperty(Object *, const Identifier &, QScriptClass::QueryFlags)
-{
- return (QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess);
-}
-
-bool FlatListScriptClass_1::compare(Object *obj1, Object *obj2)
-{
- FlatNodeObjectData *data1 = static_cast<FlatNodeObjectData*>(obj1);
- FlatNodeObjectData *data2 = static_cast<FlatNodeObjectData*>(obj2);
-
- if (!data1->nodeData || !data2->nodeData)
- return false;
-
- return data1->nodeData->index == data2->nodeData->index;
-}
-
-
-
-NestedListModel_1::NestedListModel_1(QDeclarative1ListModel *base)
- : _root(0), m_ownsRoot(false), m_listModel(base), _rolesOk(false)
-{
-}
-
-NestedListModel_1::~NestedListModel_1()
-{
- if (m_ownsRoot)
- delete _root;
-}
-
-QVariant NestedListModel_1::valueForNode(ModelNode *node, bool *hasNested) const
-{
- QObject *rv = 0;
- if (hasNested)
- *hasNested = false;
-
- if (node->isArray) {
- // List
- rv = node->model(this);
- if (hasNested)
- *hasNested = true;
- } else {
- if (!node->properties.isEmpty()) {
- // Object
- rv = node->object(this);
- } else if (node->values.count() == 0) {
- // Invalid
- return QVariant();
- } else if (node->values.count() == 1) {
- // Value
- QVariant &var = node->values[0];
- ModelNode *valueNode = qvariant_cast<ModelNode *>(var);
- if (valueNode) {
- if (!valueNode->properties.isEmpty())
- rv = valueNode->object(this);
- else
- rv = valueNode->model(this);
- } else {
- return var;
- }
- }
- }
-
- if (rv) {
- return QVariant::fromValue(rv);
- } else {
- return QVariant();
- }
-}
-
-QHash<int,QVariant> NestedListModel_1::data(int index, const QList<int> &roles, bool *hasNested) const
-{
- Q_ASSERT(_root && index >= 0 && index < _root->values.count());
- checkRoles();
- QHash<int, QVariant> rv;
-
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- if (!node)
- return rv;
-
- for (int ii = 0; ii < roles.count(); ++ii) {
- const QString &roleString = roleStrings.at(roles.at(ii));
-
- QHash<QString, ModelNode *>::ConstIterator iter = node->properties.find(roleString);
- if (iter != node->properties.end()) {
- ModelNode *row = *iter;
- rv.insert(roles.at(ii), valueForNode(row, hasNested));
- }
- }
-
- return rv;
-}
-
-QVariant NestedListModel_1::data(int index, int role) const
-{
- Q_ASSERT(_root && index >= 0 && index < _root->values.count());
- checkRoles();
- QVariant rv;
- if (roleStrings.count() < role)
- return rv;
-
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- if (!node)
- return rv;
-
- const QString &roleString = roleStrings.at(role);
-
- QHash<QString, ModelNode *>::ConstIterator iter = node->properties.find(roleString);
- if (iter != node->properties.end()) {
- ModelNode *row = *iter;
- rv = valueForNode(row);
- }
-
- return rv;
-}
-
-int NestedListModel_1::count() const
-{
- if (!_root) return 0;
- return _root->values.count();
-}
-
-void NestedListModel_1::clear()
-{
- if (_root)
- _root->clear();
-}
-
-void NestedListModel_1::remove(int index)
-{
- if (!_root)
- return;
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- _root->values.removeAt(index);
- if (node)
- delete node;
-}
-
-bool NestedListModel_1::insert(int index, const QScriptValue& valuemap)
-{
- if (!_root) {
- _root = new ModelNode(this);
- m_ownsRoot = true;
- }
-
- ModelNode *mn = new ModelNode(this);
- mn->listIndex = index;
- mn->setObjectValue(valuemap);
- _root->values.insert(index,QVariant::fromValue(mn));
- return true;
-}
-
-void NestedListModel_1::move(int from, int to, int n)
-{
- if (!_root)
- return;
- qdeclarativelistmodel_move<QVariantList>(from, to, n, &_root->values);
-}
-
-QScriptValue NestedListModel_1::get(int index) const
-{
- QDeclarativeEngine *eng = qmlEngine(m_listModel);
- if (!eng)
- return 0;
-
- if (index < 0 || index >= count()) {
- QScriptEngine *seng = QDeclarativeEnginePrivate::getScriptEngine(eng);
- if (seng)
- return seng->undefinedValue();
- return 0;
- }
-
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- if (!node)
- return 0;
-
- return QDeclarativeEnginePrivate::qmlScriptObject(node->object(this), eng);
-}
-
-void NestedListModel_1::set(int index, const QScriptValue& valuemap, QList<int> *roles)
-{
- Q_ASSERT(index >=0 && index < count());
-
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- bool emitItemsChanged = node->setObjectValue(valuemap);
- if (!emitItemsChanged)
- return;
-
- QScriptValueIterator it(valuemap);
- while (it.hasNext()) {
- it.next();
- int r = roleStrings.indexOf(it.name());
- if (r < 0) {
- r = roleStrings.count();
- roleStrings << it.name();
- }
- roles->append(r);
- }
-}
-
-void NestedListModel_1::setProperty(int index, const QString& property, const QVariant& value, QList<int> *roles)
-{
- Q_ASSERT(index >=0 && index < count());
-
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- bool emitItemsChanged = node->setProperty(property, value);
- if (!emitItemsChanged)
- return;
-
- int r = roleStrings.indexOf(property);
- if (r < 0) {
- r = roleStrings.count();
- roleStrings << property;
- }
- roles->append(r);
-}
-
-void NestedListModel_1::checkRoles() const
-{
- if (_rolesOk || !_root)
- return;
-
- for (int i = 0; i<_root->values.count(); ++i) {
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(i));
- if (node) {
- foreach (const QString &role, node->properties.keys()) {
- if (!roleStrings.contains(role))
- roleStrings.append(role);
- }
- }
- }
-
- _rolesOk = true;
-}
-
-QList<int> NestedListModel_1::roles() const
-{
- checkRoles();
- QList<int> rv;
- for (int ii = 0; ii < roleStrings.count(); ++ii)
- rv << ii;
- return rv;
-}
-
-QString NestedListModel_1::toString(int role) const
-{
- checkRoles();
- if (role < roleStrings.count())
- return roleStrings.at(role);
- else
- return QString();
-}
-
-
-ModelNode::ModelNode(NestedListModel_1 *model)
-: modelCache(0), objectCache(0), isArray(false), m_model(model), listIndex(-1)
-{
-}
-
-ModelNode::~ModelNode()
-{
- clear();
- if (modelCache) { modelCache->m_nested->_root = 0/* ==this */; delete modelCache; modelCache = 0; }
- if (objectCache) { delete objectCache; objectCache = 0; }
-}
-
-void ModelNode::clear()
-{
- ModelNode *node;
- for (int ii = 0; ii < values.count(); ++ii) {
- node = qvariant_cast<ModelNode *>(values.at(ii));
- if (node) { delete node; node = 0; }
- }
- values.clear();
-
- qDeleteAll(properties.values());
- properties.clear();
-}
-
-bool ModelNode::setObjectValue(const QScriptValue& valuemap, bool writeToCache)
-{
- bool emitItemsChanged = false;
-
- QScriptValueIterator it(valuemap);
- while (it.hasNext()) {
- it.next();
- ModelNode *prev = properties.value(it.name());
- ModelNode *value = new ModelNode(m_model);
- QScriptValue v = it.value();
-
- if (v.isArray()) {
- value->isArray = true;
- value->setListValue(v);
- if (writeToCache && objectCache)
- objectCache->setValue(it.name().toUtf8(), QVariant::fromValue(value->model(m_model)));
- emitItemsChanged = true; // for now, too inefficient to check whether list and sublists have changed
- } else {
- value->values << v.toVariant();
- if (writeToCache && objectCache)
- objectCache->setValue(it.name().toUtf8(), value->values.last());
- if (!emitItemsChanged && prev && prev->values.count() == 1
- && prev->values[0] != value->values.last()) {
- emitItemsChanged = true;
- }
- }
- if (properties.contains(it.name()))
- delete properties[it.name()];
- properties.insert(it.name(), value);
- }
- return emitItemsChanged;
-}
-
-void ModelNode::setListValue(const QScriptValue& valuelist) {
- values.clear();
- int size = valuelist.property(QLatin1String("length")).toInt32();
- for (int i=0; i<size; i++) {
- ModelNode *value = new ModelNode(m_model);
- QScriptValue v = valuelist.property(i);
- if (v.isArray()) {
- value->isArray = true;
- value->setListValue(v);
- } else if (v.isObject()) {
- value->listIndex = i;
- value->setObjectValue(v);
- } else {
- value->listIndex = i;
- value->values << v.toVariant();
- }
- values.append(QVariant::fromValue(value));
- }
-}
-
-bool ModelNode::setProperty(const QString& prop, const QVariant& val) {
- QHash<QString, ModelNode *>::const_iterator it = properties.find(prop);
- bool emitItemsChanged = false;
- if (it != properties.end()) {
- if (val != (*it)->values[0])
- emitItemsChanged = true;
- (*it)->values[0] = val;
- } else {
- ModelNode *n = new ModelNode(m_model);
- n->values << val;
- properties.insert(prop,n);
- }
- if (objectCache)
- objectCache->setValue(prop.toUtf8(), val);
- return emitItemsChanged;
-}
-
-void ModelNode::updateListIndexes()
-{
- for (QHash<QString, ModelNode *>::ConstIterator iter = properties.begin(); iter != properties.end(); ++iter) {
- ModelNode *node = iter.value();
- if (node->isArray) {
- for (int i=0; i<node->values.count(); ++i) {
- ModelNode *subNode = qvariant_cast<ModelNode *>(node->values.at(i));
- if (subNode)
- subNode->listIndex = i;
- }
- }
- node->updateListIndexes();
- }
-}
-
-/*
- Need to call this to emit itemsChanged() for modifications outside of set()
- and setProperty(), i.e. if an item returned from get() is modified
-*/
-void ModelNode::changedProperty(const QString &name) const
-{
- if (listIndex < 0)
- return;
-
- m_model->checkRoles();
- QList<int> roles;
- int role = m_model->roleStrings.indexOf(name);
- if (role < 0)
- roles = m_model->roles();
- else
- roles << role;
- emit m_model->m_listModel->itemsChanged(listIndex, 1, roles);
-}
-
-void ModelNode::dump(ModelNode *node, int ind)
-{
- QByteArray indentBa(ind * 4, ' ');
- const char *indent = indentBa.constData();
-
- for (int ii = 0; ii < node->values.count(); ++ii) {
- ModelNode *subNode = qvariant_cast<ModelNode *>(node->values.at(ii));
- if (subNode) {
- qWarning().nospace() << indent << "Sub-node " << ii;
- dump(subNode, ind + 1);
- } else {
- qWarning().nospace() << indent << "Sub-node " << ii << ": " << node->values.at(ii).toString();
- }
- }
-
- for (QHash<QString, ModelNode *>::ConstIterator iter = node->properties.begin(); iter != node->properties.end(); ++iter) {
- qWarning().nospace() << indent << "Property " << iter.key() << ':';
- dump(iter.value(), ind + 1);
- }
-}
-
-ModelObject_1::ModelObject_1(ModelNode *node, NestedListModel_1 *model, QScriptEngine *seng)
- : m_model(model),
- m_node(node),
- m_meta(new ModelNodeMetaObject_1(seng, this))
-{
-}
-
-void ModelObject_1::setValue(const QByteArray &name, const QVariant &val)
-{
- m_meta->setValue(name, val);
- //setProperty(name.constData(), val);
-}
-
-void ModelObject_1::setNodeUpdatesEnabled(bool enable)
-{
- m_meta->m_enabled = enable;
-}
-
-
-ModelNodeMetaObject_1::ModelNodeMetaObject_1(QScriptEngine *seng, ModelObject_1 *object)
- : QDeclarative1OpenMetaObject(object),
- m_enabled(false),
- m_seng(seng),
- m_obj(object)
-{
-}
-
-void ModelNodeMetaObject_1::propertyWritten(int index)
-{
- if (!m_enabled)
- return;
-
- QString propName = QString::fromUtf8(name(index));
- QVariant value = operator[](index);
-
- QScriptValue sv = m_seng->newObject();
- sv.setProperty(propName, m_seng->newVariant(value));
- bool changed = m_obj->m_node->setObjectValue(sv, false);
- if (changed)
- m_obj->m_node->changedProperty(propName);
-}
-
-
-
-
-QT_END_NAMESPACE