1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
34 #include "qmlmodelview.h"
35 #include <nodelistproperty.h>
36 #include <variantproperty.h>
38 #include <invalidmodelnodeexception.h>
39 #include "bindingproperty.h"
42 namespace QmlDesigner {
44 QmlModelState::QmlModelState()
45 : QmlModelNodeFacade(),
50 QmlModelState::QmlModelState(const ModelNode &modelNode)
51 : QmlModelNodeFacade(modelNode),
56 QmlPropertyChanges QmlModelState::propertyChanges(const ModelNode &node)
58 //### exception if not valid
61 return QmlPropertyChanges();
63 addChangeSetIfNotExists(node);
64 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
65 //### exception if not valid QmlModelStateOperation
66 if (QmlPropertyChanges(childNode).target().isValid() && QmlPropertyChanges(childNode).target() == node && QmlPropertyChanges(childNode).isValid())
67 return QmlPropertyChanges(childNode); //### exception if not valid(childNode);
69 return QmlPropertyChanges(); //not found
72 QList<QmlModelStateOperation> QmlModelState::stateOperations(const ModelNode &node) const
74 QList<QmlModelStateOperation> returnList;
75 //### exception if not valid
80 if (!modelNode().hasProperty("changes"))
83 Q_ASSERT(modelNode().property("changes").isNodeListProperty());
85 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
86 QmlModelStateOperation stateOperation(childNode);
87 if (stateOperation.isValid()) {
88 ModelNode targetNode = stateOperation.target();
89 if (targetNode.isValid()
90 && targetNode == node)
91 returnList.append(stateOperation); //### exception if not valid(childNode);
94 return returnList; //not found
97 QList<QmlPropertyChanges> QmlModelState::propertyChanges() const
99 //### exception if not valid
100 QList<QmlPropertyChanges> returnList;
105 if (!modelNode().hasProperty("changes"))
108 Q_ASSERT(modelNode().property("changes").isNodeListProperty());
110 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
111 //### exception if not valid QmlModelStateOperation
112 if (QmlPropertyChanges(childNode).isValid())
113 returnList.append(QmlPropertyChanges(childNode));
119 bool QmlModelState::hasPropertyChanges(const ModelNode &node) const
121 //### exception if not valid
126 foreach(const QmlPropertyChanges &changeSet, propertyChanges()) {
127 if (changeSet.target().isValid() && changeSet.target() == node)
133 bool QmlModelState::hasStateOperation(const ModelNode &node) const
135 //### exception if not valid
140 foreach(const QmlModelStateOperation &stateOperation, stateOperations()) {
141 if (stateOperation.target() == node)
147 QList<QmlModelStateOperation> QmlModelState::stateOperations() const
149 //### exception if not valid
150 QList<QmlModelStateOperation> returnList;
155 if (!modelNode().hasProperty("changes"))
158 Q_ASSERT(modelNode().property("changes").isNodeListProperty());
160 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
161 //### exception if not valid QmlModelStateOperation
162 if (QmlModelStateOperation(childNode).isValid())
163 returnList.append(QmlModelStateOperation(childNode));
169 /*! \brief Add a ChangeSet for the specified ModelNode to this state
170 The new ChangeSet if only added if no ChangeSet for the ModelNode
174 void QmlModelState::addChangeSetIfNotExists(const ModelNode &node)
176 //### exception if not valid
179 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
181 if (hasPropertyChanges(node)) {
182 return; //changeSet already there
185 ModelNode newChangeSet = modelNode().view()->createModelNode("QtQuick.PropertyChanges", 1, 0);
186 modelNode().nodeListProperty("changes").reparentHere(newChangeSet);
188 QmlPropertyChanges(newChangeSet).setTarget(node);
189 Q_ASSERT(QmlPropertyChanges(newChangeSet).isValid());
192 void QmlModelState::removePropertyChanges(const ModelNode &node)
194 //### exception if not valid
197 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
202 QmlPropertyChanges theChangeSet(propertyChanges(node));
203 if (theChangeSet.isValid())
204 theChangeSet.modelNode().destroy();
209 /*! \brief Returns if this state affects the specified ModelNode
211 \return true if this state affects the specifigied ModelNode
213 bool QmlModelState::affectsModelNode(const ModelNode &node) const
218 return !stateOperations(node).isEmpty();
221 QList<QmlObjectNode> QmlModelState::allAffectedNodes() const
223 QList<QmlObjectNode> returnList;
225 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
226 //### exception if not valid QmlModelStateOperation
227 if (QmlModelStateOperation(childNode).isValid() &&
228 !returnList.contains(QmlModelStateOperation(childNode).target()))
229 returnList.append(QmlModelStateOperation(childNode).target());
234 QString QmlModelState::name() const
239 return modelNode().variantProperty("name").value().toString();
242 void QmlModelState::setName(const QString &name)
244 if ((!isBaseState()) && (modelNode().isValid()))
245 modelNode().variantProperty("name").setValue(name);
248 bool QmlModelState::isValid() const
250 return QmlModelNodeFacade::isValid() &&
251 modelNode().metaInfo().isValid() &&
252 (modelNode().metaInfo().isSubclassOf("QtQuick.State", 1, 0) || isBaseState());
256 Removes state node & all subnodes.
258 void QmlModelState::destroy()
261 modelNode().destroy();
264 /*! \brief Returns if this state is the base state
266 \return true if this state is the base state
269 bool QmlModelState::isBaseState() const
271 return m_isBaseState && modelNode().isRootNode();
274 QmlModelState QmlModelState::duplicate(const QString &name) const
277 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
279 QmlItemNode parentNode(modelNode().parentProperty().parentModelNode());
280 if (!parentNode.isValid())
281 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
283 // QmlModelState newState(stateGroup().addState(name));
284 PropertyListType propertyList;
285 propertyList.append(qMakePair(QString("name"), QVariant(name)));
286 QmlModelState newState ( qmlModelView()->createModelNode("QtQuick.State", 1, 0, propertyList) );
288 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
289 ModelNode newModelNode(qmlModelView()->createModelNode(childNode.type(), childNode.majorVersion(), childNode.minorVersion()));
290 foreach (const BindingProperty &bindingProperty, childNode.bindingProperties())
291 newModelNode.bindingProperty(bindingProperty.name()).setExpression(bindingProperty.expression());
292 foreach (const VariantProperty &variantProperty, childNode.variantProperties())
293 newModelNode.variantProperty(variantProperty.name()) = variantProperty.value();
294 newState.modelNode().nodeListProperty("changes").reparentHere(newModelNode);
297 modelNode().parentProperty().reparentHere(newState);
302 QmlModelStateGroup QmlModelState::stateGroup() const
304 QmlItemNode parentNode(modelNode().parentProperty().parentModelNode());
305 return parentNode.states();
308 QmlModelState QmlModelState::createBaseState(const QmlModelView *view)
310 QmlModelState fxState(view->rootModelNode());
311 fxState.m_isBaseState = true;