nodeinstanceview.cpp 33.1 KB
Newer Older
1
2
3
4
/**************************************************************************
**
** This file is part of Qt Creator
**
con's avatar
con committed
5
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6
7
8
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
con's avatar
con committed
9
** No Commercial Usage
10
**
con's avatar
con committed
11
12
13
14
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
15
16
17
18
19
20
21
22
23
24
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
con's avatar
con committed
25
26
27
28
29
30
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
31
32
33
34
35
**
**************************************************************************/

#include "nodeinstanceview.h"

36
37
#include <QDeclarativeEngine>
#include <QDeclarativeContext>
38
#include <private/qdeclarativeengine_p.h>
39
40
41
42
43
44

#include <QtDebug>
#include <QUrl>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsObject>
45
#include <QFileSystemWatcher>
46
47
48
49
50
51
52
53
54
55
56
57
58
59

#include <model.h>
#include <modelnode.h>
#include <metainfo.h>

#include <typeinfo>
#include <iwidgetplugin.h>

#include "abstractproperty.h"
#include "variantproperty.h"
#include "bindingproperty.h"
#include "nodeabstractproperty.h"
#include "nodelistproperty.h"

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <nodeinstanceserverinterface.h>

#include "createscenecommand.h"
#include "createinstancescommand.h"
#include "clearscenecommand.h"
#include "changefileurlcommand.h"
#include "reparentinstancescommand.h"
#include "changevaluescommand.h"
#include "changebindingscommand.h"
#include "changeidscommand.h"
#include "removeinstancescommand.h"
#include "removepropertiescommand.h"
#include "valueschangedcommand.h"
#include "pixmapchangedcommand.h"
#include "informationchangedcommand.h"
#include "changestatecommand.h"
76
#include "addimportcommand.h"
77
#include "childrenchangedcommand.h"
78
79
#include "imagecontainer.h"
#include "statepreviewimagechangedcommand.h"
80
81
#include "completecomponentcommand.h"
#include "componentcompletedcommand.h"
82
83

#include "nodeinstanceserverproxy.h"
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
enum {
    debug = false
};

/*!
\defgroup CoreInstance
*/
/*!
\class QmlDesigner::NodeInstanceView
\ingroup CoreInstance
\brief Central class to create and manage instances of a ModelNode.

This view is used to instance the ModelNodes. Many AbstractViews hold a
NodeInstanceView to get values from tghe NodeInstances back.
For this purpose this view can be rendered offscreen.

\see NodeInstance ModelNode
*/

