OSDN Git Service

a3b2043e3644323b6467913e13f2c8ded6419b74
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qmldesigner / designercore / model / qmlobjectnode.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 "qmlobjectnode.h"
35 #include "qmlitemnode.h"
36 #include "qmlitemnode.h"
37 #include "qmlstate.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"
47
48 namespace QmlDesigner {
49
50 void QmlObjectNode::setVariantProperty(const QString &name, const QVariant &value)
51 {
52     if (!isValid())
53         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
54
55     if (isInBaseState()) {
56         modelNode().variantProperty(name).setValue(value); //basestate
57     } else {
58         modelNode().validId();
59
60         QmlPropertyChanges changeSet(currentState().propertyChanges(modelNode()));
61         Q_ASSERT(changeSet.isValid());
62         changeSet.modelNode().variantProperty(name) = value;
63     }
64 }
65
66 void QmlObjectNode::setBindingProperty(const QString &name, const QString &expression)
67 {
68     if (!isValid())
69         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
70
71     if (isInBaseState()) {
72         modelNode().bindingProperty(name) = expression; //basestate
73     } else {
74         modelNode().validId();
75
76         QmlPropertyChanges changeSet(currentState().propertyChanges(modelNode()));
77         Q_ASSERT(changeSet.isValid());
78         changeSet.modelNode().bindingProperty(name) = expression;
79     }
80 }
81
82 QmlModelState QmlObjectNode::currentState() const
83 {
84     if (isValid())
85         return qmlModelView()->currentState();
86     else
87         return QmlModelState();
88 }
89
90 bool QmlObjectNode::isRootModelNode() const
91 {
92     return modelNode().isRootNode();
93 }
94
95
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
100
101 */
102 QVariant  QmlObjectNode::instanceValue(const QString &name) const
103 {    
104     return nodeInstance().property(name);
105 }
106
107
108 bool QmlObjectNode::hasProperty(const QString &name) const
109 {
110     if (!isValid())
111         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
112
113     if (currentState().hasPropertyChanges(modelNode())) {
114         QmlPropertyChanges propertyChanges = currentState().propertyChanges(modelNode());
115         if (propertyChanges.modelNode().hasProperty(name))
116             return true;
117     }
118
119     return modelNode().hasProperty(name);
120 }
121
122 bool QmlObjectNode::hasBindingProperty(const QString &name) const
123 {
124     if (!isValid())
125         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
126
127     if (currentState().hasPropertyChanges(modelNode())) {
128         QmlPropertyChanges propertyChanges = currentState().propertyChanges(modelNode());
129         if (propertyChanges.modelNode().hasBindingProperty(name))
130             return true;
131     }
132
133     return modelNode().hasBindingProperty(name);
134 }
135
136 NodeAbstractProperty QmlObjectNode::nodeAbstractProperty(const QString &name) const
137 {
138    return modelNode().nodeAbstractProperty(name);
139 }
140
141 NodeProperty QmlObjectNode::nodeProperty(const QString &name) const
142 {
143     return modelNode().nodeProperty(name);
144 }
145
146 NodeListProperty QmlObjectNode::nodeListProperty(const QString &name) const
147 {
148     return modelNode().nodeListProperty(name);
149 }
150
151 bool QmlObjectNode::propertyAffectedByCurrentState(const QString &name) const
152 {
153     if (!isValid())
154         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
155
156     if (currentState().isBaseState())
157         return modelNode().hasProperty(name);
158
159     if (!currentState().hasPropertyChanges(modelNode()))
160         return false;
161
162     return currentState().propertyChanges(modelNode()).modelNode().hasProperty(name);
163 }
164
165 QVariant QmlObjectNode::modelValue(const QString &name) const
166 {
167     if (!isValid())
168         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
169
170     if (currentState().isBaseState())
171         return modelNode().variantProperty(name).value();
172
173     if (!currentState().hasPropertyChanges(modelNode()))
174         return modelNode().variantProperty(name).value();
175
176     QmlPropertyChanges propertyChanges(currentState().propertyChanges(modelNode()));
177
178     if (!propertyChanges.modelNode().hasProperty(name))
179         return modelNode().variantProperty(name).value();
180
181     return propertyChanges.modelNode().variantProperty(name).value();
182 }
183
184 QString QmlObjectNode::expression(const QString &name) const
185 {
186     if (!isValid())
187         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
188
189     if (currentState().isBaseState())
190         return modelNode().bindingProperty(name).expression();
191
192     if (!currentState().hasPropertyChanges(modelNode()))
193         return modelNode().bindingProperty(name).expression();
194
195     QmlPropertyChanges propertyChanges(currentState().propertyChanges(modelNode()));
196
197     if (!propertyChanges.modelNode().hasProperty(name))
198         return modelNode().bindingProperty(name).expression();
199
200     return propertyChanges.modelNode().bindingProperty(name).expression();
201 }
202
203 /*! \brief returns if ObjectNode is the BaseState
204
205 \return true if the ObjectNode is in the BaseState
206
207 */
208 bool QmlObjectNode::isInBaseState() const
209 {
210     return currentState().isBaseState();
211 }
212
213 bool QmlObjectNode::canReparent() const
214 {
215     return isInBaseState();
216 }
217
218 QmlPropertyChanges QmlObjectNode::propertyChangeForCurrentState() const
219 {
220     if (!isValid())
221         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
222
223      if (currentState().isBaseState())
224          return QmlPropertyChanges();
225
226      if (!currentState().hasPropertyChanges(modelNode()))
227          return QmlPropertyChanges();
228
229      return currentState().propertyChanges(modelNode());
230 }
231
232 static void removeStateOperationsForChildren(const QmlObjectNode &node)
233 {
234     if (node.isValid()) {
235         foreach (QmlModelStateOperation stateOperation, node.allAffectingStatesOperations()) {
236             stateOperation.modelNode().destroy(); //remove of belonging StatesOperations
237         }
238
239         foreach (const QmlObjectNode &childNode, node.modelNode().allDirectSubModelNodes()) {
240             removeStateOperationsForChildren(childNode);
241         }
242     }
243 }
244
245
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.
249
250 */
251 void QmlObjectNode::destroy()
252 {
253     if (!isValid())
254         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
255
256     foreach (QmlModelStateOperation stateOperation, allAffectingStatesOperations()) {
257         stateOperation.modelNode().destroy(); //remove of belonging StatesOperations
258     }
259     removeStateOperationsForChildren(modelNode());
260     modelNode().destroy();
261 }
262
263 /*! \brief Returns a list of all states that are affecting this object.
264
265 \return list of states affecting this object
266 */
267
268 QList<QmlModelState> QmlObjectNode::allAffectingStates() const
269 {
270     if (!isValid())
271         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
272
273     QList<QmlModelState> returnList;
274
275     foreach (const QmlModelState &state, allDefinedStates()) {
276         if (state.affectsModelNode(modelNode()))
277             returnList.append(state);
278     }
279     return returnList;
280 }
281
282 /*! \brief Returns a list of all state operations that are affecting this object.
283
284 \return list of state operations affecting this object
285 */
286
287 QList<QmlModelStateOperation> QmlObjectNode::allAffectingStatesOperations() const
288 {
289     if (!isValid())
290         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
291
292     QList<QmlModelStateOperation> returnList;
293     foreach (const QmlModelState &state, allDefinedStates()) {
294         if (state.affectsModelNode(modelNode()))
295             returnList.append(state.stateOperations(modelNode()));
296     }
297
298     return returnList;
299 }
300
301 static QList<QmlItemNode> allFxItemsRecursive(const QmlItemNode &fxNode)
302 {
303     QList<QmlItemNode> returnList;
304
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);
311         }
312         foreach (const QmlItemNode &node, allChildNodes) {
313             returnList.append(allFxItemsRecursive(node));
314         }
315     }
316     return returnList;
317 }
318
319 QList<QmlModelState> QmlObjectNode::allDefinedStates() const
320 {
321     if (!isValid())
322         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
323
324     QList<QmlModelState> returnList;
325
326     QList<QmlItemNode> allFxItems;
327
328     QmlItemNode rootNode(qmlModelView()->rootModelNode());
329
330     if (rootNode.isValid())
331         allFxItems.append(allFxItemsRecursive(rootNode));
332
333     foreach (const QmlItemNode &item, allFxItems) {
334         returnList.append(item.states().allStates());
335     }
336
337     return returnList;
338 }
339
340
341 /*! \brief Removes a variant property of this object from the model
342
343 */
344
345 void  QmlObjectNode::removeVariantProperty(const QString &name)
346 {
347     if (!isValid())
348         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
349
350     if (isInBaseState()) {
351         modelNode().removeProperty(name); //basestate
352     } else {
353         QmlPropertyChanges changeSet(currentState().propertyChanges(modelNode()));
354         Q_ASSERT(changeSet.isValid());
355         changeSet.removeProperty(name);
356     }
357 }
358
359 QList<ModelNode> toModelNodeList(const QList<QmlObjectNode> &fxObjectNodeList)
360 {
361     QList<ModelNode> modelNodeList;
362
363     foreach(const QmlObjectNode &fxObjectNode, fxObjectNodeList)
364         modelNodeList.append(fxObjectNode.modelNode());
365
366     return modelNodeList;
367 }
368
369 QList<QmlObjectNode> toQmlObjectNodeList(const QList<ModelNode> &modelNodeList)
370 {
371     QList<QmlObjectNode> qmlObjectNodeList;
372
373     foreach(const ModelNode &modelNode, modelNodeList) {
374         QmlObjectNode objectNode(modelNode);
375         if (objectNode.isValid())
376             qmlObjectNodeList.append(objectNode);
377     }
378
379     return qmlObjectNodeList;
380 }
381
382 bool QmlObjectNode::isAncestorOf(const QmlObjectNode &objectNode) const
383 {
384     return modelNode().isAncestorOf(objectNode.modelNode());
385 }
386
387 QVariant QmlObjectNode::instanceValue(const ModelNode &modelNode, const QString &name)
388 {
389     QmlModelView *modelView = qobject_cast<QmlModelView*>(modelNode.view());
390     if (!modelView)
391         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
392     Q_ASSERT(modelView->hasInstanceForModelNode(modelNode));
393     return modelView->instanceForModelNode(modelNode).property(name);
394 }
395
396 QString QmlObjectNode::instanceType(const QString &name) const
397 {
398     return nodeInstance().instanceType(name);
399 }
400
401 bool QmlObjectNode::instanceHasBinding(const QString &name) const
402 {
403     QmlModelView *modelView = qobject_cast<QmlModelView*>(modelNode().view());
404     if (!modelView)
405         throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
406
407     return nodeInstance().hasBindingForProperty(name);
408 }
409
410 NodeInstance QmlObjectNode::nodeInstance() const
411 {
412     return qmlModelView()->nodeInstanceView()->instanceForNode(modelNode());
413 }
414
415 QmlObjectNode QmlObjectNode::nodeForInstance(const NodeInstance &instance) const
416 {
417     return QmlObjectNode(ModelNode(instance.modelNode(), qmlModelView()));
418 }
419
420 bool QmlObjectNode::hasNodeParent() const
421 {
422     return modelNode().hasParentProperty();
423 }
424
425 bool QmlObjectNode::hasInstanceParent() const
426 {
427     return nodeInstance().parentId() >= 0 && qmlModelView()->nodeInstanceView()->hasInstanceForId(nodeInstance().parentId());
428 }
429
430
431 void QmlObjectNode::setParentProperty(const NodeAbstractProperty &parentProeprty)
432 {
433     return modelNode().setParentProperty(parentProeprty);
434 }
435
436 QmlObjectNode QmlObjectNode::instanceParent() const
437 {
438     if (hasInstanceParent())
439         return nodeForInstance(qmlModelView()->nodeInstanceView()->instanceForId(nodeInstance().parentId()));
440
441     return QmlObjectNode();
442 }
443
444 void QmlObjectNode::setId(const QString &id)
445 {
446     modelNode().setId(id);
447 }
448
449 QString QmlObjectNode::id() const
450 {
451     return modelNode().id();
452 }
453
454 QString QmlObjectNode::validId()
455 {
456     return modelNode().validId();
457 }
458
459 bool QmlObjectNode::hasDefaultProperty() const
460 {
461     return modelNode().metaInfo().hasDefaultProperty();
462 }
463
464 QString QmlObjectNode::defaultProperty() const
465 {
466     return modelNode().metaInfo().defaultPropertyName();
467 }
468
469 void QmlObjectNode::setParent(QmlObjectNode newParent)
470 {
471     if (newParent.hasDefaultProperty()) {
472         newParent.modelNode().nodeAbstractProperty(newParent.defaultProperty()).reparentHere(modelNode());
473     }
474 }
475
476 QmlItemNode QmlObjectNode::toQmlItemNode() const
477 {
478     return QmlItemNode(modelNode());
479 }
480
481 uint qHash(const QmlObjectNode &node)
482 {
483     return qHash(node.modelNode());
484 }
485 } //QmlDesigner