OSDN Git Service

2ffd8ce21ad5509c0dd0bcb68a5bc07e31c7ad92
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qmldesigner / designercore / instances / nodeinstanceview.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 "nodeinstanceview.h"
35
36 #include <QDeclarativeEngine>
37 #include <QDeclarativeContext>
38 #include <private/qdeclarativeengine_p.h>
39
40 #include <QtDebug>
41 #include <QUrl>
42 #include <QGraphicsView>
43 #include <QGraphicsScene>
44 #include <QGraphicsObject>
45 #include <QFileSystemWatcher>
46
47 #include <model.h>
48 #include <modelnode.h>
49 #include <metainfo.h>
50
51 #include <typeinfo>
52 #include <iwidgetplugin.h>
53
54 #include "abstractproperty.h"
55 #include "variantproperty.h"
56 #include "bindingproperty.h"
57 #include "nodeabstractproperty.h"
58 #include "nodelistproperty.h"
59
60 #include <nodeinstanceserverinterface.h>
61
62 #include "createscenecommand.h"
63 #include "createinstancescommand.h"
64 #include "clearscenecommand.h"
65 #include "changefileurlcommand.h"
66 #include "reparentinstancescommand.h"
67 #include "changevaluescommand.h"
68 #include "changebindingscommand.h"
69 #include "changeidscommand.h"
70 #include "removeinstancescommand.h"
71 #include "removepropertiescommand.h"
72 #include "valueschangedcommand.h"
73 #include "pixmapchangedcommand.h"
74 #include "informationchangedcommand.h"
75 #include "changestatecommand.h"
76 #include "addimportcommand.h"
77 #include "childrenchangedcommand.h"
78 #include "imagecontainer.h"
79 #include "statepreviewimagechangedcommand.h"
80 #include "completecomponentcommand.h"
81 #include "componentcompletedcommand.h"
82
83 #include "nodeinstanceserverproxy.h"
84
85 enum {
86     debug = false
87 };
88
89 /*!
90 \defgroup CoreInstance
91 */
92 /*!
93 \class QmlDesigner::NodeInstanceView
94 \ingroup CoreInstance
95 \brief Central class to create and manage instances of a ModelNode.
96
97 This view is used to instance the ModelNodes. Many AbstractViews hold a
98 NodeInstanceView to get values from tghe NodeInstances back.
99 For this purpose this view can be rendered offscreen.
100
101 \see NodeInstance ModelNode
102 */
103
104 namespace QmlDesigner {
105
106 /*! \brief Constructor
107
108   The class will be rendered offscreen if not set otherwise.
109
110 \param Parent of this object. If this parent is d this instance is
111 d too.
112
113 \see ~NodeInstanceView setRenderOffScreen
114 */
115 NodeInstanceView::NodeInstanceView(QObject *parent, NodeInstanceServerInterface::RunModus runModus)
116         : AbstractView(parent),
117           m_baseStatePreviewImage(QSize(100, 100), QImage::Format_ARGB32),
118           m_runModus(runModus)
119 {
120     m_baseStatePreviewImage.fill(0xFFFFFF);
121 }
122
123
124 /*! \brief Destructor
125
126 */
127 NodeInstanceView::~NodeInstanceView()
128 {
129     removeAllInstanceNodeRelationships();
130     delete nodeInstanceServer();
131 }
132
133 /*!   \name Overloaded Notifiers
134  *  This methodes notify the view that something has happen in the model
135  */
136 //\{
137 /*! \brief Notifing the view that it was attached to a model.
138
139   For every ModelNode in the model a NodeInstance will be created.
140 \param model Model to which the view is attached
141 */
142
143 bool isSkippedNode(const ModelNode &node)
144 {
145     static QStringList skipList =  QStringList() << "Qt.ListModel" << "QtQuick.ListModel";
146
147     if (skipList.contains(node.type()))
148         return true;
149
150     return false;
151 }
152
153 void NodeInstanceView::modelAttached(Model *model)
154 {
155     AbstractView::modelAttached(model);
156     m_nodeInstanceServer = new NodeInstanceServerProxy(this, m_runModus);
157     m_lastCrashTime.start();
158     connect(m_nodeInstanceServer.data(), SIGNAL(processCrashed()), this, SLOT(handleChrash()));
159
160     if (!isSkippedNode(rootModelNode()))
161         nodeInstanceServer()->createScene(createCreateSceneCommand());
162 }
163
164 void NodeInstanceView::modelAboutToBeDetached(Model * model)
165 {
166     removeAllInstanceNodeRelationships();
167     nodeInstanceServer()->clearScene(createClearSceneCommand());
168     delete nodeInstanceServer();
169     m_statePreviewImage.clear();
170     m_baseStatePreviewImage = QImage();
171     removeAllInstanceNodeRelationships();
172     m_activeStateInstance = NodeInstance();
173     m_rootNodeInstance = NodeInstance();
174     AbstractView::modelAboutToBeDetached(model);
175 }
176
177 void NodeInstanceView::handleChrash()
178 {
179     int elaspsedTimeSinceLastCrash = m_lastCrashTime.restart();
180
181     if (elaspsedTimeSinceLastCrash > 2000) {
182         restartProcess();
183     } else {
184         emitCustomNotification("QmlPuppet crashed");
185     }
186 }
187
188
189
190 void NodeInstanceView::restartProcess()
191 {
192     if (model()) {
193         delete nodeInstanceServer();
194
195         m_nodeInstanceServer = new NodeInstanceServerProxy(this, m_runModus);
196         connect(m_nodeInstanceServer.data(), SIGNAL(processCrashed()), this, SLOT(handleChrash()));
197
198         if (!isSkippedNode(rootModelNode()))
199             nodeInstanceServer()->createScene(createCreateSceneCommand());
200     }
201 }
202
203 void NodeInstanceView::nodeCreated(const ModelNode &createdNode)
204 {
205     NodeInstance instance = loadNode(createdNode);
206
207     if (isSkippedNode(createdNode))
208         return;
209
210     nodeInstanceServer()->createInstances(createCreateInstancesCommand(QList<NodeInstance>() << instance));
211     nodeInstanceServer()->changePropertyValues(createChangeValueCommand(createdNode.variantProperties()));
212     nodeInstanceServer()->completeComponent(createComponentCompleteCommand(QList<NodeInstance>() << instance));
213 }
214
215 /*! \brief Notifing the view that a node was created.
216 \param removedNode
217 */
218 void NodeInstanceView::nodeAboutToBeRemoved(const ModelNode &removedNode)
219 {
220     nodeInstanceServer()->removeInstances(createRemoveInstancesCommand(removedNode));
221     removeInstanceAndSubInstances(removedNode);
222 }
223
224 void NodeInstanceView::nodeRemoved(const ModelNode &/*removedNode*/, const NodeAbstractProperty &/*parentProperty*/, PropertyChangeFlags /*propertyChange*/)
225 {
226 }
227
228 void NodeInstanceView::resetHorizontalAnchors(const ModelNode &modelNode)
229 {
230     QList<BindingProperty> bindingList;
231     QList<VariantProperty> valueList;
232
233     if (modelNode.hasBindingProperty("x")) {
234         bindingList.append(modelNode.bindingProperty("x"));
235     } else if (modelNode.hasVariantProperty("x")) {
236         valueList.append(modelNode.variantProperty("x"));
237     }
238
239     if (modelNode.hasBindingProperty("width")) {
240         bindingList.append(modelNode.bindingProperty("width"));
241     } else if (modelNode.hasVariantProperty("width")) {
242         valueList.append(modelNode.variantProperty("width"));
243     }
244
245     if (!valueList.isEmpty())
246         nodeInstanceServer()->changePropertyValues(createChangeValueCommand(valueList));
247
248     if (!bindingList.isEmpty())
249         nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(bindingList));
250
251 }
252
253 void NodeInstanceView::resetVerticalAnchors(const ModelNode &modelNode)
254 {
255     QList<BindingProperty> bindingList;
256     QList<VariantProperty> valueList;
257
258     if (modelNode.hasBindingProperty("yx")) {
259         bindingList.append(modelNode.bindingProperty("yx"));
260     } else if (modelNode.hasVariantProperty("y")) {
261         valueList.append(modelNode.variantProperty("y"));
262     }
263
264     if (modelNode.hasBindingProperty("height")) {
265         bindingList.append(modelNode.bindingProperty("height"));
266     } else if (modelNode.hasVariantProperty("height")) {
267         valueList.append(modelNode.variantProperty("height"));
268     }
269
270     if (!valueList.isEmpty())
271         nodeInstanceServer()->changePropertyValues(createChangeValueCommand(valueList));
272
273     if (!bindingList.isEmpty())
274         nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(bindingList));
275 }
276
277 void NodeInstanceView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList)
278 {
279
280     QList<ModelNode> nodeList;
281     QList<AbstractProperty> nonNodePropertyList;
282
283     foreach (const AbstractProperty &property, propertyList) {
284         if (property.isNodeAbstractProperty()) {
285             nodeList.append(property.toNodeAbstractProperty().allSubNodes());
286         } else {
287             nonNodePropertyList.append(property);
288         }
289     }
290
291     nodeInstanceServer()->removeInstances(createRemoveInstancesCommand(nodeList));
292     nodeInstanceServer()->removeProperties(createRemovePropertiesCommand(nonNodePropertyList));
293
294     foreach (const AbstractProperty &property, propertyList) {
295         const QString &name = property.name();
296         if (name == "anchors.fill") {
297             resetHorizontalAnchors(property.parentModelNode());
298             resetVerticalAnchors(property.parentModelNode());
299         } else if (name == "anchors.centerIn") {
300             resetHorizontalAnchors(property.parentModelNode());
301             resetVerticalAnchors(property.parentModelNode());
302         } else if (name == "anchors.top") {
303             resetVerticalAnchors(property.parentModelNode());
304         } else if (name == "anchors.left") {
305             resetHorizontalAnchors(property.parentModelNode());
306         } else if (name == "anchors.right") {
307             resetHorizontalAnchors(property.parentModelNode());
308         } else if (name == "anchors.bottom") {
309             resetVerticalAnchors(property.parentModelNode());
310         } else if (name == "anchors.horizontalCenter") {
311             resetHorizontalAnchors(property.parentModelNode());
312         } else if (name == "anchors.verticalCenter") {
313             resetVerticalAnchors(property.parentModelNode());
314         } else if (name == "anchors.baseline") {
315             resetVerticalAnchors(property.parentModelNode());
316         }
317     }
318
319     foreach (const ModelNode &node, nodeList)
320         removeInstanceNodeRelationship(node);
321 }
322
323 void NodeInstanceView::propertiesRemoved(const QList<AbstractProperty>& /*propertyList*/)
324 {
325 }
326
327 void NodeInstanceView::removeInstanceAndSubInstances(const ModelNode &node)
328 {
329     foreach(const ModelNode &subNode, node.allSubModelNodes()) {
330         if (hasInstanceForNode(subNode))
331             removeInstanceNodeRelationship(subNode);
332     }
333
334     if (hasInstanceForNode(node))
335         removeInstanceNodeRelationship(node);
336 }
337
338 void NodeInstanceView::rootNodeTypeChanged(const QString &/*type*/, int /*majorVersion*/, int /*minorVersion*/)
339 {
340     restartProcess();
341 }
342
343 void NodeInstanceView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
344 {
345     nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(propertyList));
346 }
347
348 /*! \brief Notifing the view that a AbstractProperty value was changed to a ModelNode.
349
350   The property will be set for the NodeInstance.
351
352 \param state ModelNode to which the Property belongs
353 \param property AbstractProperty which was changed
354 \param newValue New Value of the property
355 \param oldValue Old Value of the property
356 \see AbstractProperty NodeInstance ModelNode
357 */
358
359 void NodeInstanceView::variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
360 {
361     nodeInstanceServer()->changePropertyValues(createChangeValueCommand(propertyList));
362 }
363 /*! \brief Notifing the view that a ModelNode has a new Parent.
364
365   Note that also the ModelNode::childNodes() list was changed. The
366   NodeInstance tree will be changed to reflect the ModelNode tree change.
367
368 \param node ModelNode which parent was changed.
369 \param oldParent Old parent of the node.
370 \param newParent New parent of the node.
371
372 \see NodeInstance ModelNode
373 */
374
375 void NodeInstanceView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
376 {
377     if (!isSkippedNode(node))
378         nodeInstanceServer()->reparentInstances(createReparentInstancesCommand(node, newPropertyParent, oldPropertyParent));
379 }
380
381 void NodeInstanceView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
382 {
383 }
384
385
386 void NodeInstanceView::fileUrlChanged(const QUrl &/*oldUrl*/, const QUrl &newUrl)
387 {
388     nodeInstanceServer()->changeFileUrl(createChangeFileUrlCommand(newUrl));
389 }
390
391 void NodeInstanceView::nodeIdChanged(const ModelNode& node, const QString& /*newId*/, const QString& /*oldId*/)
392 {
393     if (hasInstanceForNode(node)) {
394         NodeInstance instance = instanceForNode(node);
395         nodeInstanceServer()->changeIds(createChangeIdsCommand(QList<NodeInstance>() << instance));
396     }
397 }
398
399 void NodeInstanceView::nodeOrderChanged(const NodeListProperty & listProperty,
400                                         const ModelNode & /*movedNode*/, int /*oldIndex*/)
401 {
402     QVector<ReparentContainer> containerList;
403     QString propertyName = listProperty.name();
404     qint32 containerInstanceId = -1;
405     ModelNode containerNode = listProperty.parentModelNode();
406     if (hasInstanceForNode(containerNode))
407         containerInstanceId = instanceForNode(containerNode).instanceId();
408
409     foreach(const ModelNode &node, listProperty.toModelNodeList()) {
410         qint32 instanceId = -1;
411         if (hasInstanceForNode(node)) {
412             instanceId = instanceForNode(node).instanceId();
413             ReparentContainer container(instanceId, containerInstanceId, propertyName, containerInstanceId, propertyName);
414             containerList.append(container);
415         }
416     }
417
418     nodeInstanceServer()->reparentInstances(ReparentInstancesCommand(containerList));
419 }
420
421 /*! \brief Notifing the view that the selection has been changed.
422
423   Do nothing.
424
425 \param selectedNodeList List of ModelNode which has been selected
426 \param lastSelectedNodeList List of ModelNode which was selected
427
428 \see ModelNode NodeInstance
429 */
430 void NodeInstanceView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/,
431                                               const QList<ModelNode> &/*lastSelectedNodeList*/)
432 {
433 }
434
435 void NodeInstanceView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/)
436 {
437
438 }
439
440 void NodeInstanceView::instancePropertyChange(const QList<QPair<ModelNode, QString> > &/*propertyList*/)
441 {
442
443 }
444
445 void NodeInstanceView::instancesCompleted(const QVector<ModelNode> &/*completedNodeList*/)
446 {
447 }
448
449 void NodeInstanceView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/)
450 {
451     restartProcess();
452 }
453
454 void NodeInstanceView::instanceInformationsChange(const QVector<ModelNode> &/*nodeList*/)
455 {
456
457 }
458
459 void NodeInstanceView::instancesRenderImageChanged(const QVector<ModelNode> &/*nodeList*/)
460 {
461
462 }
463
464 void NodeInstanceView::instancesPreviewImageChanged(const QVector<ModelNode> &/*nodeList*/)
465 {
466
467 }
468
469 void NodeInstanceView::instancesChildrenChanged(const QVector<ModelNode> &/*nodeList*/)
470 {
471
472 }
473
474 void NodeInstanceView::auxiliaryDataChanged(const ModelNode &node, const QString &name, const QVariant &data)
475 {
476     if (node.isRootNode() && (name == "width" || name == "height")) {
477         if (hasInstanceForNode(node)) {
478             NodeInstance instance = instanceForNode(node);
479             QVariant value = data;
480             if (value.isValid()) {
481                 PropertyValueContainer container(instance.instanceId(), name, value, QString());
482                 ChangeValuesCommand changeValueCommand(QVector<PropertyValueContainer>() << container);
483                 nodeInstanceServer()->changePropertyValues(changeValueCommand);
484             } else {
485                 if (node.hasVariantProperty(name)) {
486                     PropertyValueContainer container(instance.instanceId(), name, node.variantProperty(name).value(), QString());
487                     ChangeValuesCommand changeValueCommand(QVector<PropertyValueContainer>() << container);
488                     nodeInstanceServer()->changePropertyValues(changeValueCommand);
489                 } else if (node.hasBindingProperty(name)) {
490                     PropertyBindingContainer container(instance.instanceId(), name, node.bindingProperty(name).expression(), QString());
491                     ChangeBindingsCommand changeValueCommand(QVector<PropertyBindingContainer>() << container);
492                     nodeInstanceServer()->changePropertyBindings(changeValueCommand);
493                 }
494             }
495         }
496     }
497 }
498
499 void NodeInstanceView::customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &, const QList<QVariant> &)
500 {
501     if (view && identifier == QLatin1String("reset QmlPuppet"))
502         restartProcess();
503 }
504
505 void NodeInstanceView::rewriterBeginTransaction()
506 {
507
508 }
509
510 void NodeInstanceView::rewriterEndTransaction()
511 {
512
513 }
514
515 void NodeInstanceView::actualStateChanged(const ModelNode &/*node*/)
516 {
517 }
518
519
520 //\}
521
522
523 void NodeInstanceView::removeAllInstanceNodeRelationships()
524 {
525     m_nodeInstanceHash.clear();
526 }
527
528 /*! \brief Returns a List of all NodeInstances
529
530 \see NodeInstance
531 */
532
533 QList<NodeInstance> NodeInstanceView::instances() const
534 {
535     return m_nodeInstanceHash.values();
536 }
537
538 /*! \brief Returns the NodeInstance for this ModelNode
539
540   Returns a invalid NodeInstance if no NodeInstance for this ModelNode exists.
541
542 \param node ModelNode must be valid.
543 \returns  NodeStance for ModelNode.
544 \see NodeInstance
545 */
546 NodeInstance NodeInstanceView::instanceForNode(const ModelNode &node) const
547 {
548     Q_ASSERT(node.isValid());
549     Q_ASSERT(m_nodeInstanceHash.contains(node));
550     Q_ASSERT(m_nodeInstanceHash.value(node).modelNode() == node);
551     return m_nodeInstanceHash.value(node);
552 }
553
554 bool NodeInstanceView::hasInstanceForNode(const ModelNode &node) const
555 {
556     return m_nodeInstanceHash.contains(node);
557 }
558
559 NodeInstance NodeInstanceView::instanceForId(qint32 id)
560 {
561     if (id < 0 || !hasModelNodeForInternalId(id))
562         return NodeInstance();
563
564     return m_nodeInstanceHash.value(modelNodeForInternalId(id));
565 }
566
567 bool NodeInstanceView::hasInstanceForId(qint32 id)
568 {
569     if (id < 0 || !hasModelNodeForInternalId(id))
570         return false;
571
572     return m_nodeInstanceHash.contains(modelNodeForInternalId(id));
573 }
574
575
576 /*! \brief Returns the root NodeInstance of this view.
577
578
579 \returns  Root NodeIntance for this view.
580 \see NodeInstance
581 */
582 NodeInstance NodeInstanceView::rootNodeInstance() const
583 {
584     return m_rootNodeInstance;
585 }
586
587 /*! \brief Returns the view NodeInstance of this view.
588
589   This can be the root NodeInstance if it is specified in the qml file.
590 \code
591     QGraphicsView {
592          QGraphicsScene {
593              Item {}
594          }
595     }
596 \endcode
597
598     If there is node view in the qml file:
599  \code
600
601     Item {}
602
603 \endcode
604     Than there will be a new NodeInstance for this QGraphicsView
605     generated which is not the root instance of this NodeInstanceView.
606
607     This is the way to get this QGraphicsView NodeInstance.
608
609 \returns  Root NodeIntance for this view.
610 \see NodeInstance
611 */
612
613
614
615 void NodeInstanceView::insertInstanceRelationships(const NodeInstance &instance)
616 {
617     Q_ASSERT(instance.instanceId() >=0);
618     if(m_nodeInstanceHash.contains(instance.modelNode()))
619         return;
620
621     m_nodeInstanceHash.insert(instance.modelNode(), instance);
622 }
623
624 void NodeInstanceView::removeInstanceNodeRelationship(const ModelNode &node)
625 {
626     Q_ASSERT(m_nodeInstanceHash.contains(node));
627     NodeInstance instance = instanceForNode(node);
628     m_nodeInstanceHash.remove(node);
629     instance.makeInvalid();
630 }
631
632 void NodeInstanceView::setStateInstance(const NodeInstance &stateInstance)
633 {
634     m_activeStateInstance = stateInstance;
635 }
636
637 void NodeInstanceView::clearStateInstance()
638 {
639     m_activeStateInstance = NodeInstance();
640 }
641
642 NodeInstance NodeInstanceView::activeStateInstance() const
643 {
644     return m_activeStateInstance;
645 }
646
647 NodeInstanceServerInterface *NodeInstanceView::nodeInstanceServer() const
648 {
649     return m_nodeInstanceServer.data();
650 }
651
652
653 NodeInstance NodeInstanceView::loadNode(const ModelNode &node)
654 {
655     NodeInstance instance(NodeInstance::create(node));
656
657     insertInstanceRelationships(instance);
658
659     if (node.isRootNode()) {
660         m_rootNodeInstance = instance;
661     }
662
663     return instance;
664 }
665
666 void NodeInstanceView::activateState(const NodeInstance &instance)
667 {
668     nodeInstanceServer()->changeState(ChangeStateCommand(instance.instanceId()));
669 //    activateBaseState();
670 //    NodeInstance stateInstance(instance);
671 //    stateInstance.activateState();
672 }
673
674 void NodeInstanceView::activateBaseState()
675 {
676     nodeInstanceServer()->changeState(ChangeStateCommand(-1));
677 //    if (activeStateInstance().isValid())
678 //        activeStateInstance().deactivateState();
679 }
680
681 void NodeInstanceView::removeRecursiveChildRelationship(const ModelNode &removedNode)
682 {
683 //    if (hasInstanceForNode(removedNode)) {
684 //        instanceForNode(removedNode).setId(QString());
685 //    }
686
687     foreach (const ModelNode &childNode, removedNode.allDirectSubModelNodes())
688         removeRecursiveChildRelationship(childNode);
689
690     removeInstanceNodeRelationship(removedNode);
691 }
692
693 QRectF NodeInstanceView::sceneRect() const
694 {
695     if (rootNodeInstance().isValid())
696        return rootNodeInstance().boundingRect();
697
698     return QRectF();
699 }
700
701 QList<ModelNode> filterNodesForSkipItems(const QList<ModelNode> &nodeList)
702 {
703     QList<ModelNode> filteredNodeList;
704     foreach(const ModelNode &node, nodeList) {
705         if (isSkippedNode(node))
706             continue;
707
708         filteredNodeList.append(node);
709     }
710
711     return filteredNodeList;
712 }
713
714 CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
715 {
716     QList<ModelNode> nodeList = allModelNodes();
717     QList<NodeInstance> instanceList;
718
719     foreach (const ModelNode &node, nodeList) {
720         NodeInstance instance = loadNode(node);
721         if (!isSkippedNode(node))
722             instanceList.append(instance);
723     }
724
725     nodeList = filterNodesForSkipItems(nodeList);
726
727     QList<VariantProperty> variantPropertyList;
728     QList<BindingProperty> bindingPropertyList;
729
730     foreach (const ModelNode &node, nodeList) {
731         variantPropertyList.append(node.variantProperties());
732         bindingPropertyList.append(node.bindingProperties());
733     }
734
735     QVector<InstanceContainer> instanceContainerList;
736     foreach(const NodeInstance &instance, instanceList) {
737         InstanceContainer container(instance.instanceId(), instance.modelNode().type(), instance.modelNode().majorVersion(), instance.modelNode().minorVersion(), instance.modelNode().metaInfo().componentFileName());
738         instanceContainerList.append(container);
739     }
740
741     QVector<ReparentContainer> reparentContainerList;
742     foreach(const NodeInstance &instance, instanceList) {
743         if (instance.modelNode().hasParentProperty()) {
744             NodeAbstractProperty parentProperty = instance.modelNode().parentProperty();
745             ReparentContainer container(instance.instanceId(), -1, QString(), instanceForNode(parentProperty.parentModelNode()).instanceId(), parentProperty.name());
746             reparentContainerList.append(container);
747         }
748     }
749
750     QVector<IdContainer> idContainerList;
751     foreach(const NodeInstance &instance, instanceList) {
752         QString id = instance.modelNode().id();
753         if (!id.isEmpty()) {
754             IdContainer container(instance.instanceId(), id);
755             idContainerList.append(container);
756         }
757     }
758
759     QVector<PropertyValueContainer> valueContainerList;
760     foreach(const VariantProperty &property, variantPropertyList) {
761         ModelNode node = property.parentModelNode();
762         if (node.isValid() && hasInstanceForNode(node)) {
763             QVariant value = property.value();
764             if (node.isRootNode()
765                     && (property.name() == "width" || property.name() == "height")
766                     && node.hasAuxiliaryData(property.name())
767                     && node.auxiliaryData(property.name()).isValid())
768                 value = node.auxiliaryData(property.name());
769
770             NodeInstance instance = instanceForNode(node);
771             PropertyValueContainer container(instance.instanceId(), property.name(), value, property.dynamicTypeName());
772             valueContainerList.append(container);
773         }
774     }
775
776     QVector<PropertyBindingContainer> bindingContainerList;
777     foreach(const BindingProperty &property, bindingPropertyList) {
778         ModelNode node = property.parentModelNode();
779         if (node.isValid() && hasInstanceForNode(node)) {
780             if (node.isRootNode()
781                     && (property.name() == "width" || property.name() == "height")
782                     && node.hasAuxiliaryData(property.name())
783                     && node.auxiliaryData(property.name()).isValid())
784                 continue;
785
786             NodeInstance instance = instanceForNode(node);
787             PropertyBindingContainer container(instance.instanceId(), property.name(), property.expression(), property.dynamicTypeName());
788             bindingContainerList.append(container);
789         }
790     }
791
792     QVector<AddImportContainer> importVector;
793     foreach(const Import &import, model()->imports())
794         importVector.append(AddImportContainer(import.url(), import.file(), import.version(), import.alias(), import.importPaths()));
795
796     return CreateSceneCommand(instanceContainerList,
797                               reparentContainerList,
798                               idContainerList,
799                               valueContainerList,
800                               bindingContainerList,
801                               importVector,
802                               model()->fileUrl());
803 }
804
805 ClearSceneCommand NodeInstanceView::createClearSceneCommand() const
806 {
807     return ClearSceneCommand();
808 }
809
810 CompleteComponentCommand NodeInstanceView::createComponentCompleteCommand(const QList<NodeInstance> &instanceList) const
811 {
812     QVector<qint32> containerList;
813     foreach(const NodeInstance &instance, instanceList) {
814         if (instance.instanceId() >= 0)
815             containerList.append(instance.instanceId());
816     }
817
818     return CompleteComponentCommand(containerList);
819 }
820
821 ComponentCompletedCommand NodeInstanceView::createComponentCompletedCommand(const QList<NodeInstance> &instanceList) const
822 {
823     QVector<qint32> containerList;
824     foreach(const NodeInstance &instance, instanceList) {
825         if (instance.instanceId() >= 0)
826             containerList.append(instance.instanceId());
827     }
828
829     return ComponentCompletedCommand(containerList);
830 }
831
832 CreateInstancesCommand NodeInstanceView::createCreateInstancesCommand(const QList<NodeInstance> &instanceList) const
833 {
834     QVector<InstanceContainer> containerList;
835     foreach(const NodeInstance &instance, instanceList) {
836         InstanceContainer container(instance.instanceId(), instance.modelNode().type(), instance.modelNode().majorVersion(), instance.modelNode().minorVersion(), instance.modelNode().metaInfo().componentFileName());
837         containerList.append(container);
838     }
839
840     return CreateInstancesCommand(containerList);
841 }
842
843 ReparentInstancesCommand NodeInstanceView::createReparentInstancesCommand(const QList<NodeInstance> &instanceList) const
844 {
845     QVector<ReparentContainer> containerList;
846     foreach(const NodeInstance &instance, instanceList) {
847         if (instance.modelNode().hasParentProperty()) {
848             NodeAbstractProperty parentProperty = instance.modelNode().parentProperty();
849             ReparentContainer container(instance.instanceId(), -1, QString(), instanceForNode(parentProperty.parentModelNode()).instanceId(), parentProperty.name());
850             containerList.append(container);
851         }
852     }
853
854     return ReparentInstancesCommand(containerList);
855 }
856
857 ReparentInstancesCommand NodeInstanceView::createReparentInstancesCommand(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent) const
858 {
859     QVector<ReparentContainer> containerList;
860
861     qint32 newParentInstanceId = -1;
862     qint32 oldParentInstanceId = -1;
863
864     if (newPropertyParent.isValid() && hasInstanceForNode(newPropertyParent.parentModelNode()))
865         newParentInstanceId = instanceForNode(newPropertyParent.parentModelNode()).instanceId();
866
867
868     if (oldPropertyParent.isValid() && hasInstanceForNode(oldPropertyParent.parentModelNode()))
869         oldParentInstanceId = instanceForNode(oldPropertyParent.parentModelNode()).instanceId();
870
871
872     ReparentContainer container(instanceForNode(node).instanceId(), oldParentInstanceId, oldPropertyParent.name(), newParentInstanceId, newPropertyParent.name());
873
874     containerList.append(container);
875
876     return ReparentInstancesCommand(containerList);
877 }
878
879 ChangeFileUrlCommand NodeInstanceView::createChangeFileUrlCommand(const QUrl &fileUrl) const
880 {
881     return ChangeFileUrlCommand(fileUrl);
882 }
883
884 ChangeValuesCommand NodeInstanceView::createChangeValueCommand(const QList<VariantProperty>& propertyList) const
885 {
886     QVector<PropertyValueContainer> containerList;
887
888     foreach(const VariantProperty &property, propertyList) {
889         ModelNode node = property.parentModelNode();
890         if (node.isValid() && hasInstanceForNode(node)) {
891             NodeInstance instance = instanceForNode(node);
892             PropertyValueContainer container(instance.instanceId(), property.name(), property.value(), property.dynamicTypeName());
893             containerList.append(container);
894         }
895
896     }
897
898     return ChangeValuesCommand(containerList);
899 }
900
901 ChangeBindingsCommand NodeInstanceView::createChangeBindingCommand(const QList<BindingProperty> &propertyList) const
902 {
903     QVector<PropertyBindingContainer> containerList;
904
905     foreach(const BindingProperty &property, propertyList) {
906         ModelNode node = property.parentModelNode();
907         if (node.isValid() && hasInstanceForNode(node)) {
908             NodeInstance instance = instanceForNode(node);
909             PropertyBindingContainer container(instance.instanceId(), property.name(), property.expression(), property.dynamicTypeName());
910             containerList.append(container);
911         }
912
913     }
914
915     return ChangeBindingsCommand(containerList);
916 }
917
918 ChangeIdsCommand NodeInstanceView::createChangeIdsCommand(const QList<NodeInstance> &instanceList) const
919 {
920     QVector<IdContainer> containerList;
921     foreach(const NodeInstance &instance, instanceList) {
922         QString id = instance.modelNode().id();
923         if (!id.isEmpty()) {
924             IdContainer container(instance.instanceId(), id);
925             containerList.append(container);
926         }
927     }
928
929     return ChangeIdsCommand(containerList);
930 }
931
932
933
934 RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const QList<ModelNode> &nodeList) const
935 {
936     QVector<qint32> idList;
937     foreach(const ModelNode &node, nodeList) {
938         if (node.isValid() && hasInstanceForNode(node)) {
939             NodeInstance instance = instanceForNode(node);
940
941             if (instance.instanceId() >= 0) {
942                 idList.append(instance.instanceId());
943             }
944         }
945     }
946
947     return RemoveInstancesCommand(idList);
948 }
949
950 RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const ModelNode &node) const
951 {
952     QVector<qint32> idList;
953
954     if (node.isValid() && hasInstanceForNode(node))
955         idList.append(instanceForNode(node).instanceId());
956
957     return RemoveInstancesCommand(idList);
958 }
959
960 RemovePropertiesCommand NodeInstanceView::createRemovePropertiesCommand(const QList<AbstractProperty> &propertyList) const
961 {
962     QVector<PropertyAbstractContainer> containerList;
963
964     foreach(const AbstractProperty &property, propertyList) {
965         ModelNode node = property.parentModelNode();
966         if (node.isValid() && hasInstanceForNode(node)) {
967             NodeInstance instance = instanceForNode(node);
968             PropertyAbstractContainer container(instance.instanceId(), property.name(), property.dynamicTypeName());
969             containerList.append(container);
970         }
971
972     }
973
974     return RemovePropertiesCommand(containerList);
975 }
976
977 AddImportCommand NodeInstanceView::createImportCommand(const Import &import)
978 {
979     return AddImportCommand(AddImportContainer(import.url(), import.file(), import.version(), import.alias(), import.importPaths()));
980 }
981
982 void NodeInstanceView::valuesChanged(const ValuesChangedCommand &command)
983 {
984     if (!model())
985         return;
986
987     QList<QPair<ModelNode, QString> > valuePropertyChangeList;
988
989     foreach(const PropertyValueContainer &container, command.valueChanges()) {
990         if (hasInstanceForId(container.instanceId())) {
991             NodeInstance instance = instanceForId(container.instanceId());
992             if (instance.isValid()) {
993                 instance.setProperty(container.name(), container.value());
994                 valuePropertyChangeList.append(qMakePair(instance.modelNode(), container.name()));
995             }
996         }
997     }
998
999     if (!valuePropertyChangeList.isEmpty())
1000         emitInstancePropertyChange(valuePropertyChangeList);
1001 }
1002
1003 void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
1004 {
1005     if (!model())
1006         return;
1007
1008     QSet<ModelNode> renderImageChangeSet;
1009
1010     foreach (const ImageContainer &container, command.images()) {
1011         if (hasInstanceForId(container.instanceId())) {
1012             NodeInstance instance = instanceForId(container.instanceId());
1013             if (instance.isValid()) {
1014                 instance.setRenderImage(container.image());
1015                 renderImageChangeSet.insert(instance.modelNode());
1016             }
1017         }
1018     }
1019
1020     if (!renderImageChangeSet.isEmpty())
1021         emitInstancesRenderImageChanged(renderImageChangeSet.toList().toVector());
1022 }
1023
1024 void NodeInstanceView::informationChanged(const InformationChangedCommand &command)
1025 {
1026     if (!model())
1027         return;
1028
1029     QVector<ModelNode> informationChangedVector;
1030
1031     foreach(const InformationContainer &container, command.informations()) {
1032         if (hasInstanceForId(container.instanceId())) {
1033             NodeInstance instance = instanceForId(container.instanceId());
1034             if (instance.isValid()) {
1035                 instance.setInformation(container.name(), container.information(), container.secondInformation(), container.thirdInformation());
1036                 if (!informationChangedVector.contains(instance.modelNode()))
1037                     informationChangedVector.append(instance.modelNode());
1038             }
1039         }
1040     }
1041
1042     if (!informationChangedVector.isEmpty())
1043         emitInstanceInformationsChange(informationChangedVector.toList().toVector());
1044 }
1045
1046 QImage NodeInstanceView::statePreviewImage(const ModelNode &stateNode) const
1047 {
1048     if (stateNode == rootModelNode())
1049         return m_baseStatePreviewImage;
1050
1051     return m_statePreviewImage.value(stateNode);
1052 }
1053
1054 void NodeInstanceView::statePreviewImagesChanged(const StatePreviewImageChangedCommand &command)
1055 {
1056     if (!model())
1057       return;
1058
1059   QVector<ModelNode> previewImageChangeVector;
1060
1061   foreach (const ImageContainer &container, command.previews()) {
1062       if (container.instanceId() == 0) {
1063           m_baseStatePreviewImage = container.image();
1064           previewImageChangeVector.append(rootModelNode());
1065       } else if (hasInstanceForId(container.instanceId())) {
1066           ModelNode node = modelNodeForInternalId(container.instanceId());
1067           m_statePreviewImage.insert(node, container.image());
1068           previewImageChangeVector.append(node);
1069       }
1070   }
1071
1072   if (!previewImageChangeVector.isEmpty())
1073        emitInstancesPreviewImageChanged(previewImageChangeVector);
1074 }
1075
1076 void NodeInstanceView::componentCompleted(const ComponentCompletedCommand &command)
1077 {
1078     if (!model())
1079         return;
1080
1081     QVector<ModelNode> nodeVector;
1082
1083     foreach(const qint32 &instanceId, command.instances()) {
1084         if (hasModelNodeForInternalId(instanceId)) {
1085             nodeVector.append(modelNodeForInternalId(instanceId));
1086         }
1087     }
1088
1089     if (!nodeVector.isEmpty())
1090         emitInstancesCompleted(nodeVector);
1091 }
1092
1093 void NodeInstanceView::childrenChanged(const ChildrenChangedCommand &command)
1094 {
1095      if (!model())
1096         return;
1097
1098     QVector<ModelNode> childNodeVector;
1099
1100     foreach(qint32 instanceId, command.childrenInstances()) {
1101         if (hasInstanceForId(instanceId)) {
1102             NodeInstance instance = instanceForId(instanceId);
1103             instance.setParentId(command.parentInstanceId());
1104             childNodeVector.append(instance.modelNode());
1105         }
1106     }
1107
1108     if (!childNodeVector.isEmpty())
1109         emitInstancesChildrenChanged(childNodeVector);
1110 }
1111
1112 }