namespace QmlDesigner {

/*! \brief Constructor

Tobias Hunger's avatar
Tobias Hunger committed
108
  The class will be rendered offscreen if not set otherwise.
109

110
111
\param Parent of this object. If this parent is d this instance is
d too.
112
113
114
115

\see ~NodeInstanceView setRenderOffScreen
*/
NodeInstanceView::NodeInstanceView(QObject *parent)
116
117
        : AbstractView(parent),
          m_baseStatePreviewImage(QSize(100, 100), QImage::Format_ARGB32)
118
{
119
    m_baseStatePreviewImage.fill(0xFFFFFF);
120
121
122
123
124
125
126
127
128
}


/*! \brief Destructor

*/
NodeInstanceView::~NodeInstanceView()
{
    removeAllInstanceNodeRelationships();
129
    delete nodeInstanceServer();
130
131
132
133
134
135
136
137
138
139
140
141
142
143
}

/*!   \name Overloaded Notifiers
 *  This methodes notify the view that something has happen in the model
 */
//\{
/*! \brief Notifing the view that it was attached to a model.

  For every ModelNode in the model a NodeInstance will be created.
\param model Model to which the view is attached
*/
void NodeInstanceView::modelAttached(Model *model)
{
    AbstractView::modelAttached(model);
144
    m_nodeInstanceServer = new NodeInstanceServerProxy(this);
145
146
    m_lastCrashTime.start();
    connect(m_nodeInstanceServer.data(), SIGNAL(processCrashed()), this, SLOT(handleChrash()));
147

148
    nodeInstanceServer()->createScene(createCreateSceneCommand());
149
150
151
152
153
}

void NodeInstanceView::modelAboutToBeDetached(Model * model)
{
    removeAllInstanceNodeRelationships();
154
155
    nodeInstanceServer()->clearScene(createClearSceneCommand());
    delete nodeInstanceServer();
156
157
158
    AbstractView::modelAboutToBeDetached(model);
}

159
160
161
162
163
164
165
void NodeInstanceView::handleChrash()
{
    int elaspsedTimeSinceLastCrash = m_lastCrashTime.restart();

    if (elaspsedTimeSinceLastCrash > 10000)
        restartProcess();
}
166

167
168
void NodeInstanceView::restartProcess()
{
169
170
171
172
    if (model()) {
        delete nodeInstanceServer();

        m_nodeInstanceServer = new NodeInstanceServerProxy(this);
173
        connect(m_nodeInstanceServer.data(), SIGNAL(processCrashed()), this, SLOT(handleChrash()));
174
175

        nodeInstanceServer()->createScene(createCreateSceneCommand());
176
177
178
    }
}

179
180
181
182
183
184
/*! \brief Notifing the view that a node was created.
  A NodeInstance will be created for the new created ModelNode.
\param createdNode New created ModelNode.
*/
void NodeInstanceView::nodeCreated(const ModelNode &createdNode)
{
185
    NodeInstance instance = loadNode(createdNode);
186
187
    nodeInstanceServer()->createInstances(createCreateInstancesCommand(QList<NodeInstance>() << instance));
    nodeInstanceServer()->changePropertyValues(createChangeValueCommand(createdNode.variantProperties()));
188
    nodeInstanceServer()->completeComponent(createComponentCompleteCommand(QList<NodeInstance>() << instance));
189
190
191
192
193
194
195
}

/*! \brief Notifing the view that a node was created.
\param removedNode
*/
void NodeInstanceView::nodeAboutToBeRemoved(const ModelNode &removedNode)
{
196
    nodeInstanceServer()->removeInstances(createRemoveInstancesCommand(removedNode));
197
198
199
200
201
202
203
    removeInstanceAndSubInstances(removedNode);
}

void NodeInstanceView::nodeRemoved(const ModelNode &/*removedNode*/, const NodeAbstractProperty &/*parentProperty*/, PropertyChangeFlags /*propertyChange*/)
{
}

204
void NodeInstanceView::resetHorizontalAnchors(const ModelNode &modelNode)
205
{
206
207
    QList<BindingProperty> bindingList;
    QList<VariantProperty> valueList;
208

209
210
211
212
    if (modelNode.hasBindingProperty("x")) {
        bindingList.append(modelNode.bindingProperty("x"));
    } else if (modelNode.hasVariantProperty("x")) {
        valueList.append(modelNode.variantProperty("x"));
213
214
    }

215
216
217
218
    if (modelNode.hasBindingProperty("width")) {
        bindingList.append(modelNode.bindingProperty("width"));
    } else if (modelNode.hasVariantProperty("width")) {
        valueList.append(modelNode.variantProperty("width"));
219
220
    }

221
222
    if (!valueList.isEmpty())
        nodeInstanceServer()->changePropertyValues(createChangeValueCommand(valueList));
223

224
225
    if (!bindingList.isEmpty())
        nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(bindingList));
226

227
}
228

229
230
231
232
void NodeInstanceView::resetVerticalAnchors(const ModelNode &modelNode)
{
    QList<BindingProperty> bindingList;
    QList<VariantProperty> valueList;
233

234
235
236
237
238
    if (modelNode.hasBindingProperty("yx")) {
        bindingList.append(modelNode.bindingProperty("yx"));
    } else if (modelNode.hasVariantProperty("y")) {
        valueList.append(modelNode.variantProperty("y"));
    }
239

240
241
242
243
    if (modelNode.hasBindingProperty("height")) {
        bindingList.append(modelNode.bindingProperty("height"));
    } else if (modelNode.hasVariantProperty("height")) {
        valueList.append(modelNode.variantProperty("height"));
244
245
    }

246
247
    if (!valueList.isEmpty())
        nodeInstanceServer()->changePropertyValues(createChangeValueCommand(valueList));
248

249
250
    if (!bindingList.isEmpty())
        nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(bindingList));
251
252
}

