OSDN Git Service

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