forked from qt-creator/qt-creator
Improve performance of State property changes
This patch is eliminating the switch from the state the base state and back if a property is changed. For that it is updating the internal caching values in QDeclarativeState. Reviewed-by: Thomas Hartmann
This commit is contained in:
@@ -43,9 +43,9 @@ FormEditorGraphicsView::FormEditorGraphicsView(QWidget *parent) :
|
||||
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
setResizeAnchor(QGraphicsView::AnchorViewCenter);
|
||||
// setCacheMode(QGraphicsView::CacheNone);
|
||||
setCacheMode(QGraphicsView::CacheBackground);
|
||||
setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
|
||||
// setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
|
||||
// setCacheMode(QGraphicsView::CacheBackground);
|
||||
// setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
|
||||
setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
|
||||
setRenderHint(QPainter::Antialiasing, false);
|
||||
|
||||
setFrameShape(QFrame::NoFrame);
|
||||
|
||||
@@ -329,8 +329,10 @@ void FormEditorScene::reparentItem(const QmlItemNode &node, const QmlItemNode &n
|
||||
Q_ASSERT(hasItemForQmlItemNode(newParent));
|
||||
FormEditorItem *item = itemForQmlItemNode(node);
|
||||
FormEditorItem *parentItem = itemForQmlItemNode(newParent);
|
||||
if (item->parentItem() != parentItem) {
|
||||
item->setParentItem(parentItem);
|
||||
item->setParent(parentItem);
|
||||
item->update();
|
||||
}
|
||||
}
|
||||
|
||||
FormEditorItem* FormEditorScene::rootFormEditorItem() const
|
||||
|
||||
@@ -58,6 +58,8 @@ class WidgetQueryView;
|
||||
namespace Internal {
|
||||
class ObjectNodeInstance;
|
||||
class QmlGraphicsItemNodeInstance;
|
||||
class QmlPropertyChangesNodeInstance;
|
||||
class QmlStateNodeInstance;
|
||||
}
|
||||
|
||||
class CORESHARED_EXPORT NodeInstance
|
||||
@@ -71,6 +73,9 @@ class CORESHARED_EXPORT NodeInstance
|
||||
friend CORESHARED_EXPORT class NodeMetaInfo;
|
||||
friend class QmlDesigner::Internal::QmlGraphicsItemNodeInstance;
|
||||
friend class QmlDesigner::Internal::ObjectNodeInstance;
|
||||
friend class QmlDesigner::Internal::QmlPropertyChangesNodeInstance;
|
||||
friend class QmlDesigner::Internal::QmlStateNodeInstance;
|
||||
|
||||
public:
|
||||
NodeInstance();
|
||||
~NodeInstance();
|
||||
@@ -82,7 +87,7 @@ public:
|
||||
NodeInstance parent() const;
|
||||
bool hasParent() const;
|
||||
ModelNode modelNode() const;
|
||||
void setModelNode(const ModelNode &node);
|
||||
|
||||
|
||||
bool isTopLevel() const;
|
||||
|
||||
@@ -119,13 +124,9 @@ public:
|
||||
void makeInvalid();
|
||||
bool hasContent() const;
|
||||
|
||||
const QObject *testHandle() const;
|
||||
bool isWrappingThisObject(QObject *object) const;
|
||||
|
||||
void setPropertyVariant(const QString &name, const QVariant &value);
|
||||
void setPropertyDynamicVariant(const QString &name, const QString &typeName, const QVariant &value);
|
||||
|
||||
void setPropertyBinding(const QString &name, const QString &expression);
|
||||
void setPropertyDynamicBinding(const QString &name, const QString &typeName, const QString &expression);
|
||||
QVariant resetVariant(const QString &name) const;
|
||||
|
||||
bool hasAnchor(const QString &name) const;
|
||||
bool isAnchoredBy() const;
|
||||
@@ -133,22 +134,35 @@ public:
|
||||
|
||||
int penWidth() const;
|
||||
|
||||
void activateState();
|
||||
void deactivateState();
|
||||
void refreshState();
|
||||
|
||||
static void registerDeclarativeTypes();
|
||||
|
||||
private: // functions
|
||||
NodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance);
|
||||
|
||||
void setModelNode(const ModelNode &node);
|
||||
|
||||
void setPropertyVariant(const QString &name, const QVariant &value);
|
||||
void setPropertyDynamicVariant(const QString &name, const QString &typeName, const QVariant &value);
|
||||
|
||||
void setPropertyBinding(const QString &name, const QString &expression);
|
||||
void setPropertyDynamicBinding(const QString &name, const QString &typeName, const QString &expression);
|
||||
|
||||
void resetProperty(const QString &name);
|
||||
|
||||
void activateState();
|
||||
void deactivateState();
|
||||
void refreshState();
|
||||
|
||||
bool updateStateVariant(const NodeInstance &target, const QString &propertyName, const QVariant &value);
|
||||
bool updateStateBinding(const NodeInstance &target, const QString &propertyName, const QString &expression);
|
||||
bool resetStateProperty(const NodeInstance &target, const QString &propertyName, const QVariant &resetValue);
|
||||
|
||||
static NodeInstance create(NodeInstanceView *nodeInstanceView, const ModelNode &node, QObject *objectToBeWrapped);
|
||||
static NodeInstance create(NodeInstanceView *nodeInstanceView, const NodeMetaInfo &metaInfo, QDeclarativeContext *context);
|
||||
|
||||
void setDeleteHeldInstance(bool deleteInstance);
|
||||
void reparent(const NodeInstance &oldParentInstance, const QString &oldParentProperty, const NodeInstance &newParentInstance, const QString &newParentProperty);
|
||||
|
||||
void resetProperty(const QString &name);
|
||||
|
||||
void setId(const QString &id);
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace QmlDesigner {
|
||||
|
||||
namespace Internal {
|
||||
class ChildrenChangeEventFilter;
|
||||
class QmlStateNodeInstance;
|
||||
}
|
||||
|
||||
class CORESHARED_EXPORT NodeInstanceView : public AbstractView
|
||||
@@ -59,6 +60,7 @@ class CORESHARED_EXPORT NodeInstanceView : public AbstractView
|
||||
|
||||
friend class NodeInstance;
|
||||
friend class Internal::ObjectNodeInstance;
|
||||
friend class Internal::QmlStateNodeInstance;
|
||||
public:
|
||||
typedef QWeakPointer<NodeInstanceView> Pointer;
|
||||
|
||||
@@ -116,6 +118,11 @@ public:
|
||||
|
||||
void setBlockStatePropertyChanges(bool block);
|
||||
|
||||
NodeInstance activeStateInstance() const;
|
||||
|
||||
void activateState(const NodeInstance &instance);
|
||||
void activateBaseState();
|
||||
|
||||
signals:
|
||||
void instanceRemoved(const NodeInstance &nodeInstance);
|
||||
|
||||
@@ -138,8 +145,16 @@ private: // functions
|
||||
Internal::ChildrenChangeEventFilter *childrenChangeEventFilter();
|
||||
void removeInstanceAndSubInstances(const ModelNode &node);
|
||||
|
||||
void setInstancePropertyVariant(const VariantProperty &property);
|
||||
void setInstancePropertyBinding(const BindingProperty &property);
|
||||
void resetInstanceProperty(const AbstractProperty &property);
|
||||
|
||||
void setStateInstance(const NodeInstance &stateInstance);
|
||||
void clearStateInstance();
|
||||
|
||||
private: //variables
|
||||
NodeInstance m_rootNodeInstance;
|
||||
NodeInstance m_activeStateInstance;
|
||||
QScopedPointer<QGraphicsView> m_graphicsView;
|
||||
|
||||
QHash<ModelNode, NodeInstance> m_nodeInstanceHash;
|
||||
|
||||
@@ -369,6 +369,7 @@ QRectF NodeInstance::boundingRect() const
|
||||
void NodeInstance::setPropertyVariant(const QString &name, const QVariant &value)
|
||||
{
|
||||
m_nodeInstance->setPropertyVariant(name, value);
|
||||
|
||||
}
|
||||
|
||||
void NodeInstance::setPropertyDynamicVariant(const QString &name, const QString &typeName, const QVariant &value)
|
||||
@@ -485,9 +486,9 @@ bool operator==(const NodeInstance &first, const NodeInstance &second)
|
||||
return first.m_nodeInstance.data() == second.m_nodeInstance.data();
|
||||
}
|
||||
|
||||
const QObject *NodeInstance::testHandle() const
|
||||
bool NodeInstance::isWrappingThisObject(QObject *object) const
|
||||
{
|
||||
return internalObject();
|
||||
return internalObject() && internalObject() == object;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -606,9 +607,24 @@ void NodeInstance::deactivateState()
|
||||
m_nodeInstance->deactivateState();
|
||||
}
|
||||
|
||||
void NodeInstance::refreshState()
|
||||
bool NodeInstance::updateStateVariant(const NodeInstance &target, const QString &propertyName, const QVariant &value)
|
||||
{
|
||||
m_nodeInstance->refreshState();
|
||||
return m_nodeInstance->updateStateVariant(target, propertyName, value);
|
||||
}
|
||||
|
||||
bool NodeInstance::updateStateBinding(const NodeInstance &target, const QString &propertyName, const QString &expression)
|
||||
{
|
||||
return m_nodeInstance->updateStateBinding(target, propertyName, expression);
|
||||
}
|
||||
|
||||
QVariant NodeInstance::resetVariant(const QString &propertyName) const
|
||||
{
|
||||
return m_nodeInstance->resetValue(propertyName);
|
||||
}
|
||||
|
||||
bool NodeInstance::resetStateProperty(const NodeInstance &target, const QString &propertyName, const QVariant &resetValue)
|
||||
{
|
||||
return m_nodeInstance->resetStateProperty(target, propertyName, resetValue);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Internal {
|
||||
NodeInstanceSignalSpy::NodeInstanceSignalSpy() :
|
||||
QObject()
|
||||
{
|
||||
blockSignals(true);
|
||||
}
|
||||
|
||||
void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Pointer &nodeInstance)
|
||||
|
||||
@@ -83,8 +83,8 @@ namespace QmlDesigner {
|
||||
|
||||
The class will be rendered offscreen if not set otherwise.
|
||||
|
||||
\param Parent of this object. If this parent is deleted this instance is
|
||||
deleted too.
|
||||
\param Parent of this object. If this parent is d this instance is
|
||||
d too.
|
||||
|
||||
\see ~NodeInstanceView setRenderOffScreen
|
||||
*/
|
||||
@@ -173,10 +173,7 @@ void NodeInstanceView::nodeRemoved(const ModelNode &/*removedNode*/, const NodeA
|
||||
void NodeInstanceView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList)
|
||||
{
|
||||
foreach (const AbstractProperty &property, propertyList) {
|
||||
if (hasInstanceForNode(property.parentModelNode())) { // TODO ugly workaround
|
||||
NodeInstance instance = instanceForNode(property.parentModelNode());
|
||||
instance.resetProperty(property.name());
|
||||
}
|
||||
resetInstanceProperty(property);
|
||||
|
||||
if (property.isNodeAbstractProperty()) {
|
||||
foreach (const ModelNode &subNode, property.toNodeAbstractProperty().allSubNodes())
|
||||
@@ -189,6 +186,93 @@ void NodeInstanceView::propertiesRemoved(const QList<AbstractProperty>& /*proper
|
||||
{
|
||||
}
|
||||
|
||||
void NodeInstanceView::resetInstanceProperty(const AbstractProperty &property)
|
||||
{
|
||||
if (hasInstanceForNode(property.parentModelNode())) { // TODO ugly workaround
|
||||
NodeInstance instance = instanceForNode(property.parentModelNode());
|
||||
Q_ASSERT(instance.isValid());
|
||||
const QString name = property.name();
|
||||
if (activeStateInstance().isValid()) {
|
||||
bool statePropertyWasReseted = activeStateInstance().resetStateProperty(instance, name, instance.resetVariant(name));
|
||||
if (!statePropertyWasReseted)
|
||||
instance.resetProperty(name);
|
||||
} else {
|
||||
instance.resetProperty(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeInstanceView::setInstancePropertyBinding(const BindingProperty &property)
|
||||
{
|
||||
NodeInstance instance = instanceForNode(property.parentModelNode());
|
||||
|
||||
const QString name = property.name();
|
||||
const QString expression = property.expression();
|
||||
|
||||
|
||||
if (activeStateInstance().isValid()) {
|
||||
bool stateBindingWasUpdated = activeStateInstance().updateStateBinding(instance, name, expression);
|
||||
if (!stateBindingWasUpdated) {
|
||||
if (property.isDynamic())
|
||||
instance.setPropertyDynamicBinding(name, property.dynamicTypeName(), expression);
|
||||
else
|
||||
instance.setPropertyBinding(name, expression);
|
||||
}
|
||||
} else {
|
||||
if (property.isDynamic())
|
||||
instance.setPropertyDynamicBinding(name, property.dynamicTypeName(), expression);
|
||||
else
|
||||
instance.setPropertyBinding(name, expression);
|
||||
}
|
||||
|
||||
|
||||
if (property.parentModelNode().isRootNode()
|
||||
&& (name == "width" || name == "height")) {
|
||||
QGraphicsObject *rootGraphicsObject = qobject_cast<QGraphicsObject*>(instance.internalObject());
|
||||
if (rootGraphicsObject) {
|
||||
m_graphicsView->setSceneRect(rootGraphicsObject->boundingRect());
|
||||
}
|
||||
}
|
||||
|
||||
instance.paintUpdate();
|
||||
|
||||
}
|
||||
|
||||
void NodeInstanceView::setInstancePropertyVariant(const VariantProperty &property)
|
||||
{
|
||||
NodeInstance instance = instanceForNode(property.parentModelNode());
|
||||
|
||||
const QString name = property.name();
|
||||
const QVariant value = property.value();
|
||||
|
||||
|
||||
if (activeStateInstance().isValid()) {
|
||||
bool stateValueWasUpdated = activeStateInstance().updateStateVariant(instance, name, value);
|
||||
if (!stateValueWasUpdated) {
|
||||
if (property.isDynamic())
|
||||
instance.setPropertyDynamicVariant(name, property.dynamicTypeName(), value);
|
||||
else
|
||||
instance.setPropertyVariant(name, value);
|
||||
}
|
||||
} else { //base state
|
||||
if (property.isDynamic())
|
||||
instance.setPropertyDynamicVariant(name, property.dynamicTypeName(), value);
|
||||
else
|
||||
instance.setPropertyVariant(name, value);
|
||||
}
|
||||
|
||||
|
||||
if (property.parentModelNode().isRootNode()
|
||||
&& (name == "width" || name == "height")) {
|
||||
QGraphicsObject *rootGraphicsObject = qobject_cast<QGraphicsObject*>(instance.internalObject());
|
||||
if (rootGraphicsObject) {
|
||||
m_graphicsView->setSceneRect(rootGraphicsObject->boundingRect());
|
||||
}
|
||||
}
|
||||
|
||||
instance.paintUpdate();
|
||||
}
|
||||
|
||||
void NodeInstanceView::removeInstanceAndSubInstances(const ModelNode &node)
|
||||
{
|
||||
foreach(const ModelNode &subNode, node.allSubModelNodes()) {
|
||||
@@ -213,22 +297,8 @@ void NodeInstanceView::rootNodeTypeChanged(const QString &/*type*/, int /*majorV
|
||||
|
||||
void NodeInstanceView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
|
||||
{
|
||||
foreach (const BindingProperty &property, propertyList) {
|
||||
NodeInstance instance = instanceForNode(property.parentModelNode());
|
||||
|
||||
if (property.isDynamic())
|
||||
instance.setPropertyDynamicBinding(property.name(), property.dynamicTypeName(), property.expression());
|
||||
else
|
||||
instance.setPropertyBinding(property.name(), property.expression());
|
||||
|
||||
if (property.parentModelNode().isRootNode()
|
||||
&& (property.name() == "width" || property.name() == "height")) {
|
||||
QGraphicsObject *rootGraphicsObject = qobject_cast<QGraphicsObject*>(instance.internalObject());
|
||||
m_graphicsView->setSceneRect(rootGraphicsObject->boundingRect());
|
||||
}
|
||||
|
||||
instance.paintUpdate();
|
||||
}
|
||||
foreach (const BindingProperty &property, propertyList)
|
||||
setInstancePropertyBinding(property);
|
||||
}
|
||||
|
||||
/*! \brief Notifing the view that a AbstractProperty value was changed to a ModelNode.
|
||||
@@ -244,24 +314,8 @@ void NodeInstanceView::bindingPropertiesChanged(const QList<BindingProperty>& pr
|
||||
|
||||
void NodeInstanceView::variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
|
||||
{
|
||||
foreach (const VariantProperty &property, propertyList) {
|
||||
NodeInstance instance = instanceForNode(property.parentModelNode());
|
||||
|
||||
if (property.isDynamic())
|
||||
instance.setPropertyDynamicVariant(property.name(), property.dynamicTypeName(), property.value());
|
||||
else
|
||||
instance.setPropertyVariant(property.name(), property.value());
|
||||
|
||||
if (property.parentModelNode().isRootNode()
|
||||
&& (property.name() == "width" || property.name() == "height")) {
|
||||
QGraphicsObject *rootGraphicsObject = qobject_cast<QGraphicsObject*>(instance.internalObject());
|
||||
if (rootGraphicsObject) {
|
||||
m_graphicsView->setSceneRect(rootGraphicsObject->boundingRect());
|
||||
}
|
||||
}
|
||||
|
||||
instance.paintUpdate();
|
||||
}
|
||||
foreach (const VariantProperty &property, propertyList)
|
||||
setInstancePropertyVariant(property);
|
||||
}
|
||||
/*! \brief Notifing the view that a ModelNode has a new Parent.
|
||||
|
||||
@@ -361,7 +415,7 @@ void NodeInstanceView::removeAllInstanceNodeRelationships()
|
||||
{
|
||||
// prevent destroyed() signals calling back
|
||||
|
||||
//first delete the root object
|
||||
//first the root object
|
||||
if (rootNodeInstance().internalObject())
|
||||
rootNodeInstance().internalObject()->disconnect();
|
||||
|
||||
@@ -502,7 +556,7 @@ void NodeInstanceView::removeInstanceNodeRelationship(const ModelNode &node)
|
||||
|
||||
void NodeInstanceView::notifyPropertyChange(const ModelNode &node, const QString &propertyName)
|
||||
{
|
||||
if (m_blockStatePropertyChanges && propertyName == "state")
|
||||
if (m_blockStatePropertyChanges)
|
||||
return;
|
||||
|
||||
if (qmlModelView()) {
|
||||
@@ -526,6 +580,21 @@ void NodeInstanceView::setBlockStatePropertyChanges(bool block)
|
||||
m_blockStatePropertyChanges = block;
|
||||
}
|
||||
|
||||
void NodeInstanceView::setStateInstance(const NodeInstance &stateInstance)
|
||||
{
|
||||
m_activeStateInstance = stateInstance;
|
||||
}
|
||||
|
||||
void NodeInstanceView::clearStateInstance()
|
||||
{
|
||||
m_activeStateInstance = NodeInstance();
|
||||
}
|
||||
|
||||
NodeInstance NodeInstanceView::activeStateInstance() const
|
||||
{
|
||||
return m_activeStateInstance;
|
||||
}
|
||||
|
||||
void NodeInstanceView::emitParentChanged(QObject *child)
|
||||
{
|
||||
if (hasInstanceForObject(child)) {
|
||||
@@ -552,6 +621,18 @@ NodeInstance NodeInstanceView::loadNode(const ModelNode &node, QObject *objectTo
|
||||
return instance;
|
||||
}
|
||||
|
||||
void NodeInstanceView::activateState(const NodeInstance &instance)
|
||||
{
|
||||
NodeInstance stateInstance(instance);
|
||||
stateInstance.activateState();
|
||||
}
|
||||
|
||||
void NodeInstanceView::activateBaseState()
|
||||
{
|
||||
if (activeStateInstance().isValid())
|
||||
activeStateInstance().deactivateState();
|
||||
}
|
||||
|
||||
void NodeInstanceView::removeRecursiveChildRelationship(const ModelNode &removedNode)
|
||||
{
|
||||
foreach (const ModelNode &childNode, removedNode.allDirectSubModelNodes())
|
||||
|
||||
@@ -121,11 +121,7 @@ void ObjectNodeInstance::destroy()
|
||||
ModelNode parentNode = parentProperty.parentModelNode();
|
||||
if (parentNode.isValid() && nodeInstanceView()->hasInstanceForNode(parentNode)) {
|
||||
NodeInstance parentInstance = nodeInstanceView()->instanceForNode(parentNode);
|
||||
if (parentInstance.isQmlGraphicsItem() && isChildrenProperty(parentProperty.name())) {
|
||||
specialRemoveParentForQmlGraphicsItemChildren(object());
|
||||
} else {
|
||||
removeFromOldProperty(object(), parentInstance.internalObject(), parentProperty.name());
|
||||
}
|
||||
reparent(parentInstance, parentProperty.name(), NodeInstance() , QString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,9 +326,23 @@ static QVariant objectToVariant(QObject *object)
|
||||
return QVariant::fromValue(object);
|
||||
}
|
||||
|
||||
static void removeObjectFromList(const QDeclarativeProperty & /*metaProperty*/, QObject * /*object*/, QDeclarativeEngine * /*engine*/)
|
||||
static void removeObjectFromList(const QDeclarativeProperty &metaProperty, QObject *objectToBeRemoved, QDeclarativeEngine * engine)
|
||||
{
|
||||
// ### Very few QML lists ever responded to removes
|
||||
QDeclarativeListReference listReference(metaProperty.object(), metaProperty.name().toLatin1(), engine);
|
||||
int count = listReference.count();
|
||||
|
||||
QObjectList objectList;
|
||||
|
||||
for(int i = 0; i < count; i ++) {
|
||||
QObject *listItem = listReference.at(i);
|
||||
if (listItem != objectToBeRemoved)
|
||||
objectList.append(listItem);
|
||||
}
|
||||
|
||||
listReference.clear();
|
||||
|
||||
foreach(QObject *object, objectList)
|
||||
listReference.append(object);
|
||||
}
|
||||
|
||||
void ObjectNodeInstance::removeFromOldProperty(QObject *object, QObject *oldParent, const QString &oldParentProperty)
|
||||
@@ -394,7 +404,6 @@ void ObjectNodeInstance::reparent(const NodeInstance &oldParentInstance, const Q
|
||||
void ObjectNodeInstance::setPropertyVariant(const QString &name, const QVariant &value)
|
||||
{
|
||||
QDeclarativeProperty QDeclarativeProperty(object(), name, context());
|
||||
|
||||
QDeclarativeProperty.write(value);
|
||||
}
|
||||
|
||||
@@ -579,10 +588,6 @@ void ObjectNodeInstance::deactivateState()
|
||||
{
|
||||
}
|
||||
|
||||
void ObjectNodeInstance::refreshState()
|
||||
{
|
||||
}
|
||||
|
||||
QStringList propertyNameForWritableProperties(QObject *object, const QString &baseName = QString())
|
||||
{
|
||||
QStringList propertyNameList;
|
||||
@@ -695,6 +700,21 @@ void ObjectNodeInstance::refreshBindings(QDeclarativeContext *context)
|
||||
context->setContextProperty(QString("__dummy_%1").arg(i++), true);
|
||||
}
|
||||
|
||||
bool ObjectNodeInstance::updateStateVariant(const NodeInstance &/*target*/, const QString &/*propertyName*/, const QVariant &/*value*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectNodeInstance::updateStateBinding(const NodeInstance &/*target*/, const QString &/*propertyName*/, const QString &/*expression*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectNodeInstance::resetStateProperty(const NodeInstance &/*target*/, const QString &/*propertyName*/, const QVariant &/*resetValue*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
|
||||
virtual QObject *parent() const;
|
||||
|
||||
void reparent(const NodeInstance &oldParentInstance, const QString &oldParentProperty, const NodeInstance &newParentInstance, const QString &newParentProperty);
|
||||
virtual void reparent(const NodeInstance &oldParentInstance, const QString &oldParentProperty, const NodeInstance &newParentInstance, const QString &newParentProperty);
|
||||
|
||||
void setId(const QString &id);
|
||||
|
||||
@@ -155,7 +155,6 @@ public:
|
||||
|
||||
virtual void activateState();
|
||||
virtual void deactivateState();
|
||||
virtual void refreshState();
|
||||
|
||||
void populateResetValueHash();
|
||||
QVariant resetValue(const QString &propertyName) const;
|
||||
@@ -166,6 +165,10 @@ public:
|
||||
|
||||
QDeclarativeContext *context() const;
|
||||
|
||||
virtual bool updateStateVariant(const NodeInstance &target, const QString &propertyName, const QVariant &value);
|
||||
virtual bool updateStateBinding(const NodeInstance &target, const QString &propertyName, const QString &expression);
|
||||
virtual bool resetStateProperty(const NodeInstance &target, const QString &propertyName, const QVariant &resetValue);
|
||||
|
||||
protected:
|
||||
static QObject* createObject(const NodeMetaInfo &metaInfo, QDeclarativeContext *context);
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
#include <QDeclarativeExpression>
|
||||
#include <private/qdeclarativebinding_p.h>
|
||||
#include <metainfo.h>
|
||||
#include <QMutableListIterator>
|
||||
|
||||
#include <private/qdeclarativestate_p_p.h>
|
||||
#include <private/qdeclarativestategroup_p.h>
|
||||
#include <private/qdeclarativeproperty_p.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
@@ -47,61 +52,72 @@ QmlPropertyChangesObject::QmlPropertyChangesObject() :
|
||||
|
||||
QDeclarativeStateOperation::ActionList QmlPropertyChangesObject::actions()
|
||||
{
|
||||
ActionList list;
|
||||
QMutableListIterator<QDeclarativeAction> actionIterator(m_qmlActionList);
|
||||
|
||||
foreach (const QString &property, m_properties.keys()) {
|
||||
QDeclarativeAction a(m_targetObject.data(), property, m_properties.value(property));
|
||||
|
||||
if (a.property.isValid()) {
|
||||
a.restore = restoreEntryValues();
|
||||
|
||||
if (a.property.propertyType() == QVariant::Url &&
|
||||
(a.toValue.type() == QVariant::String || a.toValue.type() == QVariant::ByteArray) && !a.toValue.isNull())
|
||||
a.toValue.setValue(qmlContext(this)->resolvedUrl(QUrl(a.toValue.toString())));
|
||||
|
||||
list << a;
|
||||
}
|
||||
}
|
||||
|
||||
// for (int ii = 0; ii < d->signalReplacements.count(); ++ii) {
|
||||
//
|
||||
// QmlReplaceSignalHandler *handler = d->signalReplacements.at(ii);
|
||||
//
|
||||
// if (handler->property.isValid()) {
|
||||
// Action a;
|
||||
// a.event = handler;
|
||||
// list << a;
|
||||
// }
|
||||
// }
|
||||
|
||||
foreach (const QString &property, m_expressions.keys()) {
|
||||
QDeclarativeProperty mProperty = metaProperty(property);
|
||||
|
||||
if (mProperty.isValid()) {
|
||||
QDeclarativeAction a;
|
||||
a.restore = restoreEntryValues();
|
||||
a.property = mProperty;
|
||||
a.fromValue = a.property.read();
|
||||
a.specifiedObject = m_targetObject.data();
|
||||
a.specifiedProperty = property;
|
||||
|
||||
if (m_isExplicit) {
|
||||
a.toValue = QDeclarativeExpression(qmlContext(object()), m_expressions.value(property), object()).value();
|
||||
while (actionIterator.hasNext()) {
|
||||
QDeclarativeAction &action = actionIterator.next();
|
||||
action.fromBinding = QDeclarativePropertyPrivate::binding(action.property);
|
||||
action.fromValue = action.property.read();
|
||||
if (m_expressionHash.contains(action.specifiedProperty)) {
|
||||
if(m_expressionHash[action.specifiedProperty].second.isNull()) {
|
||||
QDeclarativeBinding *binding = new QDeclarativeBinding(m_expressionHash[action.specifiedProperty].first, targetObject(), QDeclarativeEngine::contextForObject(targetObject()), this);
|
||||
binding->setTarget(action.property);
|
||||
binding->setNotifyOnValueChanged(true);
|
||||
action.toBinding = binding;
|
||||
action.toValue = binding->value();
|
||||
m_expressionHash.insert(action.specifiedProperty, ExpressionPair(m_expressionHash[action.specifiedProperty].first, binding));
|
||||
} else {
|
||||
QDeclarativeBinding *newBinding = new QDeclarativeBinding(m_expressions.value(property), object(), qmlContext(object()));
|
||||
newBinding->setTarget(mProperty);
|
||||
a.toBinding = newBinding;
|
||||
a.deletableToBinding = true;
|
||||
action.toBinding = m_expressionHash[action.specifiedProperty].second.data();
|
||||
action.toValue = m_expressionHash[action.specifiedProperty].second->value();
|
||||
}
|
||||
|
||||
list << a;
|
||||
} else {
|
||||
action.toBinding = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
return m_qmlActionList;
|
||||
}
|
||||
|
||||
QDeclarativeProperty QmlPropertyChangesObject::metaProperty(const QString &property)
|
||||
QObject *QmlPropertyChangesObject::targetObject() const
|
||||
{
|
||||
return m_targetObject.data();
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::setTargetObject(QObject *object)
|
||||
{
|
||||
m_targetObject = object;
|
||||
|
||||
QMutableListIterator<QDeclarativeAction> actionIterator(m_qmlActionList);
|
||||
while (actionIterator.hasNext()) {
|
||||
QDeclarativeAction &qmlAction = actionIterator.next();
|
||||
qmlAction.specifiedObject = object;
|
||||
qmlAction.property = createMetaProperty(qmlAction.specifiedProperty);
|
||||
qmlAction.fromValue = qmlAction.property.read();
|
||||
qmlAction.fromBinding = QDeclarativePropertyPrivate::binding(qmlAction.property);
|
||||
}
|
||||
}
|
||||
|
||||
bool QmlPropertyChangesObject::restoreEntryValues() const
|
||||
{
|
||||
return m_restoreEntryValues;
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::setRestoreEntryValues(bool restore)
|
||||
{
|
||||
m_restoreEntryValues = restore;
|
||||
}
|
||||
|
||||
bool QmlPropertyChangesObject::isExplicit() const
|
||||
{
|
||||
return m_isExplicit;
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::setIsExplicit(bool isExplicit)
|
||||
{
|
||||
m_isExplicit = isExplicit;
|
||||
}
|
||||
|
||||
QDeclarativeProperty QmlPropertyChangesObject::createMetaProperty(const QString &property)
|
||||
{
|
||||
QDeclarativeProperty prop(m_targetObject.data(), property);
|
||||
if (!prop.isValid()) {
|
||||
@@ -138,9 +154,14 @@ void QmlPropertyChangesNodeInstance::setPropertyVariant(const QString &name, con
|
||||
|
||||
if (metaObject.indexOfProperty(name.toLatin1()) > 0) { // 'restoreEntryValues', 'explicit'
|
||||
ObjectNodeInstance::setPropertyVariant(name, value);
|
||||
return;
|
||||
} else {
|
||||
changesObject()->m_properties.insert(name, value); updateStateInstance();
|
||||
changesObject()->setVariantValue(name, value);
|
||||
QObject *targetObject = changesObject()->targetObject();
|
||||
if (targetObject && nodeInstanceView()->activeStateInstance().isWrappingThisObject(changesObject()->state())) {
|
||||
changesObject()->updateRevertValueAndBinding(name);
|
||||
NodeInstance targetInstance = nodeInstanceView()->instanceForObject(targetObject);
|
||||
targetInstance.setPropertyVariant(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,32 +171,68 @@ void QmlPropertyChangesNodeInstance::setPropertyBinding(const QString &name, con
|
||||
|
||||
if (metaObject.indexOfProperty(name.toLatin1()) > 0) { // 'restoreEntryValues', 'explicit'
|
||||
ObjectNodeInstance::setPropertyBinding(name, expression);
|
||||
return;
|
||||
} else {
|
||||
changesObject()->m_expressions.insert(name, expression);
|
||||
updateStateInstance();
|
||||
changesObject()->setExpression(name, expression);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant QmlPropertyChangesNodeInstance::property(const QString &name) const
|
||||
{
|
||||
if (changesObject()->m_properties.contains(name))
|
||||
return changesObject()->m_properties.value(name);
|
||||
if (changesObject()->m_expressions.contains(name))
|
||||
return changesObject()->m_expressions.value(name);
|
||||
if (changesObject()->hasVariantValue(name))
|
||||
return changesObject()->variantValue(name);
|
||||
if (changesObject()->hasExpression(name))
|
||||
return QVariant(changesObject()->expression(name));
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void QmlPropertyChangesNodeInstance::resetProperty(const QString &name)
|
||||
{
|
||||
if (changesObject()->m_properties.contains(name))
|
||||
changesObject()->m_properties.remove(name);
|
||||
else if (changesObject()->m_expressions.contains(name))
|
||||
changesObject()->m_expressions.remove(name);
|
||||
// TODO: How to force states object to update?
|
||||
changesObject()->resetProperty(name);
|
||||
}
|
||||
|
||||
updateStateInstance();
|
||||
|
||||
void QmlPropertyChangesNodeInstance::reparent(const NodeInstance &oldParentInstance, const QString &oldParentProperty, const NodeInstance &newParentInstance, const QString &newParentProperty)
|
||||
{
|
||||
if (oldParentProperty == "changes") {
|
||||
if (changesObject()) {
|
||||
changesObject()->removeFromStateRevertList();
|
||||
}
|
||||
}
|
||||
|
||||
ObjectNodeInstance::reparent(oldParentInstance, oldParentProperty, newParentInstance, newParentProperty);
|
||||
|
||||
if (newParentProperty == "changes") {
|
||||
if (changesObject()) {
|
||||
changesObject()->addToStateRevertList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QDeclarativeState *QmlPropertyChangesObject::state() const
|
||||
{
|
||||
if (!parent())
|
||||
return 0;
|
||||
|
||||
Q_ASSERT(qobject_cast<QDeclarativeState*>(parent()));
|
||||
return static_cast<QDeclarativeState*>(parent());
|
||||
}
|
||||
|
||||
QDeclarativeStateGroup *QmlPropertyChangesObject::stateGroup() const
|
||||
{
|
||||
if (!state())
|
||||
return 0;
|
||||
|
||||
return state()->stateGroup();
|
||||
}
|
||||
|
||||
QDeclarativeStatePrivate *QmlPropertyChangesObject::statePrivate() const
|
||||
{
|
||||
if (!parent())
|
||||
return 0;
|
||||
|
||||
Q_ASSERT(qobject_cast<QDeclarativeState*>(parent()));
|
||||
return static_cast<QDeclarativeStatePrivate*>(QObjectPrivate::get(parent()));
|
||||
}
|
||||
|
||||
QmlPropertyChangesObject *QmlPropertyChangesNodeInstance::changesObject() const
|
||||
@@ -184,20 +241,358 @@ QmlPropertyChangesObject *QmlPropertyChangesNodeInstance::changesObject() const
|
||||
return static_cast<QmlPropertyChangesObject*>(object());
|
||||
}
|
||||
|
||||
void QmlPropertyChangesNodeInstance::updateStateInstance() const
|
||||
|
||||
QDeclarativeAction QmlPropertyChangesObject::createQDeclarativeAction(const QString &propertyName)
|
||||
{
|
||||
if (!nodeInstanceView()->hasInstanceForNode(modelNode()))
|
||||
return;
|
||||
QDeclarativeProperty qmlMetaProperty = createMetaProperty(propertyName);
|
||||
|
||||
NodeInstance myInstance = nodeInstanceView()->instanceForNode(modelNode());
|
||||
Q_ASSERT(myInstance.isValid());
|
||||
QDeclarativeAction qmlAction;
|
||||
qmlAction.restore = true;
|
||||
qmlAction.property = qmlMetaProperty;
|
||||
qmlAction.fromValue = qmlMetaProperty.read();
|
||||
qmlAction.fromBinding = QDeclarativePropertyPrivate::binding(qmlMetaProperty);
|
||||
qmlAction.specifiedObject = m_targetObject.data();
|
||||
qmlAction.specifiedProperty = propertyName;
|
||||
qmlAction.event = 0;
|
||||
|
||||
NodeInstance qmlStateInstance = myInstance.parent();
|
||||
if (!qmlStateInstance.isValid()
|
||||
|| !qmlStateInstance.modelNode().isValid())
|
||||
return;
|
||||
return qmlAction;
|
||||
}
|
||||
|
||||
qmlStateInstance.refreshState();
|
||||
bool QmlPropertyChangesObject::hasActionForProperty(const QString &propertyName) const
|
||||
{
|
||||
for(ActionList::iterator actionIterator = m_qmlActionList.begin();
|
||||
actionIterator != m_qmlActionList.end();
|
||||
++actionIterator) {
|
||||
QDeclarativeAction &qmlAction = *actionIterator;
|
||||
if (qmlAction.specifiedProperty == propertyName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QDeclarativeAction &QmlPropertyChangesObject::qmlActionForProperty(const QString &propertyName) const
|
||||
{
|
||||
for(ActionList::iterator actionIterator = m_qmlActionList.begin();
|
||||
actionIterator != m_qmlActionList.end();
|
||||
++actionIterator) {
|
||||
QDeclarativeAction &qmlAction = *actionIterator;
|
||||
if (qmlAction.specifiedProperty == propertyName)
|
||||
return qmlAction;
|
||||
}
|
||||
|
||||
Q_ASSERT(false);
|
||||
|
||||
return m_qmlActionList[0];
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::removeActionForProperty(const QString &propertyName)
|
||||
{
|
||||
QMutableListIterator<QDeclarativeAction> actionIterator(m_qmlActionList);
|
||||
while (actionIterator.hasNext()) {
|
||||
QDeclarativeAction &qmlAction = actionIterator.next();
|
||||
if (qmlAction.specifiedProperty == propertyName)
|
||||
actionIterator.remove();
|
||||
}
|
||||
|
||||
QMutableListIterator<QDeclarativeSimpleAction> simpleActionIterator(statePrivate()->revertList);
|
||||
while (simpleActionIterator.hasNext()) {
|
||||
QDeclarativeSimpleAction &qmlSimpleAction = simpleActionIterator.next();
|
||||
if (qmlSimpleAction.specifiedProperty == propertyName && qmlSimpleAction.specifiedObject == targetObject()) {
|
||||
simpleActionIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QmlPropertyChangesObject::isActive() const
|
||||
{
|
||||
if (state() && stateGroup())
|
||||
return state()->name() == stateGroup()->state();
|
||||
|
||||
return false;
|
||||
}
|
||||
QmlPropertyChangesObject::~QmlPropertyChangesObject()
|
||||
{
|
||||
removeFromStateRevertList();
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::removeFromStateRevertList()
|
||||
{
|
||||
if (statePrivate()) {
|
||||
QMutableListIterator<QDeclarativeSimpleAction> simpleActionIterator(statePrivate()->revertList);
|
||||
while(simpleActionIterator.hasNext()) {
|
||||
QDeclarativeSimpleAction &simpleAction = simpleActionIterator.next();
|
||||
if (simpleAction.specifiedObject == targetObject()) {
|
||||
Q_ASSERT(simpleAction.property.isValid());
|
||||
if (simpleAction.binding) {
|
||||
QDeclarativePropertyPrivate::setBinding(simpleAction.property, simpleAction.binding);
|
||||
} else if (simpleAction.value.isValid()) {
|
||||
QDeclarativePropertyPrivate::setBinding(simpleAction.property, 0);
|
||||
simpleAction.property.write(simpleAction.value);
|
||||
}
|
||||
simpleActionIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::addToStateRevertList()
|
||||
{
|
||||
if (isActive() && statePrivate()) {
|
||||
QListIterator<QDeclarativeAction> actionIterator(m_qmlActionList);
|
||||
while (actionIterator.hasNext()) {
|
||||
const QDeclarativeAction &qmlAction = actionIterator.next();
|
||||
QDeclarativeSimpleAction simpleAction(qmlAction);
|
||||
simpleAction.binding = qmlAction.fromBinding;
|
||||
simpleAction.value = qmlAction.fromValue;
|
||||
statePrivate()->revertList.append(simpleAction);
|
||||
if (qmlAction.toBinding)
|
||||
QDeclarativePropertyPrivate::setBinding(qmlAction.property, qmlAction.toBinding);
|
||||
else
|
||||
qmlAction.property.write(qmlAction.toValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::updateRevertValueAndBinding(const QString &name)
|
||||
{
|
||||
if (isActive() && statePrivate()) {
|
||||
typedef QList<QDeclarativeSimpleAction> SimpleActionList;
|
||||
if (!statePrivate()->revertList.isEmpty()) {
|
||||
for(SimpleActionList::iterator actionIterator = statePrivate()->revertList.begin();
|
||||
actionIterator != statePrivate()->revertList.end();
|
||||
++actionIterator) {
|
||||
//simple action defines values and bindings to revert current state
|
||||
QDeclarativeSimpleAction &simpleAction = *actionIterator;
|
||||
if (simpleAction.specifiedObject == targetObject()
|
||||
&& simpleAction.specifiedProperty == name) {
|
||||
const QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
simpleAction.value = qmlAction.fromValue;
|
||||
simpleAction.binding = qmlAction.fromBinding;
|
||||
return; //return since we just had to update exisisting simple action
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//simple action does not exist, yet
|
||||
|
||||
const QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
QDeclarativeSimpleAction simpleAction(qmlAction);
|
||||
simpleAction.binding = qmlAction.fromBinding;
|
||||
simpleAction.value = qmlAction.fromValue;
|
||||
statePrivate()->revertList.append(simpleAction);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::setVariantValue(const QString &name, const QVariant & value)
|
||||
{
|
||||
if (!hasActionForProperty(name)) {
|
||||
m_qmlActionList.append(createQDeclarativeAction(name));
|
||||
}
|
||||
|
||||
QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
qmlAction.toValue = value;
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::setExpression(const QString &name, const QString &expression)
|
||||
{
|
||||
if (!hasActionForProperty(name)) {
|
||||
m_qmlActionList.append(createQDeclarativeAction(name));
|
||||
}
|
||||
|
||||
QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
if (m_expressionHash.contains(name) && m_expressionHash[name].second) {
|
||||
m_expressionHash[name].second->destroy();
|
||||
}
|
||||
|
||||
QDeclarativeContext *context = QDeclarativeEngine::contextForObject(targetObject());
|
||||
QDeclarativeBinding *binding = 0;
|
||||
QDeclarativeProperty metaProperty(targetObject(), name, context);
|
||||
if (metaProperty.isValid() && metaProperty.isProperty()) {
|
||||
binding = new QDeclarativeBinding(expression, targetObject(), context, this);
|
||||
binding->setTarget(metaProperty);
|
||||
binding->setNotifyOnValueChanged(true);
|
||||
qmlAction.toBinding = binding;
|
||||
m_expressionHash.insert(name, ExpressionPair(expression, binding));
|
||||
} else {
|
||||
qWarning() << "Cannot set binding for property" << name << ": property is unknown for type";
|
||||
}
|
||||
|
||||
updateRevertValueAndBinding(name);
|
||||
if (isActive())
|
||||
QDeclarativePropertyPrivate::setBinding(metaProperty, binding, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::removeVariantValue(const QString &name)
|
||||
{
|
||||
if (hasActionForProperty(name)) {
|
||||
QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
if (hasExpression(name)) {
|
||||
qmlAction.toValue = QVariant();
|
||||
updateRevertValueAndBinding(name);
|
||||
} else {
|
||||
if (qmlAction.fromBinding)
|
||||
QDeclarativePropertyPrivate::setBinding(qmlAction.property, qmlAction.fromBinding);
|
||||
else
|
||||
qmlAction.property.write(qmlAction.fromValue);
|
||||
removeActionForProperty(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::removeExpression(const QString &name)
|
||||
{
|
||||
if (hasActionForProperty(name)) {
|
||||
QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
if (hasVariantValue(name)) {
|
||||
ExpressionPair expr = m_expressionHash.take(name);
|
||||
if (expr.second)
|
||||
expr.second.data()->destroy();
|
||||
qmlAction.toBinding = 0;
|
||||
updateRevertValueAndBinding(name);
|
||||
qmlAction.property.write(qmlAction.toValue);
|
||||
} else {
|
||||
if (qmlAction.fromBinding)
|
||||
QDeclarativePropertyPrivate::setBinding(qmlAction.property, qmlAction.fromBinding);
|
||||
else
|
||||
qmlAction.property.write(qmlAction.fromValue);
|
||||
removeActionForProperty(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlPropertyChangesObject::resetProperty(const QString &name)
|
||||
{
|
||||
if (statePrivate()) {
|
||||
QMutableListIterator<QDeclarativeSimpleAction> simpleActionIterator(statePrivate()->revertList);
|
||||
while (simpleActionIterator.hasNext()) {
|
||||
QDeclarativeSimpleAction &qmlSimpleAction = simpleActionIterator.next();
|
||||
if (qmlSimpleAction.specifiedProperty == name && qmlSimpleAction.specifiedObject == targetObject()) {
|
||||
if (qmlSimpleAction.binding) {
|
||||
qDebug() << qmlSimpleAction.binding->expression();
|
||||
QDeclarativePropertyPrivate::setBinding(qmlSimpleAction.property, qmlSimpleAction.binding);
|
||||
} else {
|
||||
QDeclarativePropertyPrivate::setBinding(qmlSimpleAction.property, 0);
|
||||
qmlSimpleAction.property.write(qmlSimpleAction.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_expressionHash.contains(name)) {
|
||||
if (m_expressionHash[name].second)
|
||||
m_expressionHash[name].second.data()->destroy();
|
||||
m_expressionHash.remove(name);
|
||||
}
|
||||
|
||||
if (hasActionForProperty(name)) {
|
||||
removeActionForProperty(name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
QVariant QmlPropertyChangesObject::variantValue(const QString &name) const
|
||||
{
|
||||
if (hasActionForProperty(name)) {
|
||||
QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
return qmlAction.toValue;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QString QmlPropertyChangesObject::expression(const QString &name) const
|
||||
{
|
||||
if (hasActionForProperty(name)) {
|
||||
QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
if (qmlAction.toBinding)
|
||||
return qmlAction.toBinding->expression();
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool QmlPropertyChangesObject::hasVariantValue(const QString &name) const
|
||||
{
|
||||
if (hasActionForProperty(name))
|
||||
return qmlActionForProperty(name).toValue.isValid();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QmlPropertyChangesObject::hasExpression(const QString &name) const
|
||||
{
|
||||
return m_expressionHash.contains(name);
|
||||
}
|
||||
|
||||
bool QmlPropertyChangesObject::updateStateVariant(const QString &name, const QVariant &value)
|
||||
{
|
||||
if (hasActionForProperty(name)) {
|
||||
QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
if (qmlAction.fromValue.isValid()) {
|
||||
qmlAction.fromValue = value;
|
||||
updateRevertValueAndBinding(name);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QmlPropertyChangesObject::updateStateBinding(const QString &name, const QString &expression)
|
||||
{
|
||||
if (hasActionForProperty(name)) {
|
||||
QDeclarativeContext *context = QDeclarativeEngine::contextForObject(targetObject());
|
||||
QDeclarativeProperty metaProperty(targetObject(), name, context);
|
||||
QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
|
||||
if (qmlAction.fromBinding) {
|
||||
if (QDeclarativePropertyPrivate::binding(qmlAction.property) == qmlAction.fromBinding)
|
||||
QDeclarativePropertyPrivate::setBinding(qmlAction.property, 0);
|
||||
qmlAction.fromBinding->destroy();
|
||||
|
||||
}
|
||||
|
||||
QDeclarativeBinding *binding = new QDeclarativeBinding(expression, targetObject(), context, this);
|
||||
binding->setTarget(metaProperty);
|
||||
binding->setNotifyOnValueChanged(true);
|
||||
qmlAction.fromBinding = binding;
|
||||
|
||||
if (m_expressionHash.contains(name))
|
||||
QDeclarativePropertyPrivate::setBinding(qmlAction.property, binding);
|
||||
|
||||
updateRevertValueAndBinding(name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QmlPropertyChangesObject::resetStateProperty(const QString &name, const QVariant &resetValue)
|
||||
{
|
||||
if (hasActionForProperty(name)) {
|
||||
QDeclarativeContext *context = QDeclarativeEngine::contextForObject(targetObject());
|
||||
QDeclarativeProperty metaProperty(targetObject(), name, context);
|
||||
QDeclarativeAction &qmlAction = qmlActionForProperty(name);
|
||||
if (m_expressionHash.contains(name) && m_expressionHash[name].second) {
|
||||
m_expressionHash[name].second.data()->destroy();
|
||||
qmlAction.toBinding = 0;
|
||||
}
|
||||
|
||||
qmlAction.fromValue = resetValue;
|
||||
|
||||
updateRevertValueAndBinding(name);
|
||||
|
||||
removeActionForProperty(name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
#include "objectnodeinstance.h"
|
||||
#include <private/qdeclarativestateoperations_p.h>
|
||||
|
||||
#include <QPair>
|
||||
#include <QWeakPointer>
|
||||
|
||||
class QDeclarativeProperty;
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
namespace Internal {
|
||||
@@ -44,35 +49,70 @@ class QmlPropertyChangesNodeInstance;
|
||||
class QmlPropertyChangesObject : public QDeclarativeStateOperation
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QObject *target READ object WRITE setObject)
|
||||
Q_PROPERTY(QObject *target READ targetObject WRITE setTargetObject)
|
||||
Q_PROPERTY(bool restoreEntryValues READ restoreEntryValues WRITE setRestoreEntryValues)
|
||||
Q_PROPERTY(bool explicit READ isExplicit WRITE setIsExplicit)
|
||||
|
||||
typedef QPair<QString, QWeakPointer<QDeclarativeBinding> > ExpressionPair;
|
||||
public:
|
||||
QObject *object() const { return m_targetObject.data(); }
|
||||
void setObject(QObject *object) {m_targetObject = object; }
|
||||
~QmlPropertyChangesObject();
|
||||
QObject *targetObject() const;
|
||||
void setTargetObject(QObject *object);
|
||||
|
||||
bool restoreEntryValues() const { return m_restoreEntryValues; }
|
||||
void setRestoreEntryValues(bool restore) { m_restoreEntryValues = restore; }
|
||||
bool restoreEntryValues() const;
|
||||
void setRestoreEntryValues(bool restore);
|
||||
|
||||
bool isExplicit() const { return m_isExplicit; }
|
||||
void setIsExplicit(bool isExplicit) { m_isExplicit = isExplicit; }
|
||||
bool isExplicit() const;
|
||||
void setIsExplicit(bool isExplicit);
|
||||
|
||||
virtual ActionList actions();
|
||||
|
||||
private:
|
||||
friend class QmlPropertyChangesNodeInstance;
|
||||
void setVariantValue(const QString &name, const QVariant & value);
|
||||
void setExpression(const QString &name, const QString &expression);
|
||||
void removeVariantValue(const QString &name);
|
||||
void removeExpression(const QString &name);
|
||||
|
||||
void resetProperty(const QString &name);
|
||||
|
||||
QVariant variantValue(const QString &name) const;
|
||||
QString expression(const QString &name) const;
|
||||
|
||||
bool hasVariantValue(const QString &name) const;
|
||||
bool hasExpression(const QString &name) const;
|
||||
|
||||
QmlPropertyChangesObject();
|
||||
QDeclarativeProperty metaProperty(const QString &property);
|
||||
|
||||
bool updateStateVariant(const QString &propertyName, const QVariant &value);
|
||||
bool updateStateBinding(const QString &propertyName, const QString &expression);
|
||||
bool resetStateProperty(const QString &propertyName, const QVariant &resetValue);
|
||||
|
||||
QDeclarativeState *state() const;
|
||||
void updateRevertValueAndBinding(const QString &name);
|
||||
|
||||
void removeFromStateRevertList();
|
||||
void addToStateRevertList();
|
||||
|
||||
private: // functions
|
||||
bool isActive() const;
|
||||
|
||||
QDeclarativeStatePrivate *statePrivate() const;
|
||||
|
||||
QDeclarativeStateGroup *stateGroup() const;
|
||||
QDeclarativeProperty createMetaProperty(const QString &property);
|
||||
|
||||
QDeclarativeAction &qmlActionForProperty(const QString &propertyName) const;
|
||||
bool hasActionForProperty(const QString &propertyName) const;
|
||||
void removeActionForProperty(const QString &propertyName);
|
||||
|
||||
QDeclarativeAction createQDeclarativeAction(const QString &propertyName);
|
||||
|
||||
private: // variables
|
||||
QWeakPointer<QObject> m_targetObject;
|
||||
bool m_restoreEntryValues;
|
||||
bool m_isExplicit;
|
||||
|
||||
QHash<QString, QVariant> m_properties;
|
||||
QHash<QString, QString> m_expressions;
|
||||
// QList<QmlReplaceSignalHandler*> signalReplacements;
|
||||
mutable ActionList m_qmlActionList;
|
||||
QHash<QString, ExpressionPair> m_expressionHash;
|
||||
};
|
||||
|
||||
class QmlPropertyChangesNodeInstance : public ObjectNodeInstance
|
||||
@@ -88,7 +128,7 @@ public:
|
||||
virtual QVariant property(const QString &name) const;
|
||||
virtual void resetProperty(const QString &name);
|
||||
|
||||
void updateStateInstance() const;
|
||||
void reparent(const NodeInstance &oldParentInstance, const QString &oldParentProperty, const NodeInstance &newParentInstance, const QString &newParentProperty);
|
||||
|
||||
protected:
|
||||
QmlPropertyChangesNodeInstance(QmlPropertyChangesObject *object);
|
||||
|
||||
@@ -32,14 +32,16 @@
|
||||
|
||||
#include <private/qdeclarativestategroup_p.h>
|
||||
|
||||
#include "qmlpropertychangesnodeinstance.h"
|
||||
#include <private/qdeclarativestateoperations_p.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
/**
|
||||
\class QmlStateNodeInstance
|
||||
|
||||
QmlStateNodeInstance manages a QDeclarativeState object. One can activate / deactivate a state
|
||||
by setting/unsetting the special "__activateState" boolean property.
|
||||
QmlStateNodeInstance manages a QDeclarativeState object.
|
||||
*/
|
||||
|
||||
QmlStateNodeInstance::QmlStateNodeInstance(QDeclarativeState *object) :
|
||||
@@ -68,6 +70,7 @@ void QmlStateNodeInstance::activateState()
|
||||
{
|
||||
if (stateGroup()) {
|
||||
if (!isStateActive())
|
||||
nodeInstanceView()->setStateInstance(nodeInstanceView()->instanceForNode(modelNode()));
|
||||
stateGroup()->setState(property("name").toString());
|
||||
}
|
||||
}
|
||||
@@ -75,17 +78,11 @@ void QmlStateNodeInstance::activateState()
|
||||
void QmlStateNodeInstance::deactivateState()
|
||||
{
|
||||
if (stateGroup()) {
|
||||
if (isStateActive())
|
||||
if (isStateActive()) {
|
||||
nodeInstanceView()->clearStateInstance();
|
||||
stateGroup()->setState(QString());
|
||||
}
|
||||
}
|
||||
|
||||
void QmlStateNodeInstance::refreshState()
|
||||
{
|
||||
nodeInstanceView()->setBlockStatePropertyChanges(true);
|
||||
deactivateState();
|
||||
activateState();
|
||||
nodeInstanceView()->setBlockStatePropertyChanges(false);
|
||||
}
|
||||
}
|
||||
|
||||
QDeclarativeState *QmlStateNodeInstance::stateObject() const
|
||||
@@ -127,5 +124,45 @@ void QmlStateNodeInstance::setPropertyBinding(const QString &name, const QString
|
||||
ObjectNodeInstance::setPropertyBinding(name, expression);
|
||||
}
|
||||
|
||||
bool QmlStateNodeInstance::updateStateVariant(const NodeInstance &target, const QString &propertyName, const QVariant &value)
|
||||
{
|
||||
// iterate over propertychange object and update values
|
||||
QDeclarativeListReference listReference(stateObject(), "changes");
|
||||
for (int i = 0; i < listReference.count(); i++) {
|
||||
//We also have parent and anchor changes
|
||||
QmlPropertyChangesObject *changeObject = qobject_cast<QmlPropertyChangesObject*>(listReference.at(i));
|
||||
if (changeObject && target.isWrappingThisObject(changeObject->targetObject()))
|
||||
return changeObject->updateStateVariant(propertyName, value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QmlStateNodeInstance::updateStateBinding(const NodeInstance &target, const QString &propertyName, const QString &expression)
|
||||
{
|
||||
// iterate over propertychange object and update binding
|
||||
QDeclarativeListReference listReference(stateObject(), "changes");
|
||||
for (int i = 0; i < listReference.count(); i++) {
|
||||
QmlPropertyChangesObject *changeObject = qobject_cast<QmlPropertyChangesObject*>(listReference.at(i));
|
||||
if (changeObject && target.isWrappingThisObject(changeObject->targetObject()))
|
||||
return changeObject->updateStateBinding(propertyName, expression);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QmlStateNodeInstance::resetStateProperty(const NodeInstance &target, const QString &propertyName, const QVariant &resetValue)
|
||||
{
|
||||
// iterate over propertychange object and reset propertry
|
||||
QDeclarativeListReference listReference(stateObject(), "changes");
|
||||
for (int i = 0; i < listReference.count(); i++) {
|
||||
QmlPropertyChangesObject *changeObject = qobject_cast<QmlPropertyChangesObject*>(listReference.at(i));
|
||||
if (changeObject && target.isWrappingThisObject(changeObject->targetObject()))
|
||||
return changeObject->resetStateProperty(propertyName, resetValue);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -54,9 +54,14 @@ public:
|
||||
|
||||
void activateState();
|
||||
void deactivateState();
|
||||
void refreshState();
|
||||
|
||||
bool updateStateVariant(const NodeInstance &target, const QString &propertyName, const QVariant &value);
|
||||
bool updateStateBinding(const NodeInstance &target, const QString &propertyName, const QString &expression);
|
||||
bool resetStateProperty(const NodeInstance &target, const QString &propertyName, const QVariant &resetValue);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
QmlStateNodeInstance(QDeclarativeState *object);
|
||||
|
||||
bool isStateActive() const;
|
||||
|
||||
@@ -272,6 +272,7 @@ static bool isTransformProperty(const QString &name)
|
||||
|
||||
void QmlModelView::nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName)
|
||||
{
|
||||
|
||||
QmlObjectNode qmlObjectNode(node);
|
||||
|
||||
if (!qmlObjectNode.isValid())
|
||||
@@ -298,18 +299,16 @@ void QmlModelView::activateState(const QmlModelState &state)
|
||||
QmlModelState oldState = m_state;
|
||||
|
||||
NodeInstance newStateInstance = instanceForModelNode(state.modelNode());
|
||||
NodeInstance oldStateInstance = oldState.isValid() ? instanceForModelNode(oldState.modelNode()) : NodeInstance();
|
||||
|
||||
if (state.isBaseState()) {
|
||||
if (oldStateInstance.isValid())
|
||||
oldStateInstance.deactivateState();
|
||||
nodeInstanceView()->activateBaseState();
|
||||
} else {
|
||||
newStateInstance.activateState();
|
||||
nodeInstanceView()->activateState(newStateInstance);
|
||||
}
|
||||
|
||||
m_state = state;
|
||||
|
||||
stateChanged(state, oldState);
|
||||
}
|
||||
stateChanged(state, oldState);}
|
||||
|
||||
void QmlModelView::changeToState(const ModelNode &node, const QString &stateName)
|
||||
{
|
||||
|
||||
@@ -64,6 +64,8 @@ void QmlObjectNode::setBindingProperty(const QString &name, const QString &expre
|
||||
if (isInBaseState()) {
|
||||
modelNode().bindingProperty(name) = expression; //basestate
|
||||
} else {
|
||||
modelNode().validId();
|
||||
|
||||
QmlPropertyChanges changeSet(currentState().propertyChanges(modelNode()));
|
||||
Q_ASSERT(changeSet.isValid());
|
||||
changeSet.modelNode().bindingProperty(name) = expression;
|
||||
|
||||
@@ -3651,36 +3651,36 @@ void TestCore::testInstancesStates()
|
||||
|
||||
// base state
|
||||
QVERIFY(textInstance.isValid());
|
||||
QCOMPARE(state1Instance.property("__activateState").toBool(), false);
|
||||
QCOMPARE(state2Instance.property("__activateState").toBool(), false);
|
||||
QCOMPARE(state1Instance == instanceView->stateInstance(), false);
|
||||
QCOMPARE(state2Instance == instanceView->stateInstance(), false);
|
||||
QCOMPARE(textInstance.property("x").toInt(), 0);
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
|
||||
// base state -> state
|
||||
state1Instance.setPropertyVariant("__activateState", true);
|
||||
QCOMPARE(state1Instance.property("__activateState").toBool(), true);
|
||||
QCOMPARE(state2Instance.property("__activateState").toBool(), false);
|
||||
instanceView->activateState(state1Instance);
|
||||
QCOMPARE(state1Instance == instanceView->stateInstance(), true);
|
||||
QCOMPARE(state2Instance == instanceView->stateInstance(), false);
|
||||
QCOMPARE(textInstance.property("x").toInt(), 10);
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("state1"));
|
||||
|
||||
// state 1 -> state 2
|
||||
state2Instance.setPropertyVariant("__activateState", true);
|
||||
QCOMPARE(state1Instance.property("__activateState").toBool(), false);
|
||||
QCOMPARE(state2Instance.property("__activateState").toBool(), true);
|
||||
instanceView->activateState(state2Instance);
|
||||
QCOMPARE(state1Instance == instanceView->stateInstance(), false);
|
||||
QCOMPARE(state2Instance == instanceView->stateInstance(), true);
|
||||
QCOMPARE(textInstance.property("x").toInt(), 0);
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("state2"));
|
||||
|
||||
// state 1 -> base state
|
||||
state2Instance.setPropertyVariant("__activateState", false);
|
||||
QCOMPARE(state1Instance.property("__activateState").toBool(), false);
|
||||
QCOMPARE(state2Instance.property("__activateState").toBool(), false);
|
||||
instanceView->activateBaseState();
|
||||
QCOMPARE(state1Instance == instanceView->stateInstance(), false);
|
||||
QCOMPARE(state2Instance == instanceView->stateInstance(), false);
|
||||
QCOMPARE(textInstance.property("x").toInt(), 0);
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
|
||||
//
|
||||
// Add/Change/Remove properties in current state
|
||||
//
|
||||
state1Instance.setPropertyVariant("__activateState", true);
|
||||
instanceView->activateState(state1Instance);
|
||||
|
||||
propertyChanges1Node.variantProperty("x").setValue(20);
|
||||
QCOMPARE(textInstance.property("x").toInt(), 20);
|
||||
@@ -3707,37 +3707,85 @@ void TestCore::testInstancesStates()
|
||||
// Reparenting state actions (while state is active)
|
||||
//
|
||||
|
||||
// state1Instance.setPropertyVariant("__activateState", true);
|
||||
// // move property changes of current state out of state
|
||||
// ModelNode state3Node = view->createModelNode("Qt/State", 4, 6);
|
||||
// state3Node.nodeListProperty("changes").reparentHere(propertyChanges1Node);
|
||||
//
|
||||
// QCOMPARE(state1->changes()->count(), 0);
|
||||
// QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
//
|
||||
// // undo
|
||||
// state1Node.nodeListProperty("changes").reparentHere(propertyChanges1Node);
|
||||
// QCOMPARE(state1->changes()->count(), 1);
|
||||
// QCOMPARE(textInstance.property("text").toString(), QString("state 1"));
|
||||
// move property changes of current state out of state
|
||||
ModelNode state3Node = view->createModelNode("Qt/State", 4, 6);
|
||||
QDeclarativeListReference changes(state1, "changes");
|
||||
QCOMPARE(changes.count(), 1);
|
||||
state3Node.nodeListProperty("changes").reparentHere(propertyChanges1Node);
|
||||
|
||||
QCOMPARE(changes.count(), 0);
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
|
||||
// undo
|
||||
state1Node.nodeListProperty("changes").reparentHere(propertyChanges1Node);
|
||||
QCOMPARE(changes.count(), 1);
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("state1"));
|
||||
|
||||
|
||||
// change base state if in state1
|
||||
|
||||
textNode.variantProperty("text").setValue("state1 and base state");
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("state1"));
|
||||
instanceView->activateBaseState();
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("state1 and base state"));
|
||||
textNode.variantProperty("text").setValue("base state");
|
||||
|
||||
// expressions
|
||||
ModelNode textNode2 = view->createModelNode("Qt/Text", 4, 6);
|
||||
textNode2.setId("targetObject2");
|
||||
textNode2.variantProperty("text").setValue("textNode2");
|
||||
|
||||
|
||||
rootNode.nodeListProperty("data").reparentHere(textNode2);
|
||||
|
||||
propertyChanges1Node.bindingProperty("text").setExpression("targetObject2.text");
|
||||
|
||||
instanceView->activateState(state1Instance);
|
||||
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("textNode2"));
|
||||
propertyChanges1Node.removeProperty("text");
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
propertyChanges1Node.variantProperty("text").setValue("state1");
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("state1"));
|
||||
|
||||
propertyChanges1Node.bindingProperty("text").setExpression("targetObject2.text");
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("textNode2"));
|
||||
|
||||
instanceView->activateBaseState();
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
|
||||
propertyChanges1Node.variantProperty("text").setValue("state1");
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
textNode.bindingProperty("text").setExpression("targetObject2.text");
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("textNode2"));
|
||||
|
||||
instanceView->activateState(state1Instance);
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("state1"));
|
||||
|
||||
instanceView->activateBaseState();
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("textNode2"));
|
||||
textNode.variantProperty("text").setValue("base state");
|
||||
|
||||
instanceView->activateState(state1Instance);
|
||||
//
|
||||
// Removing state actions (while state is active)
|
||||
//
|
||||
|
||||
// state1Instance.setPropertyVariant("__activateState", true);
|
||||
// QCOMPARE(textInstance.property("text").toString(), QString("state1"));
|
||||
// propertyChanges1Node.destroy();
|
||||
// QCOMPARE(state1->changes()->count(), 0);
|
||||
// QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("state1"));
|
||||
propertyChanges1Node.destroy();
|
||||
QCOMPARE(changes.count(), 0);
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
|
||||
//
|
||||
// Removing state (while active)
|
||||
//
|
||||
|
||||
// state2Instance.setPropertyVariant("__activateState", true);
|
||||
// QCOMPARE(textInstance.property("text").toString(), QString("state2"));
|
||||
// state2Node.destroy();
|
||||
// QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
instanceView->activateState(state2Instance);
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("state2"));
|
||||
state2Node.destroy();
|
||||
|
||||
QCOMPARE(textInstance.property("text").toString(), QString("base state"));
|
||||
|
||||
}
|
||||
|
||||
void TestCore::testStates()
|
||||
@@ -3796,14 +3844,14 @@ void TestCore::testStates()
|
||||
|
||||
NodeInstance state1Instance = view->nodeInstanceView()->instanceForNode(state1);
|
||||
QVERIFY(state1Instance.isValid());
|
||||
QCOMPARE(state1Instance.property("__activateState").toBool(), false);
|
||||
QCOMPARE(state1Instance == view->nodeInstanceView()->stateInstance(), false);
|
||||
QCOMPARE(state1Instance.property("name").toString(), QString("state 1"));
|
||||
|
||||
view->setCurrentState(state1); //set currentState "state 1"
|
||||
|
||||
QCOMPARE(view->currentState(), state1);
|
||||
|
||||
QCOMPARE(state1Instance.property("__activateState").toBool(), true);
|
||||
QCOMPARE(state1Instance == view->nodeInstanceView()->stateInstance(), true);
|
||||
|
||||
QVERIFY(!textItem.propertyAffectedByCurrentState("text"));
|
||||
|
||||
@@ -3825,7 +3873,7 @@ void TestCore::testStates()
|
||||
QCOMPARE(changes.modelNode().parentProperty().name(), QString("changes"));
|
||||
QCOMPARE(changes.modelNode().parentProperty().parentModelNode(), state1.modelNode());
|
||||
|
||||
QCOMPARE(state1Instance.property("__activateState").toBool(), true);
|
||||
QCOMPARE(state1Instance == view->nodeInstanceView()->stateInstance(), true);
|
||||
|
||||
QVERIFY(textItem.propertyAffectedByCurrentState("text"));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user