1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "qmlobjectnode.h"
35 #include "qmlitemnode.h"
36 #include "qmlitemnode.h"
38 #include "variantproperty.h"
39 #include "nodeproperty.h"
40 #include <invalidmodelnodeexception.h>
41 #include "qmlmodelview.h"
42 #include "nodeinstanceview.h"
43 #include "nodeinstance.h"
44 #include "nodemetainfo.h"
45 #include "bindingproperty.h"
46 #include "nodelistproperty.h"
48 namespace QmlDesigner {
50 void QmlObjectNode::setVariantProperty(const QString &name, const QVariant &value)
53 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
55 if (isInBaseState()) {
56 modelNode().variantProperty(name).setValue(value); //basestate
58 modelNode().validId();
60 QmlPropertyChanges changeSet(currentState().propertyChanges(modelNode()));
61 Q_ASSERT(changeSet.isValid());
62 changeSet.modelNode().variantProperty(name) = value;
66 void QmlObjectNode::setBindingProperty(const QString &name, const QString &expression)
69 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
71 if (isInBaseState()) {
72 modelNode().bindingProperty(name) = expression; //basestate
74 modelNode().validId();
76 QmlPropertyChanges changeSet(currentState().propertyChanges(modelNode()));
77 Q_ASSERT(changeSet.isValid());
78 changeSet.modelNode().bindingProperty(name) = expression;
82 QmlModelState QmlObjectNode::currentState() const
85 return qmlModelView()->currentState();
87 return QmlModelState();
90 bool QmlObjectNode::isRootModelNode() const
92 return modelNode().isRootNode();
96 /*! \brief returns the value of a property based on an actual instance
97 The return value is not the value in the model, but the value of a real
98 instanciated instance of this object.
99 \return the value of this property based on the instance
102 QVariant QmlObjectNode::instanceValue(const QString &name) const
104 return nodeInstance().property(name);
108 bool QmlObjectNode::hasProperty(const QString &name) const
111 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
113 if (currentState().hasPropertyChanges(modelNode())) {
114 QmlPropertyChanges propertyChanges = currentState().propertyChanges(modelNode());
115 if (propertyChanges.modelNode().hasProperty(name))
119 return modelNode().hasProperty(name);
122 bool QmlObjectNode::hasBindingProperty(const QString &name) const
125 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
127 if (currentState().hasPropertyChanges(modelNode())) {
128 QmlPropertyChanges propertyChanges = currentState().propertyChanges(modelNode());
129 if (propertyChanges.modelNode().hasBindingProperty(name))
133 return modelNode().hasBindingProperty(name);
136 NodeAbstractProperty QmlObjectNode::nodeAbstractProperty(const QString &name) const
138 return modelNode().nodeAbstractProperty(name);
141 NodeProperty QmlObjectNode::nodeProperty(const QString &name) const
143 return modelNode().nodeProperty(name);
146 NodeListProperty QmlObjectNode::nodeListProperty(const QString &name) const
148 return modelNode().nodeListProperty(name);
151 bool QmlObjectNode::propertyAffectedByCurrentState(const QString &name) const
154 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
156 if (currentState().isBaseState())
157 return modelNode().hasProperty(name);
159 if (!currentState().hasPropertyChanges(modelNode()))
162 return currentState().propertyChanges(modelNode()).modelNode().hasProperty(name);
165 QVariant QmlObjectNode::modelValue(const QString &name) const
168 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
170 if (currentState().isBaseState())
171 return modelNode().variantProperty(name).value();
173 if (!currentState().hasPropertyChanges(modelNode()))
174 return modelNode().variantProperty(name).value();
176 QmlPropertyChanges propertyChanges(currentState().propertyChanges(modelNode()));
178 if (!propertyChanges.modelNode().hasProperty(name))
179 return modelNode().variantProperty(name).value();
181 return propertyChanges.modelNode().variantProperty(name).value();
184 QString QmlObjectNode::expression(const QString &name) const
187 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
189 if (currentState().isBaseState())
190 return modelNode().bindingProperty(name).expression();
192 if (!currentState().hasPropertyChanges(modelNode()))
193 return modelNode().bindingProperty(name).expression();
195 QmlPropertyChanges propertyChanges(currentState().propertyChanges(modelNode()));
197 if (!propertyChanges.modelNode().hasProperty(name))
198 return modelNode().bindingProperty(name).expression();
200 return propertyChanges.modelNode().bindingProperty(name).expression();
203 /*! \brief returns if ObjectNode is the BaseState
205 \return true if the ObjectNode is in the BaseState
208 bool QmlObjectNode::isInBaseState() const
210 return currentState().isBaseState();
213 bool QmlObjectNode::canReparent() const
215 return isInBaseState();
218 QmlPropertyChanges QmlObjectNode::propertyChangeForCurrentState() const
221 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
223 if (currentState().isBaseState())
224 return QmlPropertyChanges();
226 if (!currentState().hasPropertyChanges(modelNode()))
227 return QmlPropertyChanges();
229 return currentState().propertyChanges(modelNode());
232 static void removeStateOperationsForChildren(const QmlObjectNode &node)
234 if (node.isValid()) {
235 foreach (QmlModelStateOperation stateOperation, node.allAffectingStatesOperations()) {
236 stateOperation.modelNode().destroy(); //remove of belonging StatesOperations
239 foreach (const QmlObjectNode &childNode, node.modelNode().allDirectSubModelNodes()) {
240 removeStateOperationsForChildren(childNode);
246 /*! \brief Deletes this objects ModeNode and its dependencies from the model
247 Every thing that belongs to this Object, the ModelNode and ChangeOperations
248 are deleted from the model.
251 void QmlObjectNode::destroy()
254 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
256 foreach (QmlModelStateOperation stateOperation, allAffectingStatesOperations()) {
257 stateOperation.modelNode().destroy(); //remove of belonging StatesOperations
259 removeStateOperationsForChildren(modelNode());
260 modelNode().destroy();
263 /*! \brief Returns a list of all states that are affecting this object.
265 \return list of states affecting this object
268 QList<QmlModelState> QmlObjectNode::allAffectingStates() const
271 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
273 QList<QmlModelState> returnList;
275 foreach (const QmlModelState &state, allDefinedStates()) {
276 if (state.affectsModelNode(modelNode()))
277 returnList.append(state);
282 /*! \brief Returns a list of all state operations that are affecting this object.
284 \return list of state operations affecting this object
287 QList<QmlModelStateOperation> QmlObjectNode::allAffectingStatesOperations() const
290 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
292 QList<QmlModelStateOperation> returnList;
293 foreach (const QmlModelState &state, allDefinedStates()) {
294 if (state.affectsModelNode(modelNode()))
295 returnList.append(state.stateOperations(modelNode()));
301 static QList<QmlItemNode> allFxItemsRecursive(const QmlItemNode &fxNode)
303 QList<QmlItemNode> returnList;
305 if (fxNode.isValid()) {
306 returnList.append(fxNode);
307 QList<QmlItemNode> allChildNodes;
308 foreach (const ModelNode &node, fxNode.modelNode().allDirectSubModelNodes()) {
309 if (QmlItemNode(node).isValid())
310 allChildNodes.append(node);
312 foreach (const QmlItemNode &node, allChildNodes) {
313 returnList.append(allFxItemsRecursive(node));
319 QList<QmlModelState> QmlObjectNode::allDefinedStates() const
322 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
324 QList<QmlModelState> returnList;
326 QList<QmlItemNode> allFxItems;
328 QmlItemNode rootNode(qmlModelView()->rootModelNode());
330 if (rootNode.isValid())
331 allFxItems.append(allFxItemsRecursive(rootNode));
333 foreach (const QmlItemNode &item, allFxItems) {
334 returnList.append(item.states().allStates());
341 /*! \brief Removes a variant property of this object from the model
345 void QmlObjectNode::removeVariantProperty(const QString &name)
348 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
350 if (isInBaseState()) {
351 modelNode().removeProperty(name); //basestate
353 QmlPropertyChanges changeSet(currentState().propertyChanges(modelNode()));
354 Q_ASSERT(changeSet.isValid());
355 changeSet.removeProperty(name);
359 QList<ModelNode> toModelNodeList(const QList<QmlObjectNode> &fxObjectNodeList)
361 QList<ModelNode> modelNodeList;
363 foreach(const QmlObjectNode &fxObjectNode, fxObjectNodeList)
364 modelNodeList.append(fxObjectNode.modelNode());
366 return modelNodeList;
369 QList<QmlObjectNode> toQmlObjectNodeList(const QList<ModelNode> &modelNodeList)
371 QList<QmlObjectNode> qmlObjectNodeList;
373 foreach(const ModelNode &modelNode, modelNodeList) {
374 QmlObjectNode objectNode(modelNode);
375 if (objectNode.isValid())
376 qmlObjectNodeList.append(objectNode);
379 return qmlObjectNodeList;
382 bool QmlObjectNode::isAncestorOf(const QmlObjectNode &objectNode) const
384 return modelNode().isAncestorOf(objectNode.modelNode());
387 QVariant QmlObjectNode::instanceValue(const ModelNode &modelNode, const QString &name)
389 QmlModelView *modelView = qobject_cast<QmlModelView*>(modelNode.view());
391 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
392 Q_ASSERT(modelView->hasInstanceForModelNode(modelNode));
393 return modelView->instanceForModelNode(modelNode).property(name);
396 QString QmlObjectNode::instanceType(const QString &name) const
398 return nodeInstance().instanceType(name);
401 bool QmlObjectNode::instanceHasBinding(const QString &name) const
403 QmlModelView *modelView = qobject_cast<QmlModelView*>(modelNode().view());
405 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
407 return nodeInstance().hasBindingForProperty(name);
410 NodeInstance QmlObjectNode::nodeInstance() const
412 return qmlModelView()->nodeInstanceView()->instanceForNode(modelNode());
415 QmlObjectNode QmlObjectNode::nodeForInstance(const NodeInstance &instance) const
417 return QmlObjectNode(ModelNode(instance.modelNode(), qmlModelView()));
420 bool QmlObjectNode::hasNodeParent() const
422 return modelNode().hasParentProperty();
425 bool QmlObjectNode::hasInstanceParent() const
427 return nodeInstance().parentId() >= 0 && qmlModelView()->nodeInstanceView()->hasInstanceForId(nodeInstance().parentId());
431 void QmlObjectNode::setParentProperty(const NodeAbstractProperty &parentProeprty)
433 return modelNode().setParentProperty(parentProeprty);
436 QmlObjectNode QmlObjectNode::instanceParent() const
438 if (hasInstanceParent())
439 return nodeForInstance(qmlModelView()->nodeInstanceView()->instanceForId(nodeInstance().parentId()));
441 return QmlObjectNode();
444 void QmlObjectNode::setId(const QString &id)
446 modelNode().setId(id);
449 QString QmlObjectNode::id() const
451 return modelNode().id();
454 QString QmlObjectNode::validId()
456 return modelNode().validId();
459 bool QmlObjectNode::hasDefaultProperty() const
461 return modelNode().metaInfo().hasDefaultProperty();
464 QString QmlObjectNode::defaultProperty() const
466 return modelNode().metaInfo().defaultPropertyName();
469 void QmlObjectNode::setParent(QmlObjectNode newParent)
471 if (newParent.hasDefaultProperty()) {
472 newParent.modelNode().nodeAbstractProperty(newParent.defaultProperty()).reparentHere(modelNode());
476 QmlItemNode QmlObjectNode::toQmlItemNode() const
478 return QmlItemNode(modelNode());
481 uint qHash(const QmlObjectNode &node)
483 return qHash(node.modelNode());