253
void NodeInstanceView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList)
254
255
{

256
257
    QList<ModelNode> nodeList;
    QList<AbstractProperty> nonNodePropertyList;
258

259
260
261
262
263
    foreach (const AbstractProperty &property, propertyList) {
        if (property.isNodeAbstractProperty()) {
            nodeList.append(property.toNodeAbstractProperty().allSubNodes());
        } else {
            nonNodePropertyList.append(property);
264
265
266
        }
    }

267
268
    nodeInstanceServer()->removeInstances(createRemoveInstancesCommand(nodeList));
    nodeInstanceServer()->removeProperties(createRemovePropertiesCommand(nonNodePropertyList));
269

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
    foreach (const AbstractProperty &property, propertyList) {
        const QString &name = property.name();
        if (name == "anchors.fill") {
            resetHorizontalAnchors(property.parentModelNode());
            resetVerticalAnchors(property.parentModelNode());
        } else if (name == "anchors.centerIn") {
            resetHorizontalAnchors(property.parentModelNode());
            resetVerticalAnchors(property.parentModelNode());
        } else if (name == "anchors.top") {
            resetVerticalAnchors(property.parentModelNode());
        } else if (name == "anchors.left") {
            resetHorizontalAnchors(property.parentModelNode());
        } else if (name == "anchors.right") {
            resetHorizontalAnchors(property.parentModelNode());
        } else if (name == "anchors.bottom") {
            resetVerticalAnchors(property.parentModelNode());
        } else if (name == "anchors.horizontalCenter") {
            resetHorizontalAnchors(property.parentModelNode());
        } else if (name == "anchors.verticalCenter") {
            resetVerticalAnchors(property.parentModelNode());
        } else if (name == "anchors.baseline") {
            resetVerticalAnchors(property.parentModelNode());
292
293
294
        }
    }

295
296
297
298
299
300
    foreach (const ModelNode &node, nodeList)
        removeInstanceNodeRelationship(node);
}

void NodeInstanceView::propertiesRemoved(const QList<AbstractProperty>& /*propertyList*/)
{
301
302
}

303
304
305
306
307
308
void NodeInstanceView::removeInstanceAndSubInstances(const ModelNode &node)
{
    foreach(const ModelNode &subNode, node.allSubModelNodes()) {
        if (hasInstanceForNode(subNode))
            removeInstanceNodeRelationship(subNode);
    }
309
310
311

    if (hasInstanceForNode(node))
        removeInstanceNodeRelationship(node);
312
313
}

314
void NodeInstanceView::rootNodeTypeChanged(const QString &/*type*/, int /*majorVersion*/, int /*minorVersion*/)
315
{
316
    nodeInstanceServer()->clearScene(createClearSceneCommand());
317
    removeAllInstanceNodeRelationships();
318

319
    nodeInstanceServer()->createScene(createCreateSceneCommand());
320
321
322
323
}

void NodeInstanceView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
{
324
    nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(propertyList));
325
326
327
328
}

/*! \brief Notifing the view that a AbstractProperty value was changed to a ModelNode.

Tobias Hunger's avatar
Tobias Hunger committed
329
  The property will be set for the NodeInstance.
330

Tobias Hunger's avatar
Tobias Hunger committed
331
\param state ModelNode to which the Property belongs
332
333
334
335
336
337
338
339
\param property AbstractProperty which was changed
\param newValue New Value of the property
\param oldValue Old Value of the property
\see AbstractProperty NodeInstance ModelNode
*/

void NodeInstanceView::variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
{
340
    nodeInstanceServer()->changePropertyValues(createChangeValueCommand(propertyList));
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
}
/*! \brief Notifing the view that a ModelNode has a new Parent.

  Note that also the ModelNode::childNodes() list was changed. The
  NodeInstance tree will be changed to reflect the ModelNode tree change.

\param node ModelNode which parent was changed.
\param oldParent Old parent of the node.
\param newParent New parent of the node.

\see NodeInstance ModelNode
*/

void NodeInstanceView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
356
357
358
359
360
361
362
363
364
    nodeInstanceServer()->reparentInstances(createReparentInstancesCommand(node, newPropertyParent, oldPropertyParent));
//    NodeInstance nodeInstance(instanceForNode(node));
//    NodeInstance oldParentInstance;
//    if (hasInstanceForNode(oldPropertyParent.parentModelNode()))
//        oldParentInstance = instanceForNode(oldPropertyParent.parentModelNode());
//    NodeInstance newParentInstance;
//    if (hasInstanceForNode(newPropertyParent.parentModelNode()))
//        newParentInstance = instanceForNode(newPropertyParent.parentModelNode());
//    nodeInstance.reparent(oldParentInstance, oldPropertyParent.name(), newParentInstance, newPropertyParent.name());
365
366
}

