Refactor QQuickVisualAdaptorModel to reduce memory consumption.
Don't inherit from QObject. Use a single QQmlGuard for all model types, and reset the model property if the model is deleted. Construct v8 object template on demand. Store model type specific data in a separate class that is allocated on demand. Change-Id: Id4f7b235741555b6ffba3fcf11727d85d6920e9e Reviewed-by: Martin Jones <martin.jones@nokia.com>
This commit is contained in:
parent
a96705e349
commit
f242e50a9f
File diff suppressed because it is too large
Load Diff
|
@ -42,75 +42,101 @@
|
|||
#ifndef QQUICKVISUALADAPTORMODEL_P_H
|
||||
#define QQUICKVISUALADAPTORMODEL_P_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qabstractitemmodel.h>
|
||||
|
||||
#include "private/qlistmodelinterface_p.h"
|
||||
#include "private/qquicklistaccessor_p.h"
|
||||
|
||||
#include <private/qqmlguard_p.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QQmlEngine;
|
||||
|
||||
class QQuickVisualDataModel;
|
||||
class QQuickVisualDataModelItem;
|
||||
class QQuickVisualDataModelItemMetaType;
|
||||
|
||||
class QQuickVisualAdaptorModelPrivate;
|
||||
class QQuickVisualAdaptorModel : public QObject
|
||||
class QQuickVisualAdaptorModel : public QQmlGuard<QObject>
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(QQuickVisualAdaptorModel)
|
||||
public:
|
||||
enum Flag
|
||||
class Accessors
|
||||
{
|
||||
ProxiedObject = 0x01
|
||||
public:
|
||||
inline Accessors() {}
|
||||
virtual int count(const QQuickVisualAdaptorModel &) const { return 0; }
|
||||
virtual void cleanup(QQuickVisualAdaptorModel &, QQuickVisualDataModel * = 0) const {}
|
||||
|
||||
virtual QString stringValue(const QQuickVisualAdaptorModel &, int, const QString &) const {
|
||||
return QString(); }
|
||||
|
||||
virtual QQuickVisualDataModelItem *createItem(
|
||||
QQuickVisualAdaptorModel &,
|
||||
QQuickVisualDataModelItemMetaType *,
|
||||
QQmlEngine *,
|
||||
int) const { return 0; }
|
||||
|
||||
virtual bool notify(
|
||||
const QQuickVisualAdaptorModel &,
|
||||
const QList<QQuickVisualDataModelItem *> &,
|
||||
int,
|
||||
int,
|
||||
const QList<int> &) const { return false; }
|
||||
virtual void replaceWatchedRoles(
|
||||
QQuickVisualAdaptorModel &,
|
||||
const QList<QByteArray> &,
|
||||
const QList<QByteArray> &) const {}
|
||||
virtual QVariant parentModelIndex(const QQuickVisualAdaptorModel &) const {
|
||||
return QVariant(); }
|
||||
virtual QVariant modelIndex(const QQuickVisualAdaptorModel &, int) const {
|
||||
return QVariant(); }
|
||||
virtual bool canFetchMore(const QQuickVisualAdaptorModel &) const { return false; }
|
||||
virtual void fetchMore(QQuickVisualAdaptorModel &) const {}
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
QQuickVisualAdaptorModel(QObject *parent = 0);
|
||||
virtual ~QQuickVisualAdaptorModel();
|
||||
const Accessors *accessors;
|
||||
QModelIndex rootIndex;
|
||||
QQuickListAccessor list;
|
||||
|
||||
Flags flags() const;
|
||||
QQuickVisualAdaptorModel();
|
||||
~QQuickVisualAdaptorModel();
|
||||
|
||||
QVariant model() const;
|
||||
void setModel(const QVariant &, QQmlEngine *);
|
||||
inline QVariant model() const { return list.list(); }
|
||||
void setModel(const QVariant &variant, QQuickVisualDataModel *vdm, QQmlEngine *engine);
|
||||
|
||||
QVariant rootIndex() const;
|
||||
void setRootIndex(const QVariant &root);
|
||||
inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); }
|
||||
inline const QAbstractItemModel *aim() const { return static_cast<const QAbstractItemModel *>(object()); }
|
||||
|
||||
QVariant modelIndex(int idx) const;
|
||||
QVariant parentModelIndex() const;
|
||||
inline QListModelInterface *lmi() { return static_cast<QListModelInterface *>(object()); }
|
||||
inline const QListModelInterface *lmi() const { return static_cast<const QListModelInterface *>(object()); }
|
||||
|
||||
int count() const;
|
||||
QQuickVisualDataModelItem *createItem(QQuickVisualDataModelItemMetaType *metaType, int index);
|
||||
QString stringValue(int index, const QString &role);
|
||||
void replaceWatchedRoles(const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles);
|
||||
inline int count() const { return qMax(0, accessors->count(*this)); }
|
||||
inline QString stringValue(int index, const QString &role) const {
|
||||
return accessors->stringValue(*this, index, role); }
|
||||
inline QQuickVisualDataModelItem *createItem(QQuickVisualDataModelItemMetaType *metaType, QQmlEngine *engine, int index) {
|
||||
return accessors->createItem(*this, metaType, engine, index); }
|
||||
inline bool hasProxyObject() const {
|
||||
return list.type() == QQuickListAccessor::Instance || list.type() == QQuickListAccessor::ListProperty; }
|
||||
|
||||
bool canFetchMore() const;
|
||||
void fetchMore();
|
||||
inline bool notify(
|
||||
const QList<QQuickVisualDataModelItem *> &items,
|
||||
int index,
|
||||
int count,
|
||||
const QList<int> &roles) const {
|
||||
return accessors->notify(*this, items, index, count, roles); }
|
||||
inline void replaceWatchedRoles(
|
||||
const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles) {
|
||||
accessors->replaceWatchedRoles(*this, oldRoles, newRoles); }
|
||||
|
||||
Q_SIGNALS:
|
||||
void rootIndexChanged();
|
||||
void modelReset(int oldCount, int newCount);
|
||||
inline QVariant modelIndex(int index) const { return accessors->modelIndex(*this, index); }
|
||||
inline QVariant parentModelIndex() const { return accessors->parentModelIndex(*this); }
|
||||
inline bool canFetchMore() const { return accessors->canFetchMore(*this); }
|
||||
inline void fetchMore() { return accessors->fetchMore(*this); }
|
||||
|
||||
void itemsInserted(int index, int count);
|
||||
void itemsRemoved(int index, int count);
|
||||
void itemsMoved(int from, int to, int count);
|
||||
void itemsChanged(int index, int count);
|
||||
|
||||
private Q_SLOTS:
|
||||
void _q_itemsChanged(int, int, const QList<int> &);
|
||||
void _q_itemsInserted(int index, int count);
|
||||
void _q_itemsRemoved(int index, int count);
|
||||
void _q_itemsMoved(int from, int to, int count);
|
||||
void _q_rowsInserted(const QModelIndex &,int,int);
|
||||
void _q_rowsRemoved(const QModelIndex &,int,int);
|
||||
void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
|
||||
void _q_dataChanged(const QModelIndex&,const QModelIndex&);
|
||||
void _q_layoutChanged();
|
||||
void _q_modelReset();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QQuickVisualAdaptorModel)
|
||||
protected:
|
||||
void objectDestroyed(QObject *);
|
||||
};
|
||||
|
||||
class QQuickVisualAdaptorModelProxyInterface
|
||||
|
|
|
@ -97,22 +97,22 @@ QHash<QObject*, QQuickVisualDataModelAttached*> QQuickVisualDataModelAttached::a
|
|||
*/
|
||||
|
||||
QQuickVisualDataModelPrivate::QQuickVisualDataModelPrivate(QQmlContext *ctxt)
|
||||
: m_adaptorModel(0)
|
||||
, m_delegate(0)
|
||||
: m_delegate(0)
|
||||
, m_cacheMetaType(0)
|
||||
, m_context(ctxt)
|
||||
, m_parts(0)
|
||||
, m_filterGroup(QStringLiteral("items"))
|
||||
, m_count(0)
|
||||
, m_groupCount(Compositor::MinimumGroupCount)
|
||||
, m_compositorGroup(Compositor::Cache)
|
||||
, m_complete(false)
|
||||
, m_delegateValidated(false)
|
||||
, m_reset(false)
|
||||
, m_transaction(false)
|
||||
, m_incubatorCleanupScheduled(false)
|
||||
, m_filterGroup(QStringLiteral("items"))
|
||||
, m_cacheItems(0)
|
||||
, m_items(0)
|
||||
, m_persistedItems(0)
|
||||
, m_groupCount(Compositor::MinimumGroupCount)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -121,25 +121,11 @@ QQuickVisualDataModelPrivate::~QQuickVisualDataModelPrivate()
|
|||
qDeleteAll(m_finishedIncubating);
|
||||
}
|
||||
|
||||
void QQuickVisualDataModelPrivate::connectModel(QQuickVisualAdaptorModel *model)
|
||||
{
|
||||
Q_Q(QQuickVisualDataModel);
|
||||
|
||||
QObject::connect(model, SIGNAL(itemsInserted(int,int)), q, SLOT(_q_itemsInserted(int,int)));
|
||||
QObject::connect(model, SIGNAL(itemsRemoved(int,int)), q, SLOT(_q_itemsRemoved(int,int)));
|
||||
QObject::connect(model, SIGNAL(itemsMoved(int,int,int)), q, SLOT(_q_itemsMoved(int,int,int)));
|
||||
QObject::connect(model, SIGNAL(itemsChanged(int,int)), q, SLOT(_q_itemsChanged(int,int)));
|
||||
QObject::connect(model, SIGNAL(modelReset(int,int)), q, SLOT(_q_modelReset(int,int)));
|
||||
}
|
||||
|
||||
void QQuickVisualDataModelPrivate::init()
|
||||
{
|
||||
Q_Q(QQuickVisualDataModel);
|
||||
m_compositor.setRemoveGroups(Compositor::GroupMask & ~Compositor::PersistedFlag);
|
||||
|
||||
m_adaptorModel = new QQuickVisualAdaptorModel;
|
||||
QObject::connect(m_adaptorModel, SIGNAL(rootIndexChanged()), q, SIGNAL(rootIndexChanged()));
|
||||
|
||||
m_items = new QQuickVisualDataGroup(QStringLiteral("items"), q, Compositor::Default, q);
|
||||
m_items->setDefaultInclude(true);
|
||||
m_persistedItems = new QQuickVisualDataGroup(QStringLiteral("persistedItems"), q, Compositor::Persisted, q);
|
||||
|
@ -176,7 +162,6 @@ QQuickVisualDataModel::~QQuickVisualDataModel()
|
|||
delete cacheItem;
|
||||
}
|
||||
|
||||
delete d->m_adaptorModel;
|
||||
if (d->m_cacheMetaType)
|
||||
d->m_cacheMetaType->release();
|
||||
}
|
||||
|
@ -184,6 +169,9 @@ QQuickVisualDataModel::~QQuickVisualDataModel()
|
|||
|
||||
void QQuickVisualDataModel::classBegin()
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (!d->m_context)
|
||||
d->m_context = qmlContext(this);
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::componentComplete()
|
||||
|
@ -219,8 +207,6 @@ void QQuickVisualDataModel::componentComplete()
|
|||
defaultGroups |= (1 << i);
|
||||
}
|
||||
}
|
||||
if (!d->m_context)
|
||||
d->m_context = qmlContext(this);
|
||||
|
||||
d->m_cacheMetaType = new QQuickVisualDataModelItemMetaType(
|
||||
QQmlEnginePrivate::getV8Engine(d->m_context->engine()), this, groupNames);
|
||||
|
@ -232,18 +218,18 @@ void QQuickVisualDataModel::componentComplete()
|
|||
while (!d->m_pendingParts.isEmpty())
|
||||
static_cast<QQuickVisualPartsModel *>(d->m_pendingParts.first())->updateFilterGroup();
|
||||
|
||||
d->connectModel(d->m_adaptorModel);
|
||||
QVector<Compositor::Insert> inserts;
|
||||
d->m_count = d->m_adaptorModel.count();
|
||||
d->m_compositor.append(
|
||||
d->m_adaptorModel,
|
||||
&d->m_adaptorModel,
|
||||
0,
|
||||
qMax(0, d->m_adaptorModel->count()),
|
||||
d->m_count,
|
||||
defaultGroups | Compositor::AppendFlag | Compositor::PrependFlag,
|
||||
&inserts);
|
||||
d->itemsInserted(inserts);
|
||||
d->emitChanges();
|
||||
|
||||
if (d->m_adaptorModel->canFetchMore())
|
||||
if (d->m_adaptorModel.canFetchMore())
|
||||
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
|
||||
}
|
||||
|
||||
|
@ -264,15 +250,28 @@ void QQuickVisualDataModel::componentComplete()
|
|||
QVariant QQuickVisualDataModel::model() const
|
||||
{
|
||||
Q_D(const QQuickVisualDataModel);
|
||||
return d->m_adaptorModel->model();
|
||||
return d->m_adaptorModel.model();
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::setModel(const QVariant &model)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
d->m_adaptorModel->setModel(model, d->m_context ? d->m_context->engine() : qmlEngine(this));
|
||||
if (d->m_complete && d->m_adaptorModel->canFetchMore())
|
||||
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
|
||||
|
||||
if (d->m_complete)
|
||||
_q_itemsRemoved(0, d->m_count);
|
||||
|
||||
d->m_adaptorModel.setModel(model, this, d->m_context->engine());
|
||||
d->m_adaptorModel.replaceWatchedRoles(QList<QByteArray>(), d->m_watchedRoles);
|
||||
for (int i = 0; d->m_parts && i < d->m_parts->models.count(); ++i) {
|
||||
d->m_adaptorModel.replaceWatchedRoles(
|
||||
QList<QByteArray>(), d->m_parts->models.at(i)->watchedRoles());
|
||||
}
|
||||
|
||||
if (d->m_complete) {
|
||||
_q_itemsInserted(0, d->m_adaptorModel.count());
|
||||
if (d->m_adaptorModel.canFetchMore())
|
||||
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -345,13 +344,28 @@ void QQuickVisualDataModel::setDelegate(QQmlComponent *delegate)
|
|||
QVariant QQuickVisualDataModel::rootIndex() const
|
||||
{
|
||||
Q_D(const QQuickVisualDataModel);
|
||||
return d->m_adaptorModel->rootIndex();
|
||||
return QVariant::fromValue(d->m_adaptorModel.rootIndex);
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::setRootIndex(const QVariant &root)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
d->m_adaptorModel->setRootIndex(root);
|
||||
|
||||
QModelIndex modelIndex = qvariant_cast<QModelIndex>(root);
|
||||
if (d->m_adaptorModel.rootIndex != modelIndex) {
|
||||
const int oldCount = d->m_count;
|
||||
d->m_adaptorModel.rootIndex = modelIndex;
|
||||
if (d->m_adaptorModel.canFetchMore())
|
||||
d->m_adaptorModel.fetchMore();
|
||||
if (d->m_complete) {
|
||||
const int newCount = d->m_adaptorModel.count();
|
||||
if (oldCount)
|
||||
_q_itemsRemoved(0, oldCount);
|
||||
if (newCount)
|
||||
_q_itemsInserted(0, newCount);
|
||||
}
|
||||
emit rootIndexChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -369,7 +383,7 @@ void QQuickVisualDataModel::setRootIndex(const QVariant &root)
|
|||
QVariant QQuickVisualDataModel::modelIndex(int idx) const
|
||||
{
|
||||
Q_D(const QQuickVisualDataModel);
|
||||
return d->m_adaptorModel->modelIndex(idx);
|
||||
return d->m_adaptorModel.modelIndex(idx);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -387,7 +401,7 @@ QVariant QQuickVisualDataModel::modelIndex(int idx) const
|
|||
QVariant QQuickVisualDataModel::parentModelIndex() const
|
||||
{
|
||||
Q_D(const QQuickVisualDataModel);
|
||||
return d->m_adaptorModel->parentModelIndex();
|
||||
return d->m_adaptorModel.parentModelIndex();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -791,7 +805,10 @@ QObject *QQuickVisualDataModelPrivate::object(Compositor::Group group, int index
|
|||
QQuickVisualDataModelItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0;
|
||||
|
||||
if (!cacheItem) {
|
||||
cacheItem = m_adaptorModel->createItem(m_cacheMetaType, it.modelIndex());
|
||||
cacheItem = m_adaptorModel.createItem(m_cacheMetaType, m_context->engine(), it.modelIndex());
|
||||
if (!cacheItem)
|
||||
return 0;
|
||||
|
||||
for (int i = 1; i < m_groupCount; ++i)
|
||||
cacheItem->index[i] = it.index[i];
|
||||
|
||||
|
@ -813,9 +830,9 @@ QObject *QQuickVisualDataModelPrivate::object(Compositor::Group group, int index
|
|||
|
||||
QQmlContext *creationContext = m_delegate->creationContext();
|
||||
QQmlContext *rootContext = new QQuickVisualDataModelContext(
|
||||
cacheItem, creationContext ? creationContext : m_context.data());
|
||||
cacheItem, creationContext ? creationContext : m_context);
|
||||
QQmlContext *ctxt = rootContext;
|
||||
if (m_adaptorModel->flags() & QQuickVisualAdaptorModel::ProxiedObject) {
|
||||
if (m_adaptorModel.hasProxyObject()) {
|
||||
if (QQuickVisualAdaptorModelProxyInterface *proxy = qobject_cast<QQuickVisualAdaptorModelProxyInterface *>(cacheItem)) {
|
||||
ctxt->setContextObject(proxy->proxiedObject());
|
||||
ctxt = new QQuickVisualDataModelContext(cacheItem, ctxt, ctxt);
|
||||
|
@ -829,7 +846,7 @@ QObject *QQuickVisualDataModelPrivate::object(Compositor::Group group, int index
|
|||
m_delegate->create(*incubator, ctxt, m_context);
|
||||
}
|
||||
|
||||
if (index == m_compositor.count(group) - 1 && m_adaptorModel->canFetchMore())
|
||||
if (index == m_compositor.count(group) - 1 && m_adaptorModel.canFetchMore())
|
||||
QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
|
||||
if (cacheItem->object && reference)
|
||||
cacheItem->referenceObject();
|
||||
|
@ -894,8 +911,8 @@ int QQuickVisualDataModel::indexOf(QQuickItem *item, QObject *) const
|
|||
void QQuickVisualDataModel::setWatchedRoles(QList<QByteArray> roles)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
d->m_adaptorModel->replaceWatchedRoles(d->watchedRoles, roles);
|
||||
d->watchedRoles = roles;
|
||||
d->m_adaptorModel.replaceWatchedRoles(d->m_watchedRoles, roles);
|
||||
d->m_watchedRoles = roles;
|
||||
}
|
||||
|
||||
void QQuickVisualDataModelPrivate::addGroups(
|
||||
|
@ -936,7 +953,7 @@ bool QQuickVisualDataModel::event(QEvent *e)
|
|||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (e->type() == QEvent::UpdateRequest) {
|
||||
d->m_adaptorModel->fetchMore();
|
||||
d->m_adaptorModel.fetchMore();
|
||||
} else if (e->type() == QEvent::User) {
|
||||
d->m_incubatorCleanupScheduled = false;
|
||||
qDeleteAll(d->m_finishedIncubating);
|
||||
|
@ -955,8 +972,7 @@ void QQuickVisualDataModelPrivate::itemsChanged(const QVector<Compositor::Change
|
|||
foreach (const Compositor::Change &change, changes) {
|
||||
for (int i = 1; i < m_groupCount; ++i) {
|
||||
if (change.inGroup(i)) {
|
||||
translatedChanges[i].append(
|
||||
QQuickChangeSet::Change(change.index[i], change.count));
|
||||
translatedChanges[i].append(QQuickChangeSet::Change(change.index[i], change.count));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -965,15 +981,18 @@ void QQuickVisualDataModelPrivate::itemsChanged(const QVector<Compositor::Change
|
|||
QQuickVisualDataGroupPrivate::get(m_groups[i])->changeSet.apply(translatedChanges.at(i));
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::_q_itemsChanged(int index, int count)
|
||||
void QQuickVisualDataModel::_q_itemsChanged(int index, int count, const QList<int> &roles)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (count <= 0)
|
||||
if (count <= 0 || !d->m_complete)
|
||||
return;
|
||||
QVector<Compositor::Change> changes;
|
||||
d->m_compositor.listItemsChanged(d->m_adaptorModel, index, count, &changes);
|
||||
d->itemsChanged(changes);
|
||||
d->emitChanges();
|
||||
|
||||
if (d->m_adaptorModel.notify(d->m_cache, index, count, roles)) {
|
||||
QVector<Compositor::Change> changes;
|
||||
d->m_compositor.listItemsChanged(&d->m_adaptorModel, index, count, &changes);
|
||||
d->itemsChanged(changes);
|
||||
d->emitChanges();
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickVisualDataModelPrivate::itemsInserted(
|
||||
|
@ -1046,10 +1065,19 @@ void QQuickVisualDataModel::_q_itemsInserted(int index, int count)
|
|||
{
|
||||
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (count <= 0)
|
||||
if (count <= 0 || !d->m_complete)
|
||||
return;
|
||||
|
||||
d->m_count += count;
|
||||
|
||||
for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
|
||||
QQuickVisualDataModelItem *item = d->m_cache.at(i);
|
||||
if (item->modelIndex() >= index)
|
||||
item->setModelIndex(item->modelIndex() + count);
|
||||
}
|
||||
|
||||
QVector<Compositor::Insert> inserts;
|
||||
d->m_compositor.listItemsInserted(d->m_adaptorModel, index, count, &inserts);
|
||||
d->m_compositor.listItemsInserted(&d->m_adaptorModel, index, count, &inserts);
|
||||
d->itemsInserted(inserts);
|
||||
d->emitChanges();
|
||||
}
|
||||
|
@ -1143,11 +1171,21 @@ void QQuickVisualDataModelPrivate::itemsRemoved(const QVector<Compositor::Remove
|
|||
void QQuickVisualDataModel::_q_itemsRemoved(int index, int count)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (count <= 0)
|
||||
if (count <= 0|| !d->m_complete)
|
||||
return;
|
||||
|
||||
d->m_count -= count;
|
||||
|
||||
for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
|
||||
QQuickVisualDataModelItem *item = d->m_cache.at(i);
|
||||
if (item->modelIndex() >= index + count)
|
||||
item->setModelIndex(item->modelIndex() - count);
|
||||
else if (item->modelIndex() >= index)
|
||||
item->setModelIndex(-1);
|
||||
}
|
||||
|
||||
QVector<Compositor::Remove> removes;
|
||||
d->m_compositor.listItemsRemoved(d->m_adaptorModel, index, count, &removes);
|
||||
d->m_compositor.listItemsRemoved(&d->m_adaptorModel, index, count, &removes);
|
||||
d->itemsRemoved(removes);
|
||||
|
||||
d->emitChanges();
|
||||
|
@ -1178,12 +1216,24 @@ void QQuickVisualDataModelPrivate::itemsMoved(
|
|||
void QQuickVisualDataModel::_q_itemsMoved(int from, int to, int count)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (count <= 0)
|
||||
if (count <= 0 || !d->m_complete)
|
||||
return;
|
||||
|
||||
const int minimum = qMin(from, to);
|
||||
const int maximum = qMax(from, to) + count;
|
||||
const int difference = from > to ? count : -count;
|
||||
|
||||
for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
|
||||
QQuickVisualDataModelItem *item = d->m_cache.at(i);
|
||||
if (item->modelIndex() >= from && item->modelIndex() < from + count)
|
||||
item->setModelIndex(item->modelIndex() - from + to);
|
||||
else if (item->modelIndex() >= minimum && item->modelIndex() < maximum)
|
||||
item->setModelIndex(item->modelIndex() + difference);
|
||||
}
|
||||
|
||||
QVector<Compositor::Remove> removes;
|
||||
QVector<Compositor::Insert> inserts;
|
||||
d->m_compositor.listItemsMoved(d->m_adaptorModel, from, to, count, &removes, &inserts);
|
||||
d->m_compositor.listItemsMoved(&d->m_adaptorModel, from, to, count, &removes, &inserts);
|
||||
d->itemsMoved(removes, inserts);
|
||||
d->emitChanges();
|
||||
}
|
||||
|
@ -1236,21 +1286,81 @@ void QQuickVisualDataModelPrivate::emitChanges()
|
|||
}
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::_q_modelReset(int oldCount, int newCount)
|
||||
void QQuickVisualDataModel::_q_modelReset()
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (!d->m_delegate)
|
||||
return;
|
||||
|
||||
QVector<Compositor::Remove> removes;
|
||||
QVector<Compositor::Insert> inserts;
|
||||
if (oldCount)
|
||||
d->m_compositor.listItemsRemoved(d->m_adaptorModel, 0, oldCount, &removes);
|
||||
if (newCount)
|
||||
d->m_compositor.listItemsInserted(d->m_adaptorModel, 0, newCount, &inserts);
|
||||
d->itemsMoved(removes, inserts);
|
||||
d->m_reset = true;
|
||||
d->emitChanges();
|
||||
int oldCount = d->m_count;
|
||||
d->m_adaptorModel.rootIndex = QModelIndex();
|
||||
|
||||
if (d->m_complete) {
|
||||
d->m_count = d->m_adaptorModel.count();
|
||||
|
||||
for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
|
||||
QQuickVisualDataModelItem *item = d->m_cache.at(i);
|
||||
if (item->modelIndex() != -1)
|
||||
item->setModelIndex(-1);
|
||||
}
|
||||
|
||||
QVector<Compositor::Remove> removes;
|
||||
QVector<Compositor::Insert> inserts;
|
||||
if (oldCount)
|
||||
d->m_compositor.listItemsRemoved(&d->m_adaptorModel, 0, oldCount, &removes);
|
||||
if (d->m_count)
|
||||
d->m_compositor.listItemsInserted(&d->m_adaptorModel, 0, d->m_count, &inserts);
|
||||
d->itemsMoved(removes, inserts);
|
||||
d->m_reset = true;
|
||||
|
||||
if (d->m_adaptorModel.canFetchMore())
|
||||
d->m_adaptorModel.fetchMore();
|
||||
|
||||
d->emitChanges();
|
||||
}
|
||||
emit rootIndexChanged();
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (parent == d->m_adaptorModel.rootIndex)
|
||||
_q_itemsInserted(begin, end - begin + 1);
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (parent == d->m_adaptorModel.rootIndex)
|
||||
_q_itemsRemoved(begin, end - begin + 1);
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::_q_rowsMoved(
|
||||
const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
|
||||
const QModelIndex &destinationParent, int destinationRow)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
const int count = sourceEnd - sourceStart + 1;
|
||||
if (destinationParent == d->m_adaptorModel.rootIndex && sourceParent == d->m_adaptorModel.rootIndex) {
|
||||
_q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow - count, count);
|
||||
} else if (sourceParent == d->m_adaptorModel.rootIndex) {
|
||||
_q_itemsRemoved(sourceStart, count);
|
||||
} else if (destinationParent == d->m_adaptorModel.rootIndex) {
|
||||
_q_itemsInserted(destinationRow, count);
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end)
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
if (begin.parent() == d->m_adaptorModel.rootIndex)
|
||||
_q_itemsChanged(begin.row(), end.row() - begin.row() + 1, QList<int>());
|
||||
}
|
||||
|
||||
void QQuickVisualDataModel::_q_layoutChanged()
|
||||
{
|
||||
Q_D(QQuickVisualDataModel);
|
||||
_q_itemsChanged(0, d->m_count, QList<int>());
|
||||
}
|
||||
|
||||
QQuickVisualDataModelAttached *QQuickVisualDataModel::qmlAttachedProperties(QObject *obj)
|
||||
|
@ -1261,7 +1371,7 @@ QQuickVisualDataModelAttached *QQuickVisualDataModel::qmlAttachedProperties(QObj
|
|||
bool QQuickVisualDataModelPrivate::insert(
|
||||
Compositor::insert_iterator &before, const v8::Local<v8::Object> &object, int groups)
|
||||
{
|
||||
QQuickVisualDataModelItem *cacheItem = m_adaptorModel->createItem(m_cacheMetaType, -1);
|
||||
QQuickVisualDataModelItem *cacheItem = m_adaptorModel.createItem(m_cacheMetaType, m_context->engine(), -1);
|
||||
if (!cacheItem)
|
||||
return false;
|
||||
|
||||
|
@ -1497,11 +1607,11 @@ v8::Handle<v8::Value> QQuickVisualDataModelItemMetaType::get_index(
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
QQuickVisualDataModelItem::QQuickVisualDataModelItem(QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int modelIndex)
|
||||
QQuickVisualDataModelItem::QQuickVisualDataModelItem(
|
||||
QQuickVisualDataModelItemMetaType *metaType, int modelIndex)
|
||||
: QV8ObjectResource(metaType->v8Engine)
|
||||
, metaType(metaType)
|
||||
, model(model)
|
||||
, object(0)
|
||||
, metaType(metaType)
|
||||
, attached(0)
|
||||
, objectRef(0)
|
||||
, scriptRef(0)
|
||||
|
@ -1926,7 +2036,10 @@ QQmlV8Handle QQuickVisualDataGroup::get(int index)
|
|||
: 0;
|
||||
|
||||
if (!cacheItem) {
|
||||
cacheItem = model->m_adaptorModel->createItem(model->m_cacheMetaType, it.modelIndex());
|
||||
cacheItem = model->m_adaptorModel.createItem(
|
||||
model->m_cacheMetaType, model->m_context->engine(), it.modelIndex());
|
||||
if (!cacheItem)
|
||||
return QQmlV8Handle::fromHandle(v8::Undefined());
|
||||
for (int i = 1; i < model->m_groupCount; ++i)
|
||||
cacheItem->index[i] = it.index[i];
|
||||
cacheItem->groups = it->flags;
|
||||
|
@ -2157,7 +2270,7 @@ void QQuickVisualDataGroup::resolve(QQmlV8Function *args)
|
|||
delete cacheItem;
|
||||
Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache));
|
||||
} else {
|
||||
cacheItem->resolveIndex(resolvedIndex);
|
||||
cacheItem->resolveIndex(model->m_adaptorModel, resolvedIndex);
|
||||
if (cacheItem->object)
|
||||
cacheItem->attached->emitUnresolvedChanged();
|
||||
}
|
||||
|
@ -2580,7 +2693,7 @@ QString QQuickVisualPartsModel::stringValue(int index, const QString &role)
|
|||
void QQuickVisualPartsModel::setWatchedRoles(QList<QByteArray> roles)
|
||||
{
|
||||
QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model);
|
||||
model->m_adaptorModel->replaceWatchedRoles(m_watchedRoles, roles);
|
||||
model->m_adaptorModel.replaceWatchedRoles(m_watchedRoles, roles);
|
||||
m_watchedRoles = roles;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,11 +131,17 @@ Q_SIGNALS:
|
|||
void rootIndexChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void _q_itemsChanged(int index, int count);
|
||||
void _q_itemsChanged(int index, int count, const QList<int> &roles);
|
||||
void _q_itemsInserted(int index, int count);
|
||||
void _q_itemsRemoved(int index, int count);
|
||||
void _q_itemsMoved(int from, int to, int count);
|
||||
void _q_modelReset(int oldCount, int newCount);
|
||||
void _q_modelReset();
|
||||
void _q_rowsInserted(const QModelIndex &,int,int);
|
||||
void _q_rowsRemoved(const QModelIndex &,int,int);
|
||||
void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
|
||||
void _q_dataChanged(const QModelIndex&,const QModelIndex&);
|
||||
void _q_layoutChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QQuickVisualDataModel)
|
||||
};
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
#include "qquickvisualdatamodel_p.h"
|
||||
|
||||
#include "qquickvisualadaptormodel_p.h"
|
||||
|
||||
#include <QtQml/qqmlcontext.h>
|
||||
#include <QtQml/qqmlincubator.h>
|
||||
|
||||
|
@ -105,8 +107,7 @@ class QQuickVisualDataModelItem : public QObject, public QV8ObjectResource
|
|||
Q_PROPERTY(QObject *model READ modelObject CONSTANT)
|
||||
V8_RESOURCE_TYPE(VisualDataItemType)
|
||||
public:
|
||||
QQuickVisualDataModelItem(
|
||||
QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int modelIndex);
|
||||
QQuickVisualDataModelItem(QQuickVisualDataModelItemMetaType *metaType, int modelIndex);
|
||||
~QQuickVisualDataModelItem();
|
||||
|
||||
void referenceObject() { ++objectRef; }
|
||||
|
@ -129,15 +130,14 @@ public:
|
|||
virtual v8::Handle<v8::Value> get() { return engine->newQObject(this); }
|
||||
|
||||
virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
|
||||
virtual bool resolveIndex(int) { return false; }
|
||||
virtual bool resolveIndex(const QQuickVisualAdaptorModel &, int) { return false; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void modelIndexChanged();
|
||||
|
||||
public:
|
||||
QQuickVisualDataModelItemMetaType * const metaType;
|
||||
QQmlGuard<QQuickVisualAdaptorModel> model;
|
||||
QQmlGuard<QObject> object;
|
||||
QQuickVisualDataModelItemMetaType * const metaType;
|
||||
QQuickVisualDataModelAttached *attached;
|
||||
v8::Persistent<v8::Object> indexHandle;
|
||||
v8::Persistent<v8::Value> modelHandle;
|
||||
|
@ -277,16 +277,24 @@ public:
|
|||
void incubatorStatusChanged(QVDMIncubationTask *incubationTask, QQmlIncubator::Status status);
|
||||
void setInitialState(QVDMIncubationTask *incubationTask, QObject *o);
|
||||
|
||||
QQuickVisualAdaptorModel *m_adaptorModel;
|
||||
QQuickVisualAdaptorModel m_adaptorModel;
|
||||
QQuickListCompositor m_compositor;
|
||||
QQmlComponent *m_delegate;
|
||||
QQuickVisualDataModelItemMetaType *m_cacheMetaType;
|
||||
QQmlGuard<QQmlContext> m_context;
|
||||
|
||||
QList<QQuickVisualDataModelItem *> m_cache;
|
||||
QQmlContext *m_context;
|
||||
QQuickVisualDataModelParts *m_parts;
|
||||
QQuickVisualDataGroupEmitterList m_pendingParts;
|
||||
|
||||
QQuickListCompositor m_compositor;
|
||||
QList<QQuickVisualDataModelItem *> m_cache;
|
||||
QList<QVDMIncubationTask *> m_finishedIncubating;
|
||||
QList<QByteArray> m_watchedRoles;
|
||||
|
||||
QString m_filterGroup;
|
||||
|
||||
|
||||
int m_count;
|
||||
int m_groupCount;
|
||||
|
||||
QQuickListCompositor::Group m_compositorGroup;
|
||||
bool m_complete : 1;
|
||||
bool m_delegateValidated : 1;
|
||||
|
@ -294,9 +302,6 @@ public:
|
|||
bool m_transaction : 1;
|
||||
bool m_incubatorCleanupScheduled : 1;
|
||||
|
||||
QString m_filterGroup;
|
||||
QList<QByteArray> watchedRoles;
|
||||
|
||||
union {
|
||||
struct {
|
||||
QQuickVisualDataGroup *m_cacheItems;
|
||||
|
@ -305,9 +310,6 @@ public:
|
|||
};
|
||||
QQuickVisualDataGroup *m_groups[Compositor::MaximumGroupCount];
|
||||
};
|
||||
int m_groupCount;
|
||||
|
||||
QList<QVDMIncubationTask *> m_finishedIncubating;
|
||||
};
|
||||
|
||||
class QQuickVisualPartsModel : public QQuickVisualModel, public QQuickVisualDataGroupEmitter
|
||||
|
@ -329,6 +331,7 @@ public:
|
|||
QQuickItem *item(int index, bool asynchronous=false);
|
||||
ReleaseFlags release(QQuickItem *item);
|
||||
QString stringValue(int index, const QString &role);
|
||||
QList<QByteArray> watchedRoles() const { return m_watchedRoles; }
|
||||
void setWatchedRoles(QList<QByteArray> roles);
|
||||
|
||||
int indexOf(QQuickItem *item, QObject *objectContext) const;
|
||||
|
|
|
@ -82,7 +82,7 @@ static void initStandardTreeModel(QStandardItemModel *model)
|
|||
class SingleRoleModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QStringList values WRITE setList)
|
||||
Q_PROPERTY(QStringList values READ getList WRITE setList)
|
||||
public:
|
||||
SingleRoleModel(const QByteArray &role = "name", QObject *parent = 0)
|
||||
: QAbstractListModel(parent)
|
||||
|
@ -100,6 +100,7 @@ public:
|
|||
|
||||
QStringList list;
|
||||
|
||||
QStringList getList() const { return list; }
|
||||
void setList(const QStringList &l) { list = l; }
|
||||
|
||||
public slots:
|
||||
|
@ -122,9 +123,10 @@ protected:
|
|||
class StandardItem : public QObject, public QStandardItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString text WRITE setText)
|
||||
Q_PROPERTY(QString text READ readText WRITE setText)
|
||||
|
||||
public:
|
||||
QString readText() const { return text(); }
|
||||
void writeText(const QString &text) { setText(text); }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue