summaryrefslogtreecommitdiffstats
path: root/src/declarative/fx
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2009-09-17 07:01:00 (GMT)
committerMartin Jones <martin.jones@nokia.com>2009-09-17 07:01:00 (GMT)
commit2a9bc5163553a05fee61c289d09ec2ba963911bc (patch)
treee3b7774591edca4e26e455b91355a01ac8c6d597 /src/declarative/fx
parent6f75efdaf7f4fb378506cf52ec56588f02453806 (diff)
downloadQt-2a9bc5163553a05fee61c289d09ec2ba963911bc.zip
Qt-2a9bc5163553a05fee61c289d09ec2ba963911bc.tar.gz
Qt-2a9bc5163553a05fee61c289d09ec2ba963911bc.tar.bz2
Switch Repeater over to use VisualModel.
Also extend VisualModels to support the usage Repeater used to add.
Diffstat (limited to 'src/declarative/fx')
-rw-r--r--src/declarative/fx/qfxrepeater.cpp246
-rw-r--r--src/declarative/fx/qfxrepeater.h4
-rw-r--r--src/declarative/fx/qfxrepeater_p.h9
-rw-r--r--src/declarative/fx/qfxvisualitemmodel.cpp121
4 files changed, 157 insertions, 223 deletions
diff --git a/src/declarative/fx/qfxrepeater.cpp b/src/declarative/fx/qfxrepeater.cpp
index e6ee242..719aea9 100644
--- a/src/declarative/fx/qfxrepeater.cpp
+++ b/src/declarative/fx/qfxrepeater.cpp
@@ -42,12 +42,13 @@
#include "qfxrepeater.h"
#include "qfxrepeater_p.h"
#include "qmllistaccessor.h"
+#include "qfxvisualitemmodel.h"
#include <qlistmodelinterface.h>
QT_BEGIN_NAMESPACE
QFxRepeaterPrivate::QFxRepeaterPrivate()
-: component(0), count(0)
+: model(0), ownModel(false)
{
}
@@ -55,23 +56,6 @@ QFxRepeaterPrivate::~QFxRepeaterPrivate()
{
}
-QFxItem *QFxRepeaterPrivate::addItem(QmlContext *ctxt, QFxItem *lastItem)
-{
- Q_UNUSED(lastItem)
- Q_Q(QFxRepeater);
- QObject *nobj = component->create(ctxt);
- QFxItem *item = qobject_cast<QFxItem *>(nobj);
- if (item) {
- item->setParent(q->parentItem());
-// item->stackUnder(lastItem);
- deletables << nobj;
- } else {
- delete nobj;
- }
-
- return item;
-}
-
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Repeater,QFxRepeater)
/*!
@@ -166,11 +150,47 @@ QVariant QFxRepeater::model() const
return d->dataSource;
}
-void QFxRepeater::setModel(const QVariant &v)
+void QFxRepeater::setModel(const QVariant &model)
{
Q_D(QFxRepeater);
- d->dataSource = v;
- regenerate();
+ clear();
+ /*
+ if (d->model) {
+ disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
+ disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
+ disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
+ disconnect(d->model, SIGNAL(createdItem(int, QFxItem*)), this, SLOT(createdItem(int,QFxItem*)));
+ disconnect(d->model, SIGNAL(destroyingItem(QFxItem*)), this, SLOT(destroyingItem(QFxItem*)));
+ }
+ */
+ d->dataSource = model;
+ QObject *object = qvariant_cast<QObject*>(model);
+ QFxVisualModel *vim = 0;
+ if (object && (vim = qobject_cast<QFxVisualModel *>(object))) {
+ if (d->ownModel) {
+ delete d->model;
+ d->ownModel = false;
+ }
+ d->model = vim;
+ } else {
+ if (!d->ownModel) {
+ d->model = new QFxVisualDataModel(qmlContext(this));
+ d->ownModel = true;
+ }
+ if (QFxVisualDataModel *dataModel = qobject_cast<QFxVisualDataModel*>(d->model))
+ dataModel->setModel(model);
+ }
+ if (d->model) {
+ /*
+ connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
+ connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
+ connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
+ connect(d->model, SIGNAL(createdItem(int, QFxItem*)), this, SLOT(createdItem(int,QFxItem*)));
+ connect(d->model, SIGNAL(destroyingItem(QFxItem*)), this, SLOT(destroyingItem(QFxItem*)));
+ */
+ regenerate();
+ emit countChanged();
+ }
}
/*!
@@ -182,14 +202,25 @@ void QFxRepeater::setModel(const QVariant &v)
QmlComponent *QFxRepeater::delegate() const
{
Q_D(const QFxRepeater);
- return d->component;
+ if (d->model) {
+ if (QFxVisualDataModel *dataModel = qobject_cast<QFxVisualDataModel*>(d->model))
+ return dataModel->delegate();
+ }
+
+ return 0;
}
-void QFxRepeater::setDelegate(QmlComponent *_c)
+void QFxRepeater::setDelegate(QmlComponent *delegate)
{
Q_D(QFxRepeater);
- d->component = _c;
- regenerate();
+ if (!d->ownModel) {
+ d->model = new QFxVisualDataModel(qmlContext(this));
+ d->ownModel = true;
+ }
+ if (QFxVisualDataModel *dataModel = qobject_cast<QFxVisualDataModel*>(d->model)) {
+ dataModel->setDelegate(delegate);
+ regenerate();
+ }
}
/*!
@@ -200,7 +231,9 @@ void QFxRepeater::setDelegate(QmlComponent *_c)
int QFxRepeater::count() const
{
Q_D(const QFxRepeater);
- return d->count;
+ if (d->model)
+ return d->model->count();
+ return 0;
}
@@ -227,6 +260,16 @@ QVariant QFxRepeater::itemChange(GraphicsItemChange change,
return rv;
}
+void QFxRepeater::clear()
+{
+ Q_D(QFxRepeater);
+ if (d->model) {
+ foreach (QFxItem *item, d->deletables)
+ d->model->release(item);
+ }
+ d->deletables.clear();
+}
+
/*!
\internal
*/
@@ -234,152 +277,19 @@ void QFxRepeater::regenerate()
{
Q_D(QFxRepeater);
- qDeleteAll(d->deletables);
- d->deletables.clear();
- if (!d->component || !parentItem() || !isComponentComplete())
- return;
-
- QFxItem *lastItem = this;
-
- int count = 0;
-
- if (d->dataSource.type() == QVariant::StringList) {
- QStringList sl = qvariant_cast<QStringList>(d->dataSource);
-
- count = sl.size();
- for (int ii = 0; ii < count; ++ii) {
- QmlContext *ctxt = new QmlContext(qmlContext(this), this);
- d->deletables << ctxt;
+ clear();
- ctxt->setContextProperty(QLatin1String("index"), ii);
- ctxt->setContextProperty(QLatin1String("modelData"), sl.at(ii));
-
- if (QFxItem *item = d->addItem(ctxt, lastItem))
- lastItem = item;
- }
- } else if (d->dataSource.type() == QMetaType::QVariantList) {
- QVariantList sl = qvariant_cast<QVariantList>(d->dataSource);
-
- count = sl.size();
- for (int ii = 0; ii < count; ++ii) {
- QmlContext *ctxt = new QmlContext(qmlContext(this), this);
- d->deletables << ctxt;
-
- ctxt->setContextProperty(QLatin1String("index"), ii);
- ctxt->setContextProperty(QLatin1String("modelData"), sl.at(ii));
-
- if (QFxItem *item = d->addItem(ctxt, lastItem))
- lastItem = item;
- }
- } else if (QmlMetaType::isList(d->dataSource)) {
- count = QmlMetaType::listCount(d->dataSource);
- if (count <= 0)
- return;
-
- for (int ii = 0; ii < count; ++ii) {
- QVariant v = QmlMetaType::listAt(d->dataSource, ii);
- QObject *o = QmlMetaType::toQObject(v);
-
- QmlContext *ctxt = new QmlContext(qmlContext(this), this);
- d->deletables << ctxt;
-
- ctxt->setContextProperty(QLatin1String("index"), ii);
- ctxt->setContextProperty(QLatin1String("modelData"), o);
-
- if (QFxItem *item = d->addItem(ctxt, lastItem))
- lastItem = item;
- }
- } else if (QListModelInterface *model = qobject_cast<QListModelInterface*>(d->dataSource.value<QObject*>())) {
- count = model->count();
- if (count <= 0)
- return;
-
- for (int ii = 0; ii < count; ++ii) {
- QmlContext *ctxt = new QmlContext(qmlContext(this), this);
- d->deletables << ctxt;
-
- ctxt->setContextProperty(QLatin1String("index"), ii);
-
- QList<int> roles = model->roles();
- QHash<int,QVariant> data = model->data(ii,roles);
- for (int j = 0; j < roles.size(); ++j) {
- ctxt->setContextProperty(model->toString(roles.at(j)), data.value(roles.at(j)));
- }
-
- //for compatability with other lists, assign data if there is only a single role
- if (roles.size() == 1)
- ctxt->setContextProperty(QLatin1String("modelData"), data.value(roles.at(0)));
-
- if (QFxItem *item = d->addItem(ctxt, lastItem))
- lastItem = item;
- }
- } else if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(d->dataSource.value<QObject*>())) {
- count = model->rowCount();
- if (count <= 0)
- return;
-
- for (int ii = 0; ii < count; ++ii) {
- QmlContext *ctxt = new QmlContext(qmlContext(this), this);
- d->deletables << ctxt;
-
- ctxt->setContextProperty(QLatin1String("index"), ii);
-
- QList<int> roles;
- QStringList roleNames;
- QHash<int,QVariant> data;
- for (QHash<int,QByteArray>::const_iterator it = model->roleNames().begin();
- it != model->roleNames().end(); ++it) {
- roles.append(it.key());
- roleNames.append(QLatin1String(*it));
- }
+ if (!d->model || !d->model->count() || !d->model->isValid() || !parentItem() || !isComponentComplete())
+ return;
- QModelIndex index = model->index(ii, 0);
- for (int j = 0; j < roles.size(); ++j) {
- ctxt->setContextProperty(roleNames.at(j), model->data(index, roles.at(j)));
+ if (d->model) {
+ for (int ii = 0; ii < count(); ++ii) {
+ QFxItem *item = d->model->item(ii);
+ if (item) {
+ item->setParent(parentItem());
+ d->deletables << item;
}
-
- //for compatability with other lists, assign data if there is only a single role
- if (roles.size() == 1)
- ctxt->setContextProperty(QLatin1String("modelData"), data.value(roles.at(0)));
-
- if (QFxItem *item = d->addItem(ctxt, lastItem))
- lastItem = item;
- }
- } else if (QObject *object = d->dataSource.value<QObject*>()) {
- // A single object (i.e. list of size 1).
- // Properties are the roles (excluding objectName).
- QmlContext *ctxt = new QmlContext(qmlContext(this), this);
- d->deletables << ctxt;
-
- ctxt->setContextProperty(QLatin1String("index"), QVariant(0));
- count = object->metaObject()->propertyCount();
- for (int ii = 1; ii < count; ++ii) {
- const QMetaProperty &prop = object->metaObject()->property(ii);
- ctxt->setContextProperty(QLatin1String(prop.name()), prop.read(object));
- }
-
- //for compatability with other lists, assign data if there is only a single role (excluding objectName)
- if (count == 2) {
- const QMetaProperty &prop = object->metaObject()->property(1);
- ctxt->setContextProperty(QLatin1String("modelData"), prop.read(object));
- }
-
- d->addItem(ctxt, lastItem);
-
- } else if (d->dataSource.canConvert(QVariant::Int)){
-
- count = qvariant_cast<int>(d->dataSource);
-
- for (int ii = 0; ii < count; ++ii) {
- QmlContext *ctxt = new QmlContext(qmlContext(this), this);
- d->deletables << ctxt;
-
- ctxt->setContextProperty(QLatin1String("index"), ii);
-
- if (QFxItem *item = d->addItem(ctxt, lastItem))
- lastItem = item;
}
}
- d->count = count;
}
QT_END_NAMESPACE
diff --git a/src/declarative/fx/qfxrepeater.h b/src/declarative/fx/qfxrepeater.h
index 43afd63..7d64d86 100644
--- a/src/declarative/fx/qfxrepeater.h
+++ b/src/declarative/fx/qfxrepeater.h
@@ -72,7 +72,11 @@ public:
int count() const;
+Q_SIGNALS:
+ void countChanged();
+
private:
+ void clear();
void regenerate();
protected:
diff --git a/src/declarative/fx/qfxrepeater_p.h b/src/declarative/fx/qfxrepeater_p.h
index 65b0973..a4eb96d 100644
--- a/src/declarative/fx/qfxrepeater_p.h
+++ b/src/declarative/fx/qfxrepeater_p.h
@@ -61,6 +61,7 @@
QT_BEGIN_NAMESPACE
class QmlContext;
+class QFxVisualModel;
class QFxRepeaterPrivate : public QFxItemPrivate
{
Q_DECLARE_PUBLIC(QFxRepeater)
@@ -69,13 +70,11 @@ public:
QFxRepeaterPrivate();
~QFxRepeaterPrivate();
- QFxItem *addItem(QmlContext *ctxt, QFxItem *lastItem);
-
+ QFxVisualModel *model;
QVariant dataSource;
- QmlComponent *component;
- int count;
+ bool ownModel;
- QList<QPointer<QObject> > deletables;
+ QList<QPointer<QFxItem> > deletables;
};
QT_END_NAMESPACE
diff --git a/src/declarative/fx/qfxvisualitemmodel.cpp b/src/declarative/fx/qfxvisualitemmodel.cpp
index 81fbafa..1f8c079 100644
--- a/src/declarative/fx/qfxvisualitemmodel.cpp
+++ b/src/declarative/fx/qfxvisualitemmodel.cpp
@@ -243,14 +243,34 @@ public:
QmlComponent *m_delegate;
QmlContext *m_context;
QList<int> m_roles;
- QHash<int,QString> m_roleNames;
+ QHash<QString,int> m_roleNames;
void ensureRoles() {
- if (m_roles.isEmpty()) {
+ if (m_roleNames.isEmpty()) {
if (m_listModelInterface) {
m_roles = m_listModelInterface->roles();
- for (int ii = 0; ii < m_roles.count(); ++ii)
- m_roleNames.insert(m_roles.at(ii),
- m_listModelInterface->toString(m_roles.at(ii)));
+ for (int ii = 0; ii < m_roles.count(); ++ii)
+ m_roleNames.insert(m_listModelInterface->toString(m_roles.at(ii)), m_roles.at(ii));
+ if (m_roles.count() == 1)
+ m_roleNames.insert(QLatin1String("modelData"), m_roles.at(0));
+ } else if (m_abstractItemModel) {
+ for (QHash<int,QByteArray>::const_iterator it = m_abstractItemModel->roleNames().begin();
+ it != m_abstractItemModel->roleNames().end(); ++it) {
+ m_roles.append(it.key());
+ m_roleNames.insert(QLatin1String(*it), it.key());
+ }
+ if (m_roles.count() == 1)
+ m_roleNames.insert(QLatin1String("modelData"), m_roles.at(0));
+ } else if (m_modelList) {
+ m_roleNames.insert(QLatin1String("modelData"), 0);
+ if (m_modelList->type() == QmlListAccessor::Instance) {
+ if (QObject *object = m_modelList->at(0).value<QObject*>()) {
+ int count = object->metaObject()->propertyCount();
+ for (int ii = 1; ii < count; ++ii) {
+ const QMetaProperty &prop = object->metaObject()->property(ii);
+ m_roleNames.insert(prop.name(), 0);
+ }
+ }
+ }
}
}
}
@@ -382,17 +402,14 @@ int QFxVisualDataModelDataMetaObject::createProperty(const char *name, const cha
if ((!data->m_model->m_listModelInterface || !data->m_model->m_abstractItemModel)
&& data->m_model->m_modelList) {
- if (!qstrcmp(name, "modelData"))
+ data->m_model->ensureRoles();
+ if (data->m_model->m_roleNames.contains(QLatin1String(name)))
return QmlOpenMetaObject::createProperty(name, type);
} else {
- const QLatin1String sname(name);
data->m_model->ensureRoles();
- for (QHash<int, QString>::ConstIterator iter = data->m_model->m_roleNames.begin();
- iter != data->m_model->m_roleNames.end(); ++iter) {
-
- if (*iter == sname)
- return QmlOpenMetaObject::createProperty(name, type);
- }
+ const QLatin1String sname(name);
+ if (data->m_model->m_roleNames.contains(sname))
+ return QmlOpenMetaObject::createProperty(name, type);
}
return -1;
}
@@ -407,31 +424,42 @@ QFxVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuilder &pro
QString name = QLatin1String(prop.name());
if ((!data->m_model->m_listModelInterface || !data->m_model->m_abstractItemModel)
&& data->m_model->m_modelList) {
- return data->m_model->m_modelList->at(data->m_index);
+ if (name == QLatin1String("modelData")) {
+ if (data->m_model->m_modelList->type() == QmlListAccessor::Instance) {
+ QObject *object = data->m_model->m_modelList->at(0).value<QObject*>();
+ return object->metaObject()->property(1).read(object); // the first property after objectName
+ }
+ return data->m_model->m_modelList->at(data->m_index);
+ } else {
+ // return any property of a single object instance.
+ QObject *object = data->m_model->m_modelList->at(0).value<QObject*>();
+ return object->property(prop.name());
+ }
} else if (data->m_model->m_listModelInterface) {
data->m_model->ensureRoles();
- for (QHash<int, QString>::ConstIterator iter = data->m_model->m_roleNames.begin();
- iter != data->m_model->m_roleNames.end(); ++iter) {
-
- if (*iter == name) {
- roles.append(iter.key());
- QHash<int,QVariant> values = data->m_model->m_listModelInterface->data(data->m_index, QList<int>() << iter.key());
- if (values.isEmpty())
- return QVariant();
- else
- return values.value(iter.key());
- }
+ QHash<QString,int>::const_iterator it = data->m_model->m_roleNames.find(name);
+ if (it != data->m_model->m_roleNames.end()) {
+ roles.append(*it);
+ QHash<int,QVariant> values = data->m_model->m_listModelInterface->data(data->m_index, QList<int>() << *it);
+ if (values.isEmpty())
+ return QVariant();
+ else
+ return values.value(*it);
+ } else if (data->m_model->m_roles.count() == 1 && name == QLatin1String("modelData")) {
+ //for compatability with other lists, assign modelData if there is only a single role
+ QHash<int,QVariant> values = data->m_model->m_listModelInterface->data(data->m_index, QList<int>() << data->m_model->m_roles.first());
+ if (values.isEmpty())
+ return QVariant();
+ else
+ return *values.begin();
}
} else if (data->m_model->m_abstractItemModel) {
data->m_model->ensureRoles();
- for (QHash<int, QString>::ConstIterator iter = data->m_model->m_roleNames.begin();
- iter != data->m_model->m_roleNames.end(); ++iter) {
-
- if (*iter == name) {
- roles.append(iter.key());
- QModelIndex index = data->m_model->m_abstractItemModel->index(data->m_index, 0);
- return data->m_model->m_abstractItemModel->data(index, iter.key());
- }
+ QHash<QString,int>::const_iterator it = data->m_model->m_roleNames.find(name);
+ if (it != data->m_model->m_roleNames.end()) {
+ roles.append(*it);
+ QModelIndex index = data->m_model->m_abstractItemModel->index(data->m_index, 0);
+ return data->m_model->m_abstractItemModel->data(index, *it);
}
}
Q_ASSERT(!"Can never be reached");
@@ -505,10 +533,10 @@ QFxVisualDataModelPrivate::QFxVisualDataModelPrivate(QmlContext *ctxt)
QFxVisualDataModelData *QFxVisualDataModelPrivate::data(QObject *item)
{
- QList<QFxVisualDataModelData *> dataList =
- item->findChildren<QFxVisualDataModelData *>();
- Q_ASSERT(dataList.count() == 1);
- return dataList.first();
+ QFxVisualDataModelData *dataItem =
+ item->findChild<QFxVisualDataModelData *>();
+ Q_ASSERT(dataItem);
+ return dataItem;
}
QFxVisualDataModel::QFxVisualDataModel()
@@ -537,6 +565,8 @@ QVariant QFxVisualDataModel::model() const
void QFxVisualDataModel::setModel(const QVariant &model)
{
Q_D(QFxVisualDataModel);
+ delete d->m_modelList;
+ d->m_modelList = 0;
d->m_modelVariant = model;
if (d->m_listModelInterface) {
// Assume caller has released all items.
@@ -570,11 +600,11 @@ void QFxVisualDataModel::setModel(const QVariant &model)
d->m_visualItemModel = 0;
}
+ d->m_roles.clear();
+ d->m_roleNames.clear();
+
QObject *object = qvariant_cast<QObject *>(model);
if (object && (d->m_listModelInterface = qobject_cast<QListModelInterface *>(object))) {
- d->m_roles.clear();
- d->m_roleNames.clear();
-
QObject::connect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList<int>)),
this, SLOT(_q_itemsChanged(int,int,QList<int>)));
QObject::connect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)),
@@ -583,18 +613,10 @@ void QFxVisualDataModel::setModel(const QVariant &model)
this, SLOT(_q_itemsRemoved(int,int)));
QObject::connect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
this, SLOT(_q_itemsMoved(int,int,int)));
-
if (d->m_delegate && d->m_listModelInterface->count())
emit itemsInserted(0, d->m_listModelInterface->count());
return;
} else if (object && (d->m_abstractItemModel = qobject_cast<QAbstractItemModel *>(object))) {
- d->m_roles.clear();
- d->m_roleNames.clear();
- for (QHash<int,QByteArray>::const_iterator it = d->m_abstractItemModel->roleNames().begin();
- it != d->m_abstractItemModel->roleNames().end(); ++it) {
- d->m_roles.append(it.key());
- d->m_roleNames.insert(it.key(), QLatin1String(*it));
- }
QObject::connect(d->m_abstractItemModel, SIGNAL(rowsInserted(const QModelIndex &,int,int)),
this, SLOT(_q_rowsInserted(const QModelIndex &,int,int)));
QObject::connect(d->m_abstractItemModel, SIGNAL(rowsRemoved(const QModelIndex &,int,int)),
@@ -616,8 +638,7 @@ void QFxVisualDataModel::setModel(const QVariant &model)
this, SLOT(_q_destroyingPackage(QmlPackage*)));
return;
}
- if (!d->m_modelList)
- d->m_modelList = new QmlListAccessor;
+ d->m_modelList = new QmlListAccessor;
d->m_modelList->setList(model);
if (d->m_delegate && d->modelCount()) {
emit itemsInserted(0, d->modelCount());