367
368
369
370
371
void NodeInstanceView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
}


372
void NodeInstanceView::fileUrlChanged(const QUrl &/*oldUrl*/, const QUrl &newUrl)
373
374
{
    // TODO: We have to probably reload everything, so that images etc are updated!!!
375
376
377
378
    //engine()->setBaseUrl(model()->fileUrl());

    //TODO reload the whole scene
    nodeInstanceServer()->changeFileUrl(createChangeFileUrlCommand(newUrl));
379
380
}

381
void NodeInstanceView::nodeIdChanged(const ModelNode& node, const QString& /*newId*/, const QString& /*oldId*/)
382
383
384
{
    if (hasInstanceForNode(node)) {
        NodeInstance instance = instanceForNode(node);
385
        nodeInstanceServer()->changeIds(createChangeIdsCommand(QList<NodeInstance>() << instance));
386
387
388
    }
}

389
390
void NodeInstanceView::nodeOrderChanged(const NodeListProperty & listProperty,
                                        const ModelNode & /*movedNode*/, int /*oldIndex*/)
391
{
392
393
394
395
396
397
398
    QVector<ReparentContainer> containerList;
    QString propertyName = listProperty.name();
    qint32 containerInstanceId = -1;
    ModelNode containerNode = listProperty.parentModelNode();
    if (hasInstanceForNode(containerNode))
        containerInstanceId = instanceForNode(containerNode).instanceId();

399
    foreach(const ModelNode &node, listProperty.toModelNodeList()) {
400
401
402
403
404
405
        qint32 instanceId = -1;
        if (hasInstanceForNode(node)) {
            instanceId = instanceForNode(node).instanceId();
            ReparentContainer container(instanceId, containerInstanceId, propertyName, containerInstanceId, propertyName);
            containerList.append(container);
        }
406
    }
407
408

    nodeInstanceServer()->reparentInstances(ReparentInstancesCommand(containerList));
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
}

/*! \brief Notifing the view that the selection has been changed.

  Do nothing.

\param selectedNodeList List of ModelNode which has been selected
\param lastSelectedNodeList List of ModelNode which was selected

\see ModelNode NodeInstance
*/
void NodeInstanceView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/,
                                              const QList<ModelNode> &/*lastSelectedNodeList*/)
{
}

Marco Bubke's avatar
Marco Bubke committed
425
426
427
428
void NodeInstanceView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/)
{

}
429

430
431
432
433
434
void NodeInstanceView::instancePropertyChange(const QList<QPair<ModelNode, QString> > &/*propertyList*/)
{

}

435
436
437
438
void NodeInstanceView::instancesCompleted(const QVector<ModelNode> &/*completedNodeList*/)
{
}

439
void NodeInstanceView::importAdded(const Import & import)
440
{
441
    nodeInstanceServer()->addImport(createImportCommand(import));
442
}
443

444
445
void NodeInstanceView::importRemoved(const Import &/*import*/)
{
446
    restartProcess();
447
448
}

449
450
//\}

451

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
void NodeInstanceView::removeAllInstanceNodeRelationships()
{
    m_nodeInstanceHash.clear();
}

/*! \brief Returns a List of all NodeInstances

\see NodeInstance
*/

QList<NodeInstance> NodeInstanceView::instances() const
{
    return m_nodeInstanceHash.values();
}

/*! \brief Returns the NodeInstance for this ModelNode

  Returns a invalid NodeInstance if no NodeInstance for this ModelNode exists.

\param node ModelNode must be valid.
\returns  NodeStance for ModelNode.
\see NodeInstance
*/
475
NodeInstance NodeInstanceView::instanceForNode(const ModelNode &node) const
476
477
478
479
480
481
482
{
    Q_ASSERT(node.isValid());
    Q_ASSERT(m_nodeInstanceHash.contains(node));
    Q_ASSERT(m_nodeInstanceHash.value(node).modelNode() == node);
    return m_nodeInstanceHash.value(node);
}

483
bool NodeInstanceView::hasInstanceForNode(const ModelNode &node) const
484
485
486
487
{
    return m_nodeInstanceHash.contains(node);
}

488
NodeInstance NodeInstanceView::instanceForId(qint32 id)
489
{
490
    if (id < 0 || !hasModelNodeForInternalId(id))
491
492
        return NodeInstance();

493
    return m_nodeInstanceHash.value(modelNodeForInternalId(id));
494
495
}

