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 **************************************************************************/
35 #include "qmlmodelview.h"
36 #include <nodelistproperty.h>
37 #include <variantproperty.h>
39 #include <invalidmodelnodeexception.h>
40 #include "bindingproperty.h"
43 namespace QmlDesigner {
45 QmlModelState::QmlModelState()
46 : QmlModelNodeFacade(),
51 QmlModelState::QmlModelState(const ModelNode &modelNode)
52 : QmlModelNodeFacade(modelNode),
57 QmlPropertyChanges QmlModelState::propertyChanges(const ModelNode &node)
59 //### exception if not valid
62 return QmlPropertyChanges();
64 addChangeSetIfNotExists(node);
65 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
66 //### exception if not valid QmlModelStateOperation
67 if (QmlPropertyChanges(childNode).target().isValid() && QmlPropertyChanges(childNode).target() == node && QmlPropertyChanges(childNode).isValid())
68 return QmlPropertyChanges(childNode); //### exception if not valid(childNode);
70 return QmlPropertyChanges(); //not found
73 QList<QmlModelStateOperation> QmlModelState::stateOperations(const ModelNode &node) const
75 QList<QmlModelStateOperation> returnList;
76 //### exception if not valid
81 if (!modelNode().hasProperty("changes"))
84 Q_ASSERT(modelNode().property("changes").isNodeListProperty());
86 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
87 QmlModelStateOperation stateOperation(childNode);
88 if (stateOperation.isValid()) {
89 ModelNode targetNode = stateOperation.target();
90 if (targetNode.isValid()
91 && targetNode == node)
92 returnList.append(stateOperation); //### exception if not valid(childNode);
95 return returnList; //not found
98 QList<QmlPropertyChanges> QmlModelState::propertyChanges() const
100 //### exception if not valid
101 QList<QmlPropertyChanges> returnList;
106 if (!modelNode().hasProperty("changes"))
109 Q_ASSERT(modelNode().property("changes").isNodeListProperty());
111 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
112 //### exception if not valid QmlModelStateOperation
113 if (QmlPropertyChanges(childNode).isValid())
114 returnList.append(QmlPropertyChanges(childNode));
120 bool QmlModelState::hasPropertyChanges(const ModelNode &node) const
122 //### exception if not valid
127 foreach(const QmlPropertyChanges &changeSet, propertyChanges()) {
128 if (changeSet.target().isValid() && changeSet.target() == node)
134 bool QmlModelState::hasStateOperation(const ModelNode &node) const
136 //### exception if not valid
141 foreach(const QmlModelStateOperation &stateOperation, stateOperations()) {
142 if (stateOperation.target() == node)
148 QList<QmlModelStateOperation> QmlModelState::stateOperations() const
150 //### exception if not valid
151 QList<QmlModelStateOperation> returnList;
156 if (!modelNode().hasProperty("changes"))
159 Q_ASSERT(modelNode().property("changes").isNodeListProperty());
161 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
162 //### exception if not valid QmlModelStateOperation
163 if (QmlModelStateOperation(childNode).isValid())
164 returnList.append(QmlModelStateOperation(childNode));
170 /*! \brief Add a ChangeSet for the specified ModelNode to this state
171 The new ChangeSet if only added if no ChangeSet for the ModelNode
175 void QmlModelState::addChangeSetIfNotExists(const ModelNode &node)
177 //### exception if not valid
180 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
182 if (hasPropertyChanges(node)) {
183 return; //changeSet already there
186 ModelNode newChangeSet = modelNode().view()->createModelNode("Qt/PropertyChanges", 4, 7);
187 modelNode().nodeListProperty("changes").reparentHere(newChangeSet);
189 QmlPropertyChanges(newChangeSet).setTarget(node);
190 Q_ASSERT(QmlPropertyChanges(newChangeSet).isValid());
193 void QmlModelState::removePropertyChanges(const ModelNode &node)
195 //### exception if not valid
198 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
203 QmlPropertyChanges theChangeSet(propertyChanges(node));
204 if (theChangeSet.isValid())
205 theChangeSet.modelNode().destroy();
210 /*! \brief Returns if this state affects the specified ModelNode
212 \return true if this state affects the specifigied ModelNode
214 bool QmlModelState::affectsModelNode(const ModelNode &node) const
219 return !stateOperations(node).isEmpty();
222 QList<QmlObjectNode> QmlModelState::allAffectedNodes() const
224 QList<QmlObjectNode> returnList;
226 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
227 //### exception if not valid QmlModelStateOperation
228 if (QmlModelStateOperation(childNode).isValid() &&
229 !returnList.contains(QmlModelStateOperation(childNode).target()))
230 returnList.append(QmlModelStateOperation(childNode).target());
235 QString QmlModelState::name() const
240 return modelNode().variantProperty("name").value().toString();
243 void QmlModelState::setName(const QString &name)
245 if ((!isBaseState()) && (modelNode().isValid()))
246 modelNode().variantProperty("name").setValue(name);
249 bool QmlModelState::isValid() const
251 return QmlModelNodeFacade::isValid() &&
252 modelNode().metaInfo().isValid() &&
253 (modelNode().metaInfo().isSubclassOf("Qt/State", 4, 7) || isBaseState());
257 Removes state node & all subnodes.
259 void QmlModelState::destroy()
262 modelNode().destroy();
265 /*! \brief Returns if this state is the base state
267 \return true if this state is the base state
270 bool QmlModelState::isBaseState() const
272 return m_isBaseState && modelNode().isRootNode();
275 QmlModelState QmlModelState::duplicate(const QString &name) const
278 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
280 QmlItemNode parentNode(modelNode().parentProperty().parentModelNode());
281 if (!parentNode.isValid())
282 throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
284 // QmlModelState newState(stateGroup().addState(name));
285 PropertyListType propertyList;
286 propertyList.append(qMakePair(QString("name"), QVariant(name)));
287 QmlModelState newState ( qmlModelView()->createModelNode("Qt/State", 4, 7, propertyList) );
289 foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) {
290 ModelNode newModelNode(qmlModelView()->createModelNode(childNode.type(), childNode.majorVersion(), childNode.minorVersion()));
291 foreach (const BindingProperty &bindingProperty, childNode.bindingProperties())
292 newModelNode.bindingProperty(bindingProperty.name()).setExpression(bindingProperty.expression());
293 foreach (const VariantProperty &variantProperty, childNode.variantProperties())
294 newModelNode.variantProperty(variantProperty.name()) = variantProperty.value();
295 newState.modelNode().nodeListProperty("changes").reparentHere(newModelNode);
298 modelNode().parentProperty().reparentHere(newState);
303 QmlModelStateGroup QmlModelState::stateGroup() const
305 QmlItemNode parentNode(modelNode().parentProperty().parentModelNode());
306 return parentNode.states();
309 QmlModelState QmlModelState::createBaseState(const QmlModelView *view)
311 QmlModelState fxState(view->rootModelNode());
312 fxState.m_isBaseState = true;