OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qmldesigner / designercore / model / qmlstate.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
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.
18 **
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.
22 **
23 ** Other Usage
24 **
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.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "qmlstate.h"
34 #include "qmlmodelview.h"
35 #include <nodelistproperty.h>
36 #include <variantproperty.h>
37 #include <metainfo.h>
38 #include <invalidmodelnodeexception.h>
39 #include "bindingproperty.h"
40
41
42 namespace QmlDesigner {
43
44 QmlModelState::QmlModelState()
45    : QmlModelNodeFacade(),
46      m_isBaseState(false)
47 {
48 }
49
50 QmlModelState::QmlModelState(const ModelNode &modelNode)
51         : QmlModelNodeFacade(modelNode),
52         m_isBaseState(false)
53 {
54 }
55
56 QmlPropertyChanges QmlModelState::propertyChanges(const ModelNode &node)
57 {
58     //### exception if not valid
59
60     if (isBaseState())
61         return  QmlPropertyChanges();
62
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);
68     }
69     return QmlPropertyChanges(); //not found
70 }
71
72 QList<QmlModelStateOperation> QmlModelState::stateOperations(const ModelNode &node) const
73 {
74     QList<QmlModelStateOperation> returnList;
75     //### exception if not valid
76
77     if (isBaseState())
78         return returnList;
79
80     if (!modelNode().hasProperty("changes"))
81         return returnList;
82
83     Q_ASSERT(modelNode().property("changes").isNodeListProperty());
84
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);
92         }
93     }
94     return returnList; //not found
95 }
96
97 QList<QmlPropertyChanges> QmlModelState::propertyChanges() const
98 {
99     //### exception if not valid
100     QList<QmlPropertyChanges> returnList;
101
102     if (isBaseState())
103         return returnList;
104
105     if (!modelNode().hasProperty("changes"))
106         return returnList;
107
108     Q_ASSERT(modelNode().property("changes").isNodeListProperty());
109
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));
114     }
115     return returnList;
116 }
117
118
119 bool QmlModelState::hasPropertyChanges(const ModelNode &node) const
120 {
121     //### exception if not valid
122
123     if (isBaseState())
124         return false;
125
126     foreach(const QmlPropertyChanges &changeSet, propertyChanges()) {
127         if (changeSet.target().isValid() && changeSet.target() == node)
128             return true;
129     }
130     return false;
131 }
132
133 bool QmlModelState::hasStateOperation(const ModelNode &node) const
134 {
135     //### exception if not valid
136
137     if (isBaseState())
138         return false;
139
140     foreach(const  QmlModelStateOperation &stateOperation, stateOperations()) {
141         if (stateOperation.target() == node)
142             return true;
143     }
144     return false;
145 }
146
147 QList<QmlModelStateOperation> QmlModelState::stateOperations() const
148 {
149     //### exception if not valid
150     QList<QmlModelStateOperation> returnList;
151
152     if (isBaseState())
153         return returnList;
154
155     if (!modelNode().hasProperty("changes"))
156         return returnList;
157
158     Q_ASSERT(modelNode().property("changes").isNodeListProperty());
159
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));
164     }
165     return returnList;
166 }
167
168
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
171   does not exist, yet.
172 */
173
174 void QmlModelState::addChangeSetIfNotExists(const ModelNode &node)
175 {
176     //### exception if not valid
177
178     if (!isValid())
179         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
180
181     if (hasPropertyChanges(node)) {
182         return; //changeSet already there
183     }
184
185     ModelNode newChangeSet = modelNode().view()->createModelNode("QtQuick.PropertyChanges", 1, 0);
186     modelNode().nodeListProperty("changes").reparentHere(newChangeSet);
187
188     QmlPropertyChanges(newChangeSet).setTarget(node);
189     Q_ASSERT(QmlPropertyChanges(newChangeSet).isValid());
190 }
191
192 void QmlModelState::removePropertyChanges(const ModelNode &node)
193 {
194     //### exception if not valid
195
196     if (!isValid())
197         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
198
199     if (isBaseState())
200         return;
201
202      QmlPropertyChanges theChangeSet(propertyChanges(node));
203      if (theChangeSet.isValid())
204          theChangeSet.modelNode().destroy();
205 }
206
207
208
209 /*! \brief Returns if this state affects the specified ModelNode
210
211 \return true if this state affects the specifigied ModelNode
212 */
213 bool QmlModelState::affectsModelNode(const ModelNode &node) const
214 {
215     if (isBaseState())
216         return false;
217
218     return !stateOperations(node).isEmpty();
219 }
220
221 QList<QmlObjectNode> QmlModelState::allAffectedNodes() const
222 {
223     QList<QmlObjectNode> returnList;
224
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());
230     }
231     return returnList;
232 }
233
234 QString QmlModelState::name() const
235 {
236     if (isBaseState())
237         return QString();
238
239     return modelNode().variantProperty("name").value().toString();
240 }
241
242 void QmlModelState::setName(const QString &name)
243 {
244     if ((!isBaseState()) && (modelNode().isValid()))
245         modelNode().variantProperty("name").setValue(name);
246 }
247
248 bool QmlModelState::isValid() const
249 {
250     return QmlModelNodeFacade::isValid() &&
251             modelNode().metaInfo().isValid() &&
252             (modelNode().metaInfo().isSubclassOf("QtQuick.State", 1, 0) || isBaseState());
253 }
254
255 /**
256   Removes state node & all subnodes.
257   */
258 void QmlModelState::destroy()
259 {
260     Q_ASSERT(isValid());
261     modelNode().destroy();
262 }
263
264 /*! \brief Returns if this state is the base state
265
266 \return true if this state is the base state
267 */
268
269 bool QmlModelState::isBaseState() const
270 {
271     return m_isBaseState && modelNode().isRootNode();
272 }
273
274 QmlModelState QmlModelState::duplicate(const QString &name) const
275 {
276     if (!isValid())
277         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
278
279     QmlItemNode parentNode(modelNode().parentProperty().parentModelNode());
280     if (!parentNode.isValid())
281         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
282
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) );
287
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);
295     }
296
297     modelNode().parentProperty().reparentHere(newState);
298
299     return newState;
300 }
301
302 QmlModelStateGroup QmlModelState::stateGroup() const
303 {
304     QmlItemNode parentNode(modelNode().parentProperty().parentModelNode());
305     return parentNode.states();
306 }
307
308 QmlModelState QmlModelState::createBaseState(const QmlModelView *view)
309 {
310     QmlModelState fxState(view->rootModelNode());
311     fxState.m_isBaseState = true;
312     return fxState;
313 }
314
315 } // QmlDesigner