496
bool NodeInstanceView::hasInstanceForId(qint32 id)
497
{
498
    if (id < 0 || !hasModelNodeForInternalId(id))
499
500
        return false;

501
    return m_nodeInstanceHash.contains(modelNodeForInternalId(id));
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
}


/*! \brief Returns the root NodeInstance of this view.


\returns  Root NodeIntance for this view.
\see NodeInstance
*/
NodeInstance NodeInstanceView::rootNodeInstance() const
{
    return m_rootNodeInstance;
}

/*! \brief Returns the view NodeInstance of this view.

  This can be the root NodeInstance if it is specified in the qml file.
\code
    QGraphicsView {
         QGraphicsScene {
             Item {}
         }
    }
\endcode

    If there is node view in the qml file:
 \code

    Item {}

\endcode
    Than there will be a new NodeInstance for this QGraphicsView
    generated which is not the root instance of this NodeInstanceView.

    This is the way to get this QGraphicsView NodeInstance.

\returns  Root NodeIntance for this view.
\see NodeInstance
*/



544
void NodeInstanceView::insertInstanceRelationships(const NodeInstance &instance)
545
{
546
    Q_ASSERT(instance.instanceId() >=0);
547
548
549
    if(m_nodeInstanceHash.contains(instance.modelNode()))
        return;

550
    m_nodeInstanceHash.insert(instance.modelNode(), instance);
551
552
553
554
555
556
557
558
559
560
}

void NodeInstanceView::removeInstanceNodeRelationship(const ModelNode &node)
{
    Q_ASSERT(m_nodeInstanceHash.contains(node));
    NodeInstance instance = instanceForNode(node);
    m_nodeInstanceHash.remove(node);
    instance.makeInvalid();
}

561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
void NodeInstanceView::setStateInstance(const NodeInstance &stateInstance)
{
    m_activeStateInstance = stateInstance;
}

void NodeInstanceView::clearStateInstance()
{
    m_activeStateInstance = NodeInstance();
}

NodeInstance NodeInstanceView::activeStateInstance() const
{
    return m_activeStateInstance;
}

576
NodeInstanceServerInterface *NodeInstanceView::nodeInstanceServer() const
577
{
578
    return m_nodeInstanceServer.data();
579
580
}

581
582

NodeInstance NodeInstanceView::loadNode(const ModelNode &node)
583
{
584
    NodeInstance instance(NodeInstance::create(node));
585
586

    insertInstanceRelationships(instance);
587
588
589
590
591
592
593
594

    if (node.isRootNode()) {
        m_rootNodeInstance = instance;
    }

    return instance;
}

595
596
void NodeInstanceView::activateState(const NodeInstance &instance)
{
597
598
599
600
    nodeInstanceServer()->changeState(ChangeStateCommand(instance.instanceId()));
//    activateBaseState();
//    NodeInstance stateInstance(instance);
//    stateInstance.activateState();
601
602
603
604
}

void NodeInstanceView::activateBaseState()
{
605
606
607
    nodeInstanceServer()->changeState(ChangeStateCommand(-1));
//    if (activeStateInstance().isValid())
//        activeStateInstance().deactivateState();
608
609
}

610
611
void NodeInstanceView::removeRecursiveChildRelationship(const ModelNode &removedNode)
{
612
613
614
//    if (hasInstanceForNode(removedNode)) {
//        instanceForNode(removedNode).setId(QString());
//    }
615

616
617
618
619
620
621
622
623
    foreach (const ModelNode &childNode, removedNode.allDirectSubModelNodes())
        removeRecursiveChildRelationship(childNode);

    removeInstanceNodeRelationship(removedNode);
}

QRectF NodeInstanceView::sceneRect() const
{
624
    if (rootNodeInstance().isValid())
625
       return rootNodeInstance().boundingRect();
626
627
628
629

    return QRectF();
}

