1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
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
16 ** GNU Lesser General Public License Usage
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.
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.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "nodeinstanceview.h"
36 #include <QDeclarativeEngine>
37 #include <QDeclarativeContext>
38 #include <private/qdeclarativeengine_p.h>
42 #include <QGraphicsView>
43 #include <QGraphicsScene>
44 #include <QGraphicsObject>
45 #include <QFileSystemWatcher>
48 #include <modelnode.h>
52 #include <iwidgetplugin.h>
54 #include "abstractproperty.h"
55 #include "variantproperty.h"
56 #include "bindingproperty.h"
57 #include "nodeabstractproperty.h"
58 #include "nodelistproperty.h"
60 #include <nodeinstanceserverinterface.h>
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"
83 #include "nodeinstanceserverproxy.h"
90 \defgroup CoreInstance
93 \class QmlDesigner::NodeInstanceView
95 \brief Central class to create and manage instances of a ModelNode.
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.
101 \see NodeInstance ModelNode
104 namespace QmlDesigner {
106 /*! \brief Constructor
108 The class will be rendered offscreen if not set otherwise.
110 \param Parent of this object. If this parent is d this instance is
113 \see ~NodeInstanceView setRenderOffScreen
115 NodeInstanceView::NodeInstanceView(QObject *parent, NodeInstanceServerInterface::RunModus runModus)
116 : AbstractView(parent),
117 m_baseStatePreviewImage(QSize(100, 100), QImage::Format_ARGB32),
120 m_baseStatePreviewImage.fill(0xFFFFFF);
124 /*! \brief Destructor
127 NodeInstanceView::~NodeInstanceView()
129 removeAllInstanceNodeRelationships();
130 delete nodeInstanceServer();
133 /*! \name Overloaded Notifiers
134 * This methodes notify the view that something has happen in the model
137 /*! \brief Notifing the view that it was attached to a model.
139 For every ModelNode in the model a NodeInstance will be created.
140 \param model Model to which the view is attached
143 bool isSkippedNode(const ModelNode &node)
145 static QStringList skipList = QStringList() << "Qt.ListModel" << "QtQuick.ListModel";
147 if (skipList.contains(node.type()))
153 void NodeInstanceView::modelAttached(Model *model)
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()));
160 if (!isSkippedNode(rootModelNode()))
161 nodeInstanceServer()->createScene(createCreateSceneCommand());
164 void NodeInstanceView::modelAboutToBeDetached(Model * model)
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);
177 void NodeInstanceView::handleChrash()
179 int elaspsedTimeSinceLastCrash = m_lastCrashTime.restart();
181 if (elaspsedTimeSinceLastCrash > 2000) {
184 emitCustomNotification("QmlPuppet crashed");
190 void NodeInstanceView::restartProcess()
193 delete nodeInstanceServer();
195 m_nodeInstanceServer = new NodeInstanceServerProxy(this, m_runModus);
196 connect(m_nodeInstanceServer.data(), SIGNAL(processCrashed()), this, SLOT(handleChrash()));
198 if (!isSkippedNode(rootModelNode()))
199 nodeInstanceServer()->createScene(createCreateSceneCommand());
203 void NodeInstanceView::nodeCreated(const ModelNode &createdNode)
205 NodeInstance instance = loadNode(createdNode);
207 if (isSkippedNode(createdNode))
210 nodeInstanceServer()->createInstances(createCreateInstancesCommand(QList<NodeInstance>() << instance));
211 nodeInstanceServer()->changePropertyValues(createChangeValueCommand(createdNode.variantProperties()));
212 nodeInstanceServer()->completeComponent(createComponentCompleteCommand(QList<NodeInstance>() << instance));
215 /*! \brief Notifing the view that a node was created.
218 void NodeInstanceView::nodeAboutToBeRemoved(const ModelNode &removedNode)
220 nodeInstanceServer()->removeInstances(createRemoveInstancesCommand(removedNode));
221 removeInstanceAndSubInstances(removedNode);
224 void NodeInstanceView::nodeRemoved(const ModelNode &/*removedNode*/, const NodeAbstractProperty &/*parentProperty*/, PropertyChangeFlags /*propertyChange*/)
228 void NodeInstanceView::resetHorizontalAnchors(const ModelNode &modelNode)
230 QList<BindingProperty> bindingList;
231 QList<VariantProperty> valueList;
233 if (modelNode.hasBindingProperty("x")) {
234 bindingList.append(modelNode.bindingProperty("x"));
235 } else if (modelNode.hasVariantProperty("x")) {
236 valueList.append(modelNode.variantProperty("x"));
239 if (modelNode.hasBindingProperty("width")) {
240 bindingList.append(modelNode.bindingProperty("width"));
241 } else if (modelNode.hasVariantProperty("width")) {
242 valueList.append(modelNode.variantProperty("width"));
245 if (!valueList.isEmpty())
246 nodeInstanceServer()->changePropertyValues(createChangeValueCommand(valueList));
248 if (!bindingList.isEmpty())
249 nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(bindingList));
253 void NodeInstanceView::resetVerticalAnchors(const ModelNode &modelNode)
255 QList<BindingProperty> bindingList;
256 QList<VariantProperty> valueList;
258 if (modelNode.hasBindingProperty("yx")) {
259 bindingList.append(modelNode.bindingProperty("yx"));
260 } else if (modelNode.hasVariantProperty("y")) {
261 valueList.append(modelNode.variantProperty("y"));
264 if (modelNode.hasBindingProperty("height")) {
265 bindingList.append(modelNode.bindingProperty("height"));
266 } else if (modelNode.hasVariantProperty("height")) {
267 valueList.append(modelNode.variantProperty("height"));
270 if (!valueList.isEmpty())
271 nodeInstanceServer()->changePropertyValues(createChangeValueCommand(valueList));
273 if (!bindingList.isEmpty())
274 nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(bindingList));
277 void NodeInstanceView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList)
280 QList<ModelNode> nodeList;
281 QList<AbstractProperty> nonNodePropertyList;
283 foreach (const AbstractProperty &property, propertyList) {
284 if (property.isNodeAbstractProperty()) {
285 nodeList.append(property.toNodeAbstractProperty().allSubNodes());
287 nonNodePropertyList.append(property);
291 nodeInstanceServer()->removeInstances(createRemoveInstancesCommand(nodeList));
292 nodeInstanceServer()->removeProperties(createRemovePropertiesCommand(nonNodePropertyList));
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());
319 foreach (const ModelNode &node, nodeList)
320 removeInstanceNodeRelationship(node);
323 void NodeInstanceView::propertiesRemoved(const QList<AbstractProperty>& /*propertyList*/)
327 void NodeInstanceView::removeInstanceAndSubInstances(const ModelNode &node)
329 foreach(const ModelNode &subNode, node.allSubModelNodes()) {
330 if (hasInstanceForNode(subNode))
331 removeInstanceNodeRelationship(subNode);
334 if (hasInstanceForNode(node))
335 removeInstanceNodeRelationship(node);
338 void NodeInstanceView::rootNodeTypeChanged(const QString &/*type*/, int /*majorVersion*/, int /*minorVersion*/)
343 void NodeInstanceView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
345 nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(propertyList));
348 /*! \brief Notifing the view that a AbstractProperty value was changed to a ModelNode.
350 The property will be set for the NodeInstance.
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
359 void NodeInstanceView::variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
361 nodeInstanceServer()->changePropertyValues(createChangeValueCommand(propertyList));
363 /*! \brief Notifing the view that a ModelNode has a new Parent.
365 Note that also the ModelNode::childNodes() list was changed. The
366 NodeInstance tree will be changed to reflect the ModelNode tree change.
368 \param node ModelNode which parent was changed.
369 \param oldParent Old parent of the node.
370 \param newParent New parent of the node.
372 \see NodeInstance ModelNode
375 void NodeInstanceView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
377 if (!isSkippedNode(node))
378 nodeInstanceServer()->reparentInstances(createReparentInstancesCommand(node, newPropertyParent, oldPropertyParent));
381 void NodeInstanceView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
386 void NodeInstanceView::fileUrlChanged(const QUrl &/*oldUrl*/, const QUrl &newUrl)
388 nodeInstanceServer()->changeFileUrl(createChangeFileUrlCommand(newUrl));
391 void NodeInstanceView::nodeIdChanged(const ModelNode& node, const QString& /*newId*/, const QString& /*oldId*/)
393 if (hasInstanceForNode(node)) {
394 NodeInstance instance = instanceForNode(node);
395 nodeInstanceServer()->changeIds(createChangeIdsCommand(QList<NodeInstance>() << instance));
399 void NodeInstanceView::nodeOrderChanged(const NodeListProperty & listProperty,
400 const ModelNode & /*movedNode*/, int /*oldIndex*/)
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();
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);
418 nodeInstanceServer()->reparentInstances(ReparentInstancesCommand(containerList));
421 /*! \brief Notifing the view that the selection has been changed.
425 \param selectedNodeList List of ModelNode which has been selected
426 \param lastSelectedNodeList List of ModelNode which was selected
428 \see ModelNode NodeInstance
430 void NodeInstanceView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/,
431 const QList<ModelNode> &/*lastSelectedNodeList*/)
435 void NodeInstanceView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/)
440 void NodeInstanceView::instancePropertyChange(const QList<QPair<ModelNode, QString> > &/*propertyList*/)
445 void NodeInstanceView::instancesCompleted(const QVector<ModelNode> &/*completedNodeList*/)
449 void NodeInstanceView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/)
454 void NodeInstanceView::instanceInformationsChange(const QVector<ModelNode> &/*nodeList*/)
459 void NodeInstanceView::instancesRenderImageChanged(const QVector<ModelNode> &/*nodeList*/)
464 void NodeInstanceView::instancesPreviewImageChanged(const QVector<ModelNode> &/*nodeList*/)
469 void NodeInstanceView::instancesChildrenChanged(const QVector<ModelNode> &/*nodeList*/)
474 void NodeInstanceView::auxiliaryDataChanged(const ModelNode &node, const QString &name, const QVariant &data)
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);
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);
499 void NodeInstanceView::customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &, const QList<QVariant> &)
501 if (view && identifier == QLatin1String("reset QmlPuppet"))
505 void NodeInstanceView::rewriterBeginTransaction()
510 void NodeInstanceView::rewriterEndTransaction()
515 void NodeInstanceView::actualStateChanged(const ModelNode &/*node*/)
523 void NodeInstanceView::removeAllInstanceNodeRelationships()
525 m_nodeInstanceHash.clear();
528 /*! \brief Returns a List of all NodeInstances
533 QList<NodeInstance> NodeInstanceView::instances() const
535 return m_nodeInstanceHash.values();
538 /*! \brief Returns the NodeInstance for this ModelNode
540 Returns a invalid NodeInstance if no NodeInstance for this ModelNode exists.
542 \param node ModelNode must be valid.
543 \returns NodeStance for ModelNode.
546 NodeInstance NodeInstanceView::instanceForNode(const ModelNode &node) const
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);
554 bool NodeInstanceView::hasInstanceForNode(const ModelNode &node) const
556 return m_nodeInstanceHash.contains(node);
559 NodeInstance NodeInstanceView::instanceForId(qint32 id)
561 if (id < 0 || !hasModelNodeForInternalId(id))
562 return NodeInstance();
564 return m_nodeInstanceHash.value(modelNodeForInternalId(id));
567 bool NodeInstanceView::hasInstanceForId(qint32 id)
569 if (id < 0 || !hasModelNodeForInternalId(id))
572 return m_nodeInstanceHash.contains(modelNodeForInternalId(id));
576 /*! \brief Returns the root NodeInstance of this view.
579 \returns Root NodeIntance for this view.
582 NodeInstance NodeInstanceView::rootNodeInstance() const
584 return m_rootNodeInstance;
587 /*! \brief Returns the view NodeInstance of this view.
589 This can be the root NodeInstance if it is specified in the qml file.
598 If there is node view in the qml file:
604 Than there will be a new NodeInstance for this QGraphicsView
605 generated which is not the root instance of this NodeInstanceView.
607 This is the way to get this QGraphicsView NodeInstance.
609 \returns Root NodeIntance for this view.
615 void NodeInstanceView::insertInstanceRelationships(const NodeInstance &instance)
617 Q_ASSERT(instance.instanceId() >=0);
618 if(m_nodeInstanceHash.contains(instance.modelNode()))
621 m_nodeInstanceHash.insert(instance.modelNode(), instance);
624 void NodeInstanceView::removeInstanceNodeRelationship(const ModelNode &node)
626 Q_ASSERT(m_nodeInstanceHash.contains(node));
627 NodeInstance instance = instanceForNode(node);
628 m_nodeInstanceHash.remove(node);
629 instance.makeInvalid();
632 void NodeInstanceView::setStateInstance(const NodeInstance &stateInstance)
634 m_activeStateInstance = stateInstance;
637 void NodeInstanceView::clearStateInstance()
639 m_activeStateInstance = NodeInstance();
642 NodeInstance NodeInstanceView::activeStateInstance() const
644 return m_activeStateInstance;
647 NodeInstanceServerInterface *NodeInstanceView::nodeInstanceServer() const
649 return m_nodeInstanceServer.data();
653 NodeInstance NodeInstanceView::loadNode(const ModelNode &node)
655 NodeInstance instance(NodeInstance::create(node));
657 insertInstanceRelationships(instance);
659 if (node.isRootNode()) {
660 m_rootNodeInstance = instance;
666 void NodeInstanceView::activateState(const NodeInstance &instance)
668 nodeInstanceServer()->changeState(ChangeStateCommand(instance.instanceId()));
669 // activateBaseState();
670 // NodeInstance stateInstance(instance);
671 // stateInstance.activateState();
674 void NodeInstanceView::activateBaseState()
676 nodeInstanceServer()->changeState(ChangeStateCommand(-1));
677 // if (activeStateInstance().isValid())
678 // activeStateInstance().deactivateState();
681 void NodeInstanceView::removeRecursiveChildRelationship(const ModelNode &removedNode)
683 // if (hasInstanceForNode(removedNode)) {
684 // instanceForNode(removedNode).setId(QString());
687 foreach (const ModelNode &childNode, removedNode.allDirectSubModelNodes())
688 removeRecursiveChildRelationship(childNode);
690 removeInstanceNodeRelationship(removedNode);
693 QRectF NodeInstanceView::sceneRect() const
695 if (rootNodeInstance().isValid())
696 return rootNodeInstance().boundingRect();
701 QList<ModelNode> filterNodesForSkipItems(const QList<ModelNode> &nodeList)
703 QList<ModelNode> filteredNodeList;
704 foreach(const ModelNode &node, nodeList) {
705 if (isSkippedNode(node))
708 filteredNodeList.append(node);
711 return filteredNodeList;
714 CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
716 QList<ModelNode> nodeList = allModelNodes();
717 QList<NodeInstance> instanceList;
719 foreach (const ModelNode &node, nodeList) {
720 NodeInstance instance = loadNode(node);
721 if (!isSkippedNode(node))
722 instanceList.append(instance);
725 nodeList = filterNodesForSkipItems(nodeList);
727 QList<VariantProperty> variantPropertyList;
728 QList<BindingProperty> bindingPropertyList;
730 foreach (const ModelNode &node, nodeList) {
731 variantPropertyList.append(node.variantProperties());
732 bindingPropertyList.append(node.bindingProperties());
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);
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);
750 QVector<IdContainer> idContainerList;
751 foreach(const NodeInstance &instance, instanceList) {
752 QString id = instance.modelNode().id();
754 IdContainer container(instance.instanceId(), id);
755 idContainerList.append(container);
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());
770 NodeInstance instance = instanceForNode(node);
771 PropertyValueContainer container(instance.instanceId(), property.name(), value, property.dynamicTypeName());
772 valueContainerList.append(container);
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())
786 NodeInstance instance = instanceForNode(node);
787 PropertyBindingContainer container(instance.instanceId(), property.name(), property.expression(), property.dynamicTypeName());
788 bindingContainerList.append(container);
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()));
796 return CreateSceneCommand(instanceContainerList,
797 reparentContainerList,
800 bindingContainerList,
805 ClearSceneCommand NodeInstanceView::createClearSceneCommand() const
807 return ClearSceneCommand();
810 CompleteComponentCommand NodeInstanceView::createComponentCompleteCommand(const QList<NodeInstance> &instanceList) const
812 QVector<qint32> containerList;
813 foreach(const NodeInstance &instance, instanceList) {
814 if (instance.instanceId() >= 0)
815 containerList.append(instance.instanceId());
818 return CompleteComponentCommand(containerList);
821 ComponentCompletedCommand NodeInstanceView::createComponentCompletedCommand(const QList<NodeInstance> &instanceList) const
823 QVector<qint32> containerList;
824 foreach(const NodeInstance &instance, instanceList) {
825 if (instance.instanceId() >= 0)
826 containerList.append(instance.instanceId());
829 return ComponentCompletedCommand(containerList);
832 CreateInstancesCommand NodeInstanceView::createCreateInstancesCommand(const QList<NodeInstance> &instanceList) const
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);
840 return CreateInstancesCommand(containerList);
843 ReparentInstancesCommand NodeInstanceView::createReparentInstancesCommand(const QList<NodeInstance> &instanceList) const
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);
854 return ReparentInstancesCommand(containerList);
857 ReparentInstancesCommand NodeInstanceView::createReparentInstancesCommand(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent) const
859 QVector<ReparentContainer> containerList;
861 qint32 newParentInstanceId = -1;
862 qint32 oldParentInstanceId = -1;
864 if (newPropertyParent.isValid() && hasInstanceForNode(newPropertyParent.parentModelNode()))
865 newParentInstanceId = instanceForNode(newPropertyParent.parentModelNode()).instanceId();
868 if (oldPropertyParent.isValid() && hasInstanceForNode(oldPropertyParent.parentModelNode()))
869 oldParentInstanceId = instanceForNode(oldPropertyParent.parentModelNode()).instanceId();
872 ReparentContainer container(instanceForNode(node).instanceId(), oldParentInstanceId, oldPropertyParent.name(), newParentInstanceId, newPropertyParent.name());
874 containerList.append(container);
876 return ReparentInstancesCommand(containerList);
879 ChangeFileUrlCommand NodeInstanceView::createChangeFileUrlCommand(const QUrl &fileUrl) const
881 return ChangeFileUrlCommand(fileUrl);
884 ChangeValuesCommand NodeInstanceView::createChangeValueCommand(const QList<VariantProperty>& propertyList) const
886 QVector<PropertyValueContainer> containerList;
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);
898 return ChangeValuesCommand(containerList);
901 ChangeBindingsCommand NodeInstanceView::createChangeBindingCommand(const QList<BindingProperty> &propertyList) const
903 QVector<PropertyBindingContainer> containerList;
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);
915 return ChangeBindingsCommand(containerList);
918 ChangeIdsCommand NodeInstanceView::createChangeIdsCommand(const QList<NodeInstance> &instanceList) const
920 QVector<IdContainer> containerList;
921 foreach(const NodeInstance &instance, instanceList) {
922 QString id = instance.modelNode().id();
924 IdContainer container(instance.instanceId(), id);
925 containerList.append(container);
929 return ChangeIdsCommand(containerList);
934 RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const QList<ModelNode> &nodeList) const
936 QVector<qint32> idList;
937 foreach(const ModelNode &node, nodeList) {
938 if (node.isValid() && hasInstanceForNode(node)) {
939 NodeInstance instance = instanceForNode(node);
941 if (instance.instanceId() >= 0) {
942 idList.append(instance.instanceId());
947 return RemoveInstancesCommand(idList);
950 RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const ModelNode &node) const
952 QVector<qint32> idList;
954 if (node.isValid() && hasInstanceForNode(node))
955 idList.append(instanceForNode(node).instanceId());
957 return RemoveInstancesCommand(idList);
960 RemovePropertiesCommand NodeInstanceView::createRemovePropertiesCommand(const QList<AbstractProperty> &propertyList) const
962 QVector<PropertyAbstractContainer> containerList;
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);
974 return RemovePropertiesCommand(containerList);
977 AddImportCommand NodeInstanceView::createImportCommand(const Import &import)
979 return AddImportCommand(AddImportContainer(import.url(), import.file(), import.version(), import.alias(), import.importPaths()));
982 void NodeInstanceView::valuesChanged(const ValuesChangedCommand &command)
987 QList<QPair<ModelNode, QString> > valuePropertyChangeList;
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()));
999 if (!valuePropertyChangeList.isEmpty())
1000 emitInstancePropertyChange(valuePropertyChangeList);
1003 void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
1008 QSet<ModelNode> renderImageChangeSet;
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());
1020 if (!renderImageChangeSet.isEmpty())
1021 emitInstancesRenderImageChanged(renderImageChangeSet.toList().toVector());
1024 void NodeInstanceView::informationChanged(const InformationChangedCommand &command)
1029 QVector<ModelNode> informationChangedVector;
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());
1042 if (!informationChangedVector.isEmpty())
1043 emitInstanceInformationsChange(informationChangedVector.toList().toVector());
1046 QImage NodeInstanceView::statePreviewImage(const ModelNode &stateNode) const
1048 if (stateNode == rootModelNode())
1049 return m_baseStatePreviewImage;
1051 return m_statePreviewImage.value(stateNode);
1054 void NodeInstanceView::statePreviewImagesChanged(const StatePreviewImageChangedCommand &command)
1059 QVector<ModelNode> previewImageChangeVector;
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);
1072 if (!previewImageChangeVector.isEmpty())
1073 emitInstancesPreviewImageChanged(previewImageChangeVector);
1076 void NodeInstanceView::componentCompleted(const ComponentCompletedCommand &command)
1081 QVector<ModelNode> nodeVector;
1083 foreach(const qint32 &instanceId, command.instances()) {
1084 if (hasModelNodeForInternalId(instanceId)) {
1085 nodeVector.append(modelNodeForInternalId(instanceId));
1089 if (!nodeVector.isEmpty())
1090 emitInstancesCompleted(nodeVector);
1093 void NodeInstanceView::childrenChanged(const ChildrenChangedCommand &command)
1098 QVector<ModelNode> childNodeVector;
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());
1108 if (!childNodeVector.isEmpty())
1109 emitInstancesChildrenChanged(childNodeVector);