diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-04-07 04:01:41 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-04-07 04:01:41 (GMT) |
commit | d4e0060d3e8961f0c802289dd6eebf9688be2fc7 (patch) | |
tree | 472590cd15e6372e32ad334dcdd3cb4cc731f02a /src | |
parent | 19a566f82a7c684423331a8caab70ec594afd1ce (diff) | |
parent | f2d08b168a116dd048ec1a38dd3b710de08a4a8e (diff) | |
download | Qt-d4e0060d3e8961f0c802289dd6eebf9688be2fc7.zip Qt-d4e0060d3e8961f0c802289dd6eebf9688be2fc7.tar.gz Qt-d4e0060d3e8961f0c802289dd6eebf9688be2fc7.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-qml:
Cleanup minehunt example
Keep track of the item count to avoid calling model->count() during batched changes
Allow iteration over the Item.children property
Add QListModelInterface::modelReset() signal and emit this in
Compile
Allow MouseArea.Drag.target to be reset.
Document MouseEvent.accepted.
Initialize drag movement correctly if drag.target is set after mouse move.
Expand test.
Honor the startDragThreshold in MouseArea drag.
Don't crash if a target isn't specified for AnchorChanges.
Optimization: Only allocate QScriptValue if we need too
Crash: Assign context in CreateSimpleObject too
Optimization: Minor object allocation speedup
Optimization: Improve allocation strategy for QDeclarativeDeclarativeData
Diffstat (limited to 'src')
25 files changed, 259 insertions, 78 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 330de20..411f22e 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -125,8 +125,10 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) } } +void (*QDeclarativeData::destroyed)(QDeclarativeData *, QObject *) = 0; +void (*QDeclarativeData::parentChanged)(QDeclarativeData *, QObject *, QObject *) = 0; + QObjectData::~QObjectData() {} -QDeclarativeData::~QDeclarativeData() {} QObjectPrivate::QObjectPrivate(int version) : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0) @@ -876,7 +878,7 @@ QObject::~QObject() } if (d->declarativeData) - d->declarativeData->destroyed(this); + QDeclarativeData::destroyed(d->declarativeData, this); { QMutex *signalSlotMutex = 0; @@ -2025,7 +2027,7 @@ void QObjectPrivate::setParent_helper(QObject *o) } } if (!wasDeleted && declarativeData) - declarativeData->parentChanged(q, o); + QDeclarativeData::parentChanged(declarativeData, q, o); } /*! diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 3b59abb..e5d904c 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -87,9 +87,8 @@ enum { QObjectPrivateVersion = QT_VERSION }; class Q_CORE_EXPORT QDeclarativeData { public: - virtual ~QDeclarativeData(); - virtual void destroyed(QObject *) = 0; - virtual void parentChanged(QObject *, QObject *) = 0; + static void (*destroyed)(QDeclarativeData *, QObject *); + static void (*parentChanged)(QDeclarativeData *, QObject *, QObject *); }; class Q_CORE_EXPORT QObjectPrivate : public QObjectData diff --git a/src/declarative/3rdparty/qlistmodelinterface.cpp b/src/declarative/3rdparty/qlistmodelinterface.cpp index 98d6a5b..20501a0 100644 --- a/src/declarative/3rdparty/qlistmodelinterface.cpp +++ b/src/declarative/3rdparty/qlistmodelinterface.cpp @@ -106,4 +106,10 @@ QT_BEGIN_NAMESPACE \a roles changed. */ +/*! \fn void QListModelInterface::modelReset() + Emit this signal when all of the model data has changed. + This is more efficient than forcing the receivier to handle multiple + inserted and removed signals etc. +*/ + QT_END_NAMESPACE diff --git a/src/declarative/3rdparty/qlistmodelinterface_p.h b/src/declarative/3rdparty/qlistmodelinterface_p.h index 07592ad..da91d12 100644 --- a/src/declarative/3rdparty/qlistmodelinterface_p.h +++ b/src/declarative/3rdparty/qlistmodelinterface_p.h @@ -72,6 +72,7 @@ class Q_DECLARATIVE_EXPORT QListModelInterface : public QObject void itemsRemoved(int index, int count); void itemsMoved(int from, int to, int count); void itemsChanged(int index, int count, const QList<int> &roles); + void modelReset(); protected: QListModelInterface(QObjectPrivate &dd, QObject *parent) diff --git a/src/declarative/graphicsitems/qdeclarativeevents.cpp b/src/declarative/graphicsitems/qdeclarativeevents.cpp index 6118ea8..a181071 100644 --- a/src/declarative/graphicsitems/qdeclarativeevents.cpp +++ b/src/declarative/graphicsitems/qdeclarativeevents.cpp @@ -133,6 +133,17 @@ Item { These properties hold the position of the mouse event. */ + +/*! + \qmlproperty bool MouseEvent::accepted + + Setting \a accepted to true prevents the mouse event from being + propagated to items below this item. + + Generally, if the item acts on the mouse event then it should be accepted + so that items lower in the stacking order do not also respond to the same event. +*/ + /*! \qmlproperty enum MouseEvent::button diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 8247f17..3ad18cf 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -102,7 +102,7 @@ public: QDeclarativeGridViewPrivate() : currentItem(0), flow(QDeclarativeGridView::LeftToRight) , visibleIndex(0) , currentIndex(-1) - , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1) + , cellWidth(100), cellHeight(100), columns(1), itemCount(0), requestedIndex(-1) , highlightRangeStart(0), highlightRangeEnd(0), highlightRange(QDeclarativeGridView::NoHighlightRange) , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0) @@ -315,6 +315,7 @@ public: int cellHeight; int columns; int requestedIndex; + int itemCount; qreal highlightRangeStart; qreal highlightRangeEnd; QDeclarativeGridView::HighlightRangeMode highlightRange; @@ -358,6 +359,7 @@ void QDeclarativeGridViewPrivate::clear() currentItem = 0; createHighlight(); trackedItem = 0; + itemCount = 0; } FxGridItem *QDeclarativeGridViewPrivate::createItem(int modelIndex) @@ -403,6 +405,7 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (!isValid() || !q->isComponentComplete()) return; + itemCount = model->count(); qreal bufferFrom = from - buffer; qreal bufferTo = to + buffer; qreal fillFrom = from; @@ -546,6 +549,10 @@ void QDeclarativeGridViewPrivate::layout() { Q_Q(QDeclarativeGridView); layoutScheduled = false; + if (!isValid()) { + clear(); + return; + } if (visibleItems.count()) { qreal rowPos = visibleItems.first()->rowPos(); qreal colPos = visibleItems.first()->colPos(); @@ -1780,13 +1787,15 @@ void QDeclarativeGridView::componentComplete() { Q_D(QDeclarativeGridView); QDeclarativeFlickable::componentComplete(); - d->updateGrid(); - refill(); - if (d->currentIndex < 0) - d->updateCurrent(0); - else - d->updateCurrent(d->currentIndex); - d->fixupPosition(); + if (d->isValid()) { + d->updateGrid(); + refill(); + if (d->currentIndex < 0) + d->updateCurrent(0); + else + d->updateCurrent(d->currentIndex); + d->fixupPosition(); + } } void QDeclarativeGridView::trackedPositionChanged() @@ -1859,6 +1868,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) } else if (d->currentIndex < 0) { d->updateCurrent(0); } + d->itemCount += count; emit countChanged(); return; } @@ -1889,6 +1899,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) emit currentIndexChanged(); } d->scheduleLayout(); + d->itemCount += count; emit countChanged(); return; } @@ -1976,6 +1987,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) for (int j = 0; j < added.count(); ++j) added.at(j)->attached->emitAdd(); + d->itemCount += count; emit countChanged(); } @@ -1984,6 +1996,8 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) Q_D(QDeclarativeGridView); if (!isComponentComplete()) return; + + d->itemCount -= count; bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count; bool removedVisible = false; @@ -2031,7 +2045,8 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) d->releaseItem(d->currentItem); d->currentItem = 0; d->currentIndex = -1; - d->updateCurrent(qMin(modelIndex, d->model->count()-1)); + if (d->itemCount) + d->updateCurrent(qMin(modelIndex, d->itemCount-1)); } // update visibleIndex @@ -2046,7 +2061,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) if (removedVisible && d->visibleItems.isEmpty()) { d->timeline.clear(); d->setPosition(0); - if (d->model->count() == 0) + if (d->itemCount == 0) update(); } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index e85d60f..31d97f3 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -152,7 +152,7 @@ public: : currentItem(0), orient(QDeclarativeListView::Vertical) , visiblePos(0), visibleIndex(0) , averageSize(100.0), currentIndex(-1), requestedIndex(-1) - , highlightRangeStart(0), highlightRangeEnd(0) + , itemCount(0), highlightRangeStart(0), highlightRangeEnd(0) , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightPosAnimator(0), highlightSizeAnimator(0) , sectionCriteria(0), spacing(0.0) @@ -447,6 +447,7 @@ public: qreal averageSize; int currentIndex; int requestedIndex; + int itemCount; qreal highlightRangeStart; qreal highlightRangeEnd; QDeclarativeComponent *highlightComponent; @@ -501,6 +502,7 @@ void QDeclarativeListViewPrivate::init() void QDeclarativeListViewPrivate::clear() { + timeline.clear(); for (int i = 0; i < visibleItems.count(); ++i) releaseItem(visibleItems.at(i)); visibleItems.clear(); @@ -516,6 +518,8 @@ void QDeclarativeListViewPrivate::clear() trackedItem = 0; minExtentDirty = true; maxExtentDirty = true; + setPosition(0); + itemCount = 0; } FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) @@ -594,6 +598,7 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) Q_Q(QDeclarativeListView); if (!isValid() || !q->isComponentComplete()) return; + itemCount = model->count(); qreal bufferFrom = from - buffer; qreal bufferTo = to + buffer; qreal fillFrom = from; @@ -698,6 +703,10 @@ void QDeclarativeListViewPrivate::layout() { Q_Q(QDeclarativeListView); layoutScheduled = false; + if (!isValid()) { + clear(); + return; + } updateSections(); if (!visibleItems.isEmpty()) { int oldEnd = visibleItems.last()->endPosition(); @@ -711,8 +720,6 @@ void QDeclarativeListViewPrivate::layout() if (currentItem && currentIndex > lastVisibleIndex()) currentItem->setPosition(currentItem->position() + (visibleItems.last()->endPosition() - oldEnd)); } - if (!isValid()) - return; q->refill(); minExtentDirty = true; maxExtentDirty = true; @@ -2314,13 +2321,15 @@ void QDeclarativeListView::componentComplete() { Q_D(QDeclarativeListView); QDeclarativeFlickable::componentComplete(); - refill(); - d->moveReason = QDeclarativeListViewPrivate::SetIndex; - if (d->currentIndex < 0) - d->updateCurrent(0); - else - d->updateCurrent(d->currentIndex); - d->fixupPosition(); + if (d->isValid()) { + refill(); + d->moveReason = QDeclarativeListViewPrivate::SetIndex; + if (d->currentIndex < 0) + d->updateCurrent(0); + else + d->updateCurrent(d->currentIndex); + d->fixupPosition(); + } } void QDeclarativeListView::refill() @@ -2401,6 +2410,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) } else if (d->currentIndex < 0) { d->updateCurrent(0); } + d->itemCount += count; emit countChanged(); return; } @@ -2432,6 +2442,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) emit currentIndexChanged(); } d->scheduleLayout(); + d->itemCount += count; emit countChanged(); return; } @@ -2524,6 +2535,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) for (int j = 0; j < added.count(); ++j) added.at(j)->attached->emitAdd(); + d->itemCount += count; emit countChanged(); } @@ -2534,6 +2546,7 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) return; d->moveReason = QDeclarativeListViewPrivate::Other; d->updateUnrequestedIndexes(); + d->itemCount -= count; FxListItem *firstVisible = d->firstVisibleItem(); int preRemovedSize = 0; @@ -2586,7 +2599,8 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) d->releaseItem(d->currentItem); d->currentItem = 0; d->currentIndex = -1; - d->updateCurrent(qMin(modelIndex, d->model->count()-1)); + if (d->itemCount) + d->updateCurrent(qMin(modelIndex, d->itemCount-1)); } // update visibleIndex @@ -2602,7 +2616,7 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) d->visiblePos = d->header ? d->header->size() : 0; d->timeline.clear(); d->setPosition(0); - if (d->model->count() == 0) + if (d->itemCount == 0) update(); } diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index 816aa78..c95bd29 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -71,6 +71,14 @@ void QDeclarativeDrag::setTarget(QGraphicsObject *t) emit targetChanged(); } +void QDeclarativeDrag::resetTarget() +{ + if (!_target) + return; + _target = 0; + emit targetChanged(); +} + QDeclarativeDrag::Axis QDeclarativeDrag::axis() const { return _axis; @@ -412,8 +420,8 @@ void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if (d->drag && d->drag->target()) { if (!d->moved) { - if (d->dragX) d->startX = drag()->target()->x(); - if (d->dragY) d->startY = drag()->target()->y(); + d->startX = drag()->target()->x(); + d->startY = drag()->target()->y(); } QPointF startLocalPos; @@ -439,7 +447,7 @@ void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } } - if (d->dragX) { + if (d->dragX && d->dragged) { qreal x = (curLocalPos.x() - startLocalPos.x()) + d->startX; if (x < drag()->xmin()) x = drag()->xmin(); @@ -447,7 +455,7 @@ void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event) x = drag()->xmax(); drag()->target()->setX(x); } - if (d->dragY) { + if (d->dragY && d->dragged) { qreal y = (curLocalPos.y() - startLocalPos.y()) + d->startY; if (y < drag()->ymin()) y = drag()->ymin(); @@ -455,8 +463,8 @@ void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event) y = drag()->ymax(); drag()->target()->setY(y); } + d->moved = true; } - d->moved = true; QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress); emit positionChanged(&me); } diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p.h index db49b57..58faac1 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p.h @@ -55,7 +55,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeDrag : public QObject Q_OBJECT Q_ENUMS(Axis) - Q_PROPERTY(QGraphicsObject *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QGraphicsObject *target READ target WRITE setTarget NOTIFY targetChanged RESET resetTarget) Q_PROPERTY(Axis axis READ axis WRITE setAxis NOTIFY axisChanged) Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged) Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged) @@ -69,6 +69,7 @@ public: QGraphicsObject *target() const; void setTarget(QGraphicsObject *); + void resetTarget(); enum Axis { XAxis=0x01, YAxis=0x02, XandYAxis=0x03 }; Axis axis() const; diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 2938f51..174459b 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -662,6 +662,7 @@ void QDeclarativeVisualDataModel::setModel(const QVariant &model) this, SLOT(_q_itemsRemoved(int,int))); QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)), this, SLOT(_q_itemsMoved(int,int,int))); + QObject::disconnect(d->m_listModelInterface, SIGNAL(modelReset()), this, SLOT(_q_modelReset())); d->m_listModelInterface = 0; } else if (d->m_abstractItemModel) { QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsInserted(const QModelIndex &,int,int)), @@ -705,6 +706,7 @@ void QDeclarativeVisualDataModel::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))); + QObject::connect(d->m_listModelInterface, SIGNAL(modelReset()), this, SLOT(_q_modelReset())); d->m_metaDataCacheable = true; if (d->m_delegate && d->m_listModelInterface->count()) emit itemsInserted(0, d->m_listModelInterface->count()); @@ -1152,6 +1154,8 @@ void QDeclarativeVisualDataModel::_q_itemsChanged(int index, int count, void QDeclarativeVisualDataModel::_q_itemsInserted(int index, int count) { Q_D(QDeclarativeVisualDataModel); + if (!count) + return; // XXX - highly inefficient QHash<int,QDeclarativeVisualDataModelPrivate::ObjectRef> items; for (QHash<int,QDeclarativeVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin(); @@ -1179,6 +1183,8 @@ void QDeclarativeVisualDataModel::_q_itemsInserted(int index, int count) void QDeclarativeVisualDataModel::_q_itemsRemoved(int index, int count) { Q_D(QDeclarativeVisualDataModel); + if (!count) + return; // XXX - highly inefficient QHash<int, QDeclarativeVisualDataModelPrivate::ObjectRef> items; for (QHash<int, QDeclarativeVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin(); diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index f4ccce1..b12d6f4 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -881,23 +881,38 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) } // Create the object - QDeclarativeInstruction create; - create.type = QDeclarativeInstruction::CreateObject; - create.line = obj->location.start.line; - create.create.column = obj->location.start.column; - create.create.data = -1; - if (!obj->custom.isEmpty()) - create.create.data = output->indexForByteArray(obj->custom); - create.create.type = obj->type; - if (!output->types.at(create.create.type).type && - !obj->bindingBitmask.isEmpty()) { - Q_ASSERT(obj->bindingBitmask.size() % 4 == 0); - create.create.bindingBits = - output->indexForByteArray(obj->bindingBitmask); + if (obj->custom.isEmpty() && output->types.at(obj->type).type && + obj != compileState.root) { + + QDeclarativeInstruction create; + create.type = QDeclarativeInstruction::CreateSimpleObject; + create.line = obj->location.start.line; + create.createSimple.create = output->types.at(obj->type).type->createFunction(); + create.createSimple.typeSize = output->types.at(obj->type).type->createSize(); + create.createSimple.column = obj->location.start.column; + output->bytecode << create; + } else { - create.create.bindingBits = -1; + + QDeclarativeInstruction create; + create.type = QDeclarativeInstruction::CreateObject; + create.line = obj->location.start.line; + create.create.column = obj->location.start.column; + create.create.data = -1; + if (!obj->custom.isEmpty()) + create.create.data = output->indexForByteArray(obj->custom); + create.create.type = obj->type; + if (!output->types.at(create.create.type).type && + !obj->bindingBitmask.isEmpty()) { + Q_ASSERT(obj->bindingBitmask.size() % 4 == 0); + create.create.bindingBits = + output->indexForByteArray(obj->bindingBitmask); + } else { + create.create.bindingBits = -1; + } + output->bytecode << create; + } - output->bytecode << create; // Setup the synthesized meta object if necessary if (!obj->metadata.isEmpty()) { diff --git a/src/declarative/qml/qdeclarativedeclarativedata_p.h b/src/declarative/qml/qdeclarativedeclarativedata_p.h index adfff19..87c5c9c 100644 --- a/src/declarative/qml/qdeclarativedeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedeclarativedata_p.h @@ -64,6 +64,10 @@ class QDeclarativeAbstractBinding; class QDeclarativeContext; class QDeclarativePropertyCache; class QDeclarativeContextData; +// This class is structured in such a way, that simply zero'ing it is the +// default state for elemental object allocations. This is crucial in the +// workings of the QDeclarativeInstruction::CreateSimpleObject instruction. +// Don't change anything here without first considering that case! class Q_AUTOTEST_EXPORT QDeclarativeDeclarativeData : public QDeclarativeData { public: @@ -71,10 +75,10 @@ public: : ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), - attachedProperties(0), propertyCache(0), guards(0) {} + attachedProperties(0), scriptValue(0), propertyCache(0), guards(0) {} - virtual void destroyed(QObject *); - virtual void parentChanged(QObject *, QObject *); + void destroyed(QObject *); + void parentChanged(QObject *, QObject *); void setImplicitDestructible() { if (!explicitIndestructibleSet) indestructible = false; @@ -109,7 +113,9 @@ public: QHash<int, QObject *> *attachedProperties; - QScriptValue scriptValue; + // ### Can we make this QScriptValuePrivate so we incur no additional allocation + // cost? + QScriptValue *scriptValue; QDeclarativePropertyCache *propertyCache; QDeclarativeGuard<QObject> *guards; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 52a1f45..f7d1df3 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -346,6 +346,17 @@ Q_GLOBAL_STATIC(QDeclarativeEngineDebugServer, qmlEngineDebugServer); typedef QMap<QString, QString> StringStringMap; Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri + +static void QDeclarativeDeclarativeData_destroyed(QDeclarativeData *d, QObject *o) +{ + static_cast<QDeclarativeDeclarativeData *>(d)->destroyed(o); +} + +static void QDeclarativeDeclarativeData_parentChanged(QDeclarativeData *d, QObject *o, QObject *p) +{ + static_cast<QDeclarativeDeclarativeData *>(d)->parentChanged(o, p); +} + void QDeclarativeEnginePrivate::init() { Q_Q(QDeclarativeEngine); @@ -353,6 +364,9 @@ void QDeclarativeEnginePrivate::init() qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString"); qRegisterMetaType<QScriptValue>("QScriptValue"); + QDeclarativeData::destroyed = QDeclarativeDeclarativeData_destroyed; + QDeclarativeData::parentChanged = QDeclarativeDeclarativeData_parentChanged; + contextClass = new QDeclarativeContextScriptClass(q); objectClass = new QDeclarativeObjectScriptClass(q); valueTypeClass = new QDeclarativeValueTypeScriptClass(q); @@ -848,15 +862,16 @@ void QDeclarativeDeclarativeData::destroyed(QObject *object) if (ownContext) context->destroy(); + if (scriptValue) + delete scriptValue; + if (ownMemory) delete this; - else - this->~QDeclarativeDeclarativeData(); } void QDeclarativeDeclarativeData::parentChanged(QObject *, QObject *parent) { - if (!parent && scriptValue.isValid()) scriptValue = QScriptValue(); + if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; } } bool QDeclarativeDeclarativeData::hasBindingBit(int bit) const diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index 3cf4d2b..1f8b8af 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -60,6 +60,8 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) break; case QDeclarativeInstruction::CreateObject: qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE\t\t\t" << instr->create.type << "\t\t\t" << types.at(instr->create.type).className; + case QDeclarativeInstruction::CreateSimpleObject: + qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE_SIMPLE\t\t" << instr->createSimple.typeSize; break; case QDeclarativeInstruction::SetId: qWarning().nospace() << idx << "\t\t" << line << "\t" << "SETID\t\t\t" << instr->setId.value << "\t\t\t" << primitives.at(instr->setId.value); diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index 877179d..1f3c964 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -74,6 +74,7 @@ public: // top of the stack. Init, /* init */ CreateObject, /* create */ + CreateSimpleObject, /* createSimple */ SetId, /* setId */ SetDefault, CreateComponent, /* createComponent */ @@ -175,6 +176,11 @@ public: int bindingBits; ushort column; }; + struct CreateSimpleInstruction { + void (*create)(void *); + int typeSize; + ushort column; + }; struct StoreMetaInstruction { int data; int aliasData; @@ -305,6 +311,7 @@ public: union { InitInstruction init; CreateInstruction create; + CreateSimpleInstruction createSimple; StoreMetaInstruction storeMeta; SetIdInstruction setId; AssignValueSourceInstruction assignValueSource; diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp index af21765..56cc219 100644 --- a/src/declarative/qml/qdeclarativemetatype.cpp +++ b/src/declarative/qml/qdeclarativemetatype.cpp @@ -313,6 +313,16 @@ QDeclarativeCustomParser *QDeclarativeType::customParser() const return d->m_customParser; } +QDeclarativeType::CreateFunc QDeclarativeType::createFunction() const +{ + return d->m_newFunc; +} + +int QDeclarativeType::createSize() const +{ + return d->m_allocationSize; +} + bool QDeclarativeType::isCreatable() const { return d->m_newFunc != 0; diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h index b3ec5e3..96e3c74 100644 --- a/src/declarative/qml/qdeclarativemetatype_p.h +++ b/src/declarative/qml/qdeclarativemetatype_p.h @@ -115,6 +115,10 @@ public: QObject *create() const; void create(QObject **, void **, size_t) const; + typedef void (*CreateFunc)(void *); + CreateFunc createFunction() const; + int createSize() const; + QDeclarativeCustomParser *customParser() const; bool isCreatable() const; diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index d3ee67b..759a506 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -109,11 +109,11 @@ QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type return scriptEngine->undefinedValue(); } else if (!ddata->indestructible && !object->parent()) { return newObject(scriptEngine, this, new ObjectData(object, type)); - } else if (!ddata->scriptValue.isValid()) { - ddata->scriptValue = newObject(scriptEngine, this, new ObjectData(object, type)); - return ddata->scriptValue; - } else if (ddata->scriptValue.engine() == QDeclarativeEnginePrivate::getScriptEngine(engine)) { - return ddata->scriptValue; + } else if (!ddata->scriptValue) { + ddata->scriptValue = new QScriptValue(newObject(scriptEngine, this, new ObjectData(object, type))); + return *ddata->scriptValue; + } else if (ddata->scriptValue->engine() == QDeclarativeEnginePrivate::getScriptEngine(engine)) { + return *ddata->scriptValue; } else { return newObject(scriptEngine, this, new ObjectData(object, type)); } diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 5ba7f9b..0117880 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -236,13 +236,39 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, } } else { QDeclarative_setParent_noEvent(o, parent); - // o->setParent(parent); } } stack.push(o); } break; + case QDeclarativeInstruction::CreateSimpleObject: + { + QObject *o = (QObject *)operator new(instr.createSimple.typeSize + + sizeof(QDeclarativeDeclarativeData)); + ::bzero(o, instr.createSimple.typeSize + sizeof(QDeclarativeDeclarativeData)); + instr.createSimple.create(o); + + QDeclarativeDeclarativeData *ddata = + (QDeclarativeDeclarativeData *)(((const char *)o) + instr.createSimple.typeSize); + ddata->lineNumber = instr.line; + ddata->columnNumber = instr.createSimple.column; + + QObjectPrivate::get(o)->declarativeData = ddata; + ddata->context = ddata->outerContext = ctxt; + ddata->nextContextObject = ctxt->contextObjects; + if (ddata->nextContextObject) + ddata->nextContextObject->prevContextObject = &ddata->nextContextObject; + ddata->prevContextObject = &ctxt->contextObjects; + ctxt->contextObjects = ddata; + + QObject *parent = stack.top(); + QDeclarative_setParent_noEvent(o, parent); + + stack.push(o); + } + break; + case QDeclarativeInstruction::SetId: { QObject *target = stack.top(); diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 2cc1fcc..410a269 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -1090,6 +1090,9 @@ bool QDeclarativeAnchorChanges::changesBindings() void QDeclarativeAnchorChanges::saveOriginals() { Q_D(QDeclarativeAnchorChanges); + if (!d->target) + return; + d->origLeft = d->target->anchors()->left(); d->origRight = d->target->anchors()->right(); d->origHCenter = d->target->anchors()->horizontalCenter(); @@ -1146,6 +1149,9 @@ void QDeclarativeAnchorChanges::copyOriginals(QDeclarativeActionEvent *other) void QDeclarativeAnchorChanges::clearBindings() { Q_D(QDeclarativeAnchorChanges); + if (!d->target) + return; + d->fromX = d->target->x(); d->fromY = d->target->y(); d->fromWidth = d->target->width(); @@ -1242,6 +1248,9 @@ void QDeclarativeAnchorChanges::rewind() void QDeclarativeAnchorChanges::saveCurrentValues() { Q_D(QDeclarativeAnchorChanges); + if (!d->target) + return; + d->rewindLeft = d->target->anchors()->left(); d->rewindRight = d->target->anchors()->right(); d->rewindHCenter = d->target->anchors()->horizontalCenter(); @@ -1259,6 +1268,9 @@ void QDeclarativeAnchorChanges::saveCurrentValues() void QDeclarativeAnchorChanges::saveTargetValues() { Q_D(QDeclarativeAnchorChanges); + if (!d->target) + return; + d->toX = d->target->x(); d->toY = d->target->y(); d->toWidth = d->target->width(); diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index b33af06..11c7305 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -878,21 +878,22 @@ void QDeclarativeXmlListModel::queryCompleted(const QDeclarativeXmlQueryResult & } } if (!hasKeys) { - if (!(origCount == 0 && d->size == 0)) { - emit itemsRemoved(0, origCount); - emit itemsInserted(0, d->size); - emit countChanged(); - } + if (!(origCount == 0 && d->size == 0)) + emit modelReset(); } else { + if (result.removed.count() == 1 && result.removed[0].first == 0 + && result.removed[0].second == origCount) { + emit modelReset(); + } else { + for (int i=0; i<result.removed.count(); i++) + emit itemsRemoved(result.removed[i].first, result.removed[i].second); + for (int i=0; i<result.inserted.count(); i++) + emit itemsInserted(result.inserted[i].first, result.inserted[i].second); - for (int i=0; i<result.removed.count(); i++) - emit itemsRemoved(result.removed[i].first, result.removed[i].second); - for (int i=0; i<result.inserted.count(); i++) - emit itemsInserted(result.inserted[i].first, result.inserted[i].second); - - if (sizeChanged) - emit countChanged(); + if (sizeChanged) + emit countChanged(); + } } emit statusChanged(d->status); diff --git a/src/declarative/util/qdeclarativexmllistmodel_p.h b/src/declarative/util/qdeclarativexmllistmodel_p.h index 7b85476..fd410a7 100644 --- a/src/declarative/util/qdeclarativexmllistmodel_p.h +++ b/src/declarative/util/qdeclarativexmllistmodel_p.h @@ -124,6 +124,7 @@ Q_SIGNALS: void xmlChanged(); void queryChanged(); void namespaceDeclarationsChanged(); + void modelReset(); public Q_SLOTS: // ### need to use/expose Expiry to guess when to call this? diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index d6daf4d..150343e 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -7615,11 +7615,26 @@ void QGraphicsObject::updateMicroFocus() QGraphicsItem::updateMicroFocus(); } -void QGraphicsItemPrivate::append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item) +void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item) { QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast<QGraphicsObject *>(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0); } +int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object)); + return d->children.count(); +} + +QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object)); + if (index >= 0 && index < d->children.count()) + return d->children.at(index)->toGraphicsObject(); + else + return 0; +} + /*! Returns a list of this item's children. @@ -7632,7 +7647,8 @@ QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList() Q_Q(QGraphicsItem); if (isObject) { QGraphicsObject *that = static_cast<QGraphicsObject *>(q); - return QDeclarativeListProperty<QGraphicsObject>(that, &children, QGraphicsItemPrivate::append); + return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append, + children_count, children_at); } else { //QGraphicsItem is not supported for this property return QDeclarativeListProperty<QGraphicsObject>(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 73b8f04..922581d 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -480,9 +480,12 @@ public: void resetFocusProxy(); virtual void subFocusItemChange(); + static void children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item); + static int children_count(QDeclarativeListProperty<QGraphicsObject> *list); + static QGraphicsObject *children_at(QDeclarativeListProperty<QGraphicsObject> *list, int); + inline QTransform transformToParent() const; inline void ensureSortedChildren(); - static void append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item); static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b); void ensureSequentialSiblingIndex(); inline void sendScenePosChange(); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e88026c..9353d10 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1478,7 +1478,7 @@ QWidget::~QWidget() QObjectPrivate::clearGuards(this); if (d->declarativeData) { - d->declarativeData->destroyed(this); + QDeclarativeData::destroyed(d->declarativeData, this); d->declarativeData = 0; // don't activate again in ~QObject } |