630
CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
631
{
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
    QList<ModelNode> nodeList = allModelNodes();
    QList<NodeInstance> instanceList;

    foreach (const ModelNode &node, nodeList)
        instanceList.append(loadNode(node));


    QList<VariantProperty> variantPropertyList;
    QList<BindingProperty> bindingPropertyList;

    foreach (const ModelNode &node, nodeList) {
        variantPropertyList.append(node.variantProperties());
        bindingPropertyList.append(node.bindingProperties());
    }

    QVector<InstanceContainer> instanceContainerList;
    foreach(const NodeInstance &instance, instanceList) {
        InstanceContainer container(instance.instanceId(), instance.modelNode().type(), instance.modelNode().majorVersion(), instance.modelNode().minorVersion(), instance.modelNode().metaInfo().componentFileName());
        instanceContainerList.append(container);
    }

    QVector<ReparentContainer> reparentContainerList;
    foreach(const NodeInstance &instance, instanceList) {
        if (instance.modelNode().hasParentProperty()) {
            NodeAbstractProperty parentProperty = instance.modelNode().parentProperty();
            ReparentContainer container(instance.instanceId(), -1, QString(), instanceForNode(parentProperty.parentModelNode()).instanceId(), parentProperty.name());
            reparentContainerList.append(container);
        }
    }

    QVector<IdContainer> idContainerList;
    foreach(const NodeInstance &instance, instanceList) {
        QString id = instance.modelNode().id();
        if (!id.isEmpty()) {
            IdContainer container(instance.instanceId(), id);
            idContainerList.append(container);
        }
    }

    QVector<PropertyValueContainer> valueContainerList;
    foreach(const VariantProperty &property, variantPropertyList) {
        ModelNode node = property.parentModelNode();
        if (node.isValid() && hasInstanceForNode(node)) {
            NodeInstance instance = instanceForNode(node);
            PropertyValueContainer container(instance.instanceId(), property.name(), property.value(), property.dynamicTypeName());
            valueContainerList.append(container);
        }
    }

    QVector<PropertyBindingContainer> bindingContainerList;
    foreach(const BindingProperty &property, bindingPropertyList) {
        ModelNode node = property.parentModelNode();
        if (node.isValid() && hasInstanceForNode(node)) {
            NodeInstance instance = instanceForNode(node);
            PropertyBindingContainer container(instance.instanceId(), property.name(), property.expression(), property.dynamicTypeName());
            bindingContainerList.append(container);
        }
    }

691
692
693
694
    QVector<AddImportContainer> importVector;
    foreach(const Import &import, model()->imports())
        importVector.append(AddImportContainer(import.url(), import.file(), import.version(), import.alias(), import.importPaths()));

695
696
697
698
699
    return CreateSceneCommand(instanceContainerList,
                              reparentContainerList,
                              idContainerList,
                              valueContainerList,
                              bindingContainerList,
700
                              importVector,
701
                              model()->fileUrl());
702
}
703

704
705
706
707
ClearSceneCommand NodeInstanceView::createClearSceneCommand() const
{
    return ClearSceneCommand();
}
708

709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
CompleteComponentCommand NodeInstanceView::createComponentCompleteCommand(const QList<NodeInstance> &instanceList) const
{
    QVector<qint32> containerList;
    foreach(const NodeInstance &instance, instanceList) {
        if (instance.instanceId() >= 0)
            containerList.append(instance.instanceId());
    }

    return CompleteComponentCommand(containerList);
}

ComponentCompletedCommand NodeInstanceView::createComponentCompletedCommand(const QList<NodeInstance> &instanceList) const
{
    QVector<qint32> containerList;
    foreach(const NodeInstance &instance, instanceList) {
        if (instance.instanceId() >= 0)
            containerList.append(instance.instanceId());
    }

    return ComponentCompletedCommand(containerList);
}

731
CreateInstancesCommand NodeInstanceView::createCreateInstancesCommand(const QList<NodeInstance> &instanceList) const
732
{
733
734
    QVector<InstanceContainer> containerList;
    foreach(const NodeInstance &instance, instanceList) {
735
        InstanceContainer container(instance.instanceId(), instance.modelNode().type(), instance.modelNode().majorVersion(), instance.modelNode().minorVersion(), instance.modelNode().metaInfo().componentFileName());
736
        containerList.append(container);
737
738
    }

739
    return CreateInstancesCommand(containerList);
740
741
}

742
ReparentInstancesCommand NodeInstanceView::createReparentInstancesCommand(const QList<NodeInstance> &instanceList) const
743
{
744
745
746
747
748
749
750
751
    QVector<ReparentContainer> containerList;
    foreach(const NodeInstance &instance, instanceList) {
        if (instance.modelNode().hasParentProperty()) {
            NodeAbstractProperty parentProperty = instance.modelNode().parentProperty();
            ReparentContainer container(instance.instanceId(), -1, QString(), instanceForNode(parentProperty.parentModelNode()).instanceId(), parentProperty.name());
            containerList.append(container);
        }
    }
752

753
    return ReparentInstancesCommand(containerList);
754
755
}

756
ReparentInstancesCommand NodeInstanceView::createReparentInstancesCommand(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent) const
757
{
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
    QVector<ReparentContainer> containerList;

    qint32 newParentInstanceId = -1;
    qint32 oldParentInstanceId = -1;

    if (newPropertyParent.isValid() && hasInstanceForNode(newPropertyParent.parentModelNode()))
        newParentInstanceId = instanceForNode(newPropertyParent.parentModelNode()).instanceId();


    if (oldPropertyParent.isValid() && hasInstanceForNode(oldPropertyParent.parentModelNode()))
        oldParentInstanceId = instanceForNode(oldPropertyParent.parentModelNode()).instanceId();


    ReparentContainer container(instanceForNode(node).instanceId(), oldParentInstanceId, oldPropertyParent.name(), newParentInstanceId, newPropertyParent.name());

    containerList.append(container);

    return ReparentInstancesCommand(containerList);
776
777
}

778
ChangeFileUrlCommand NodeInstanceView::createChangeFileUrlCommand(const QUrl &fileUrl) const
779
{
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    return ChangeFileUrlCommand(fileUrl);
}

ChangeValuesCommand NodeInstanceView::createChangeValueCommand(const QList<VariantProperty>& propertyList) const
{
    QVector<PropertyValueContainer> containerList;

    foreach(const VariantProperty &property, propertyList) {
        ModelNode node = property.parentModelNode();
        if (node.isValid() && hasInstanceForNode(node)) {
            NodeInstance instance = instanceForNode(node);
            PropertyValueContainer container(instance.instanceId(), property.name(), property.value(), property.dynamicTypeName());
            containerList.append(container);
        }

    }

    return ChangeValuesCommand(containerList);
}

ChangeBindingsCommand NodeInstanceView::createChangeBindingCommand(const QList<BindingProperty> &propertyList) const
{
    QVector<PropertyBindingContainer> containerList;

    foreach(const BindingProperty &property, propertyList) {
        ModelNode node = property.parentModelNode();
        if (node.isValid() && hasInstanceForNode(node)) {
            NodeInstance instance = instanceForNode(node);
            PropertyBindingContainer container(instance.instanceId(), property.name(), property.expression(), property.dynamicTypeName());
            containerList.append(container);
        }

    }

    return ChangeBindingsCommand(containerList);
}

ChangeIdsCommand NodeInstanceView::createChangeIdsCommand(const QList<NodeInstance> &instanceList) const
{
    QVector<IdContainer> containerList;
    foreach(const NodeInstance &instance, instanceList) {
        QString id = instance.modelNode().id();
        if (!id.isEmpty()) {
            IdContainer container(instance.instanceId(), id);
            containerList.append(container);
        }
    }

    return ChangeIdsCommand(containerList);
}

831

832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875

RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const QList<ModelNode> &nodeList) const
{
    QVector<qint32> idList;
    foreach(const ModelNode &node, nodeList) {
        if (node.isValid() && hasInstanceForNode(node)) {
            NodeInstance instance = instanceForNode(node);

            if (instance.instanceId() >= 0) {
                idList.append(instance.instanceId());
            }
        }
    }

    return RemoveInstancesCommand(idList);
}

RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const ModelNode &node) const
{
    QVector<qint32> idList;

    if (node.isValid() && hasInstanceForNode(node))
        idList.append(instanceForNode(node).instanceId());

    return RemoveInstancesCommand(idList);
}

RemovePropertiesCommand NodeInstanceView::createRemovePropertiesCommand(const QList<AbstractProperty> &propertyList) const
{
    QVector<PropertyAbstractContainer> containerList;

    foreach(const AbstractProperty &property, propertyList) {
        ModelNode node = property.parentModelNode();
        if (node.isValid() && hasInstanceForNode(node)) {
            NodeInstance instance = instanceForNode(node);
            PropertyAbstractContainer container(instance.instanceId(), property.name(), property.dynamicTypeName());
            containerList.append(container);
        }

    }

    return RemovePropertiesCommand(containerList);
}

876
877
AddImportCommand NodeInstanceView::createImportCommand(const Import &import)
{
878
    return AddImportCommand(AddImportContainer(import.url(), import.file(), import.version(), import.alias(), import.importPaths()));
879
880
}

881
882
void NodeInstanceView::valuesChanged(const ValuesChangedCommand &command)
{
883
884
885
    if (!model())
        return;

886
887
    QList<QPair<ModelNode, QString> > valuePropertyChangeList;

888
889
890
891
892
    foreach(const PropertyValueContainer &container, command.valueChanges()) {
        if (hasInstanceForId(container.instanceId())) {
            NodeInstance instance = instanceForId(container.instanceId());
            if (instance.isValid()) {
                instance.setProperty(container.name(), container.value());
893
                valuePropertyChangeList.append(qMakePair(instance.modelNode(), container.name()));
894
895
896
897
            }
        }
    }

898
899
    if (!valuePropertyChangeList.isEmpty())
        emitInstancePropertyChange(valuePropertyChangeList);
900
901
902
}

void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
903
{
904
    if (!model())
905
906
        return;

907
    QSet<ModelNode> renderImageChangeSet;
908

909
910
911
912
913
914
915
    foreach (const ImageContainer &container, command.images()) {
        if (hasInstanceForId(container.instanceId())) {
            NodeInstance instance = instanceForId(container.instanceId());
            if (instance.isValid()) {
                instance.setRenderImage(container.image());
                renderImageChangeSet.insert(instance.modelNode());
            }
916
917
918
        }
    }

919
    if (!renderImageChangeSet.isEmpty())
920
        emitCustomNotification("__instance render pixmap changed__", renderImageChangeSet.toList());
921
922
923
924
}

void NodeInstanceView::informationChanged(const InformationChangedCommand &command)
{
925
926
927
    if (!model())
        return;

928
929
    QList<ModelNode> informationChangedList;

930
931
932
933
934
    foreach(const InformationContainer &container, command.informations()) {
        if (hasInstanceForId(container.instanceId())) {
            NodeInstance instance = instanceForId(container.instanceId());
            if (instance.isValid()) {
                instance.setInformation(container.name(), container.information(), container.secondInformation(), container.thirdInformation());
935
                informationChangedList.append(instance.modelNode());
936
937
938
            }
        }
    }
939

940
941
    if (!informationChangedList.isEmpty())
        emitCustomNotification("__instance information changed__", informationChangedList);
942
943
}

944
QImage NodeInstanceView::statePreviewImage(const ModelNode &stateNode) const
945
{
946
947
948
949
950
    if (stateNode == rootModelNode())
        return m_baseStatePreviewImage;

    return m_statePreviewImage.value(stateNode);
}
951

952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
void NodeInstanceView::statePreviewImagesChanged(const StatePreviewImageChangedCommand &command)
{
    if (!model())
      return;

  QList<ModelNode> previewImageChangeList;

  foreach (const ImageContainer &container, command.previews()) {
      if (container.instanceId() == 0) {
          m_baseStatePreviewImage = container.image();
          previewImageChangeList.append(rootModelNode());
      } else if (hasInstanceForId(container.instanceId())) {
          ModelNode node = modelNodeForInternalId(container.instanceId());
          m_statePreviewImage.insert(node, container.image());
          previewImageChangeList.append(node);
      }
  }

  if (!previewImageChangeList.isEmpty())
       emitCustomNotification("__instance preview image changed__", previewImageChangeList);
972
973
}

974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
void NodeInstanceView::componentCompleted(const ComponentCompletedCommand &command)
{
    if (!model())
        return;

    QVector<ModelNode> nodeVector;

    foreach(const qint32 &instanceId, command.instances()) {
        if (hasModelNodeForInternalId(instanceId)) {
            nodeVector.append(modelNodeForInternalId(instanceId));
        }
    }

    if (!nodeVector.isEmpty())
        emitInstancesCompleted(nodeVector);
}

991
992
void NodeInstanceView::childrenChanged(const ChildrenChangedCommand &command)
{
993
994
995
     if (!model())
        return;

996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
    QList<ModelNode> childNodeList;

    foreach(qint32 instanceId, command.childrenInstances()) {
        if (hasInstanceForId(instanceId)) {
            NodeInstance instance = instanceForId(instanceId);
            instance.setParentId(command.parentInstanceId());
            childNodeList.append(instance.modelNode());
        }
    }

    if (!childNodeList.isEmpty())
        emitCustomNotification("__instance children changed__", childNodeList);
}
1009

1010
}