| 
									
										
										
										
											2012-11-06 15:35:19 +01:00
										 |  |  | /****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2016-01-15 14:59:14 +01:00
										 |  |  | ** Copyright (C) 2016 The Qt Company Ltd. | 
					
						
							|  |  |  | ** Contact: https://www.qt.io/licensing/
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-11-06 15:35:19 +01:00
										 |  |  | ** This file is part of Qt Creator. | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-11-06 15:35:19 +01:00
										 |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							| 
									
										
										
										
											2016-01-15 14:59:14 +01:00
										 |  |  | ** a written agreement between you and The Qt Company. For licensing terms | 
					
						
							|  |  |  | ** and conditions see https://www.qt.io/terms-conditions. For further
 | 
					
						
							|  |  |  | ** information use the contact form at https://www.qt.io/contact-us.
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2015-09-18 11:34:48 +02:00
										 |  |  | ** GNU General Public License Usage | 
					
						
							|  |  |  | ** Alternatively, this file may be used under the terms of the GNU | 
					
						
							| 
									
										
										
										
											2016-01-15 14:59:14 +01:00
										 |  |  | ** General Public License version 3 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
					
						
							|  |  |  | ** included in the packaging of this file. Please review the following | 
					
						
							|  |  |  | ** information to ensure the GNU General Public License requirements will | 
					
						
							|  |  |  | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-11-06 15:35:19 +01:00
										 |  |  | ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2016-01-15 14:59:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | #include "nodeinstanceserver.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-15 13:41:01 +02:00
										 |  |  | #include "servernodeinstance.h"
 | 
					
						
							|  |  |  | #include "objectnodeinstance.h"
 | 
					
						
							|  |  |  | #include "childrenchangeeventfilter.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "dummycontextobject.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <propertyabstractcontainer.h>
 | 
					
						
							|  |  |  | #include <propertybindingcontainer.h>
 | 
					
						
							|  |  |  | #include <propertyvaluecontainer.h>
 | 
					
						
							|  |  |  | #include <instancecontainer.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <commondefines.h>
 | 
					
						
							|  |  |  | #include <nodeinstanceclientinterface.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-19 13:11:39 +02:00
										 |  |  | #include <qmlprivategate.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 15:30:29 +02:00
										 |  |  | #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
 | 
					
						
							|  |  |  | #include <private/qquickdesignersupportmetainfo_p.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-15 13:41:01 +02:00
										 |  |  | #include <createinstancescommand.h>
 | 
					
						
							|  |  |  | #include <changefileurlcommand.h>
 | 
					
						
							|  |  |  | #include <clearscenecommand.h>
 | 
					
						
							|  |  |  | #include <reparentinstancescommand.h>
 | 
					
						
							|  |  |  | #include <changevaluescommand.h>
 | 
					
						
							|  |  |  | #include <changeauxiliarycommand.h>
 | 
					
						
							|  |  |  | #include <changebindingscommand.h>
 | 
					
						
							|  |  |  | #include <changeidscommand.h>
 | 
					
						
							|  |  |  | #include <removeinstancescommand.h>
 | 
					
						
							|  |  |  | #include <removepropertiescommand.h>
 | 
					
						
							|  |  |  | #include <valueschangedcommand.h>
 | 
					
						
							|  |  |  | #include <informationchangedcommand.h>
 | 
					
						
							|  |  |  | #include <pixmapchangedcommand.h>
 | 
					
						
							|  |  |  | #include <changestatecommand.h>
 | 
					
						
							|  |  |  | #include <childrenchangedcommand.h>
 | 
					
						
							|  |  |  | #include <completecomponentcommand.h>
 | 
					
						
							|  |  |  | #include <componentcompletedcommand.h>
 | 
					
						
							|  |  |  | #include <createscenecommand.h>
 | 
					
						
							|  |  |  | #include <changenodesourcecommand.h>
 | 
					
						
							|  |  |  | #include <tokencommand.h>
 | 
					
						
							|  |  |  | #include <removesharedmemorycommand.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  | #include <QDebug>
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | #include <QQmlEngine>
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  | #include <QQmlApplicationEngine>
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | #include <QFileSystemWatcher>
 | 
					
						
							|  |  |  | #include <QUrl>
 | 
					
						
							|  |  |  | #include <QSet>
 | 
					
						
							|  |  |  | #include <QDir>
 | 
					
						
							|  |  |  | #include <QVariant>
 | 
					
						
							|  |  |  | #include <QMetaType>
 | 
					
						
							|  |  |  | #include <QQmlComponent>
 | 
					
						
							|  |  |  | #include <QQmlContext>
 | 
					
						
							|  |  |  | #include <qqmllist.h>
 | 
					
						
							|  |  |  | #include <QAbstractAnimation>
 | 
					
						
							|  |  |  | #include <QMutableVectorIterator>
 | 
					
						
							| 
									
										
										
										
											2015-05-19 15:04:36 +02:00
										 |  |  | #include <QQuickView>
 | 
					
						
							| 
									
										
										
										
											2016-11-21 15:58:23 +01:00
										 |  |  | #include <QSet>
 | 
					
						
							| 
									
										
										
										
											2015-07-14 12:06:07 +02:00
										 |  |  | #include <designersupportdelegate.h>
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 11:51:31 +02:00
										 |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  | namespace { | 
					
						
							| 
									
										
										
										
											2019-07-03 18:34:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool testImportStatements(const QStringList &importStatementList, | 
					
						
							|  |  |  |                           const QUrl &url, QString *errorMessage = nullptr) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-11-21 18:23:56 +01:00
										 |  |  |     if (importStatementList.isEmpty()) | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2016-10-05 12:14:42 +02:00
										 |  |  |     // ToDo: move engine outside of this function, this makes it expensive
 | 
					
						
							|  |  |  |     QQmlEngine engine; | 
					
						
							|  |  |  |     QQmlComponent testImportComponent(&engine); | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-05 12:14:42 +02:00
										 |  |  |     QByteArray testComponentCode = QStringList(importStatementList).join("\n").toUtf8(); | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-05 12:14:42 +02:00
										 |  |  |     testImportComponent.setData(testComponentCode.append("\nItem {}\n"), url); | 
					
						
							|  |  |  |     testImportComponent.create(); | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-05 12:14:42 +02:00
										 |  |  |     if (testImportComponent.isError()) { | 
					
						
							|  |  |  |         if (errorMessage) { | 
					
						
							|  |  |  |             errorMessage->append("found not working imports: "); | 
					
						
							|  |  |  |             errorMessage->append(testImportComponent.errorString()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sortFilterImports(const QStringList &imports, QStringList *workingImports, QStringList *failedImports, const QUrl &url, QString *errorMessage) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-11-21 15:58:23 +01:00
										 |  |  |     static QSet<QString> visited; | 
					
						
							| 
									
										
										
										
											2016-11-21 18:23:56 +01:00
										 |  |  |     QString visitCheckId("imports: %1, workingImports: %2, failedImports: %3"); | 
					
						
							|  |  |  |     visitCheckId = visitCheckId.arg(imports.join(""), workingImports->join(""), failedImports->join("")); | 
					
						
							|  |  |  |     if (visited.contains(visitCheckId)) | 
					
						
							| 
									
										
										
										
											2016-11-21 15:58:23 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2016-11-21 18:23:56 +01:00
										 |  |  |         visited.insert(visitCheckId); | 
					
						
							| 
									
										
										
										
											2016-11-21 15:58:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-05 12:14:42 +02:00
										 |  |  |     for (const QString &import : imports) { | 
					
						
							|  |  |  |         const QStringList alreadyTestedImports = *workingImports + *failedImports; | 
					
						
							|  |  |  |         if (!alreadyTestedImports.contains(import)) { | 
					
						
							|  |  |  |             QStringList readyForTestImports = *workingImports; | 
					
						
							|  |  |  |             readyForTestImports.append(import); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QString lastErrorMessage; | 
					
						
							|  |  |  |             if (testImportStatements(readyForTestImports, url, &lastErrorMessage)) { | 
					
						
							|  |  |  |                 Q_ASSERT(!workingImports->contains(import)); | 
					
						
							|  |  |  |                 workingImports->append(import); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 if (imports.endsWith(import) == false) { | 
					
						
							|  |  |  |                     // the not working import is not the last import, so there could be some
 | 
					
						
							|  |  |  |                     // import dependency which we try with the reorderd remaining imports
 | 
					
						
							|  |  |  |                     QStringList reorderedImports; | 
					
						
							|  |  |  |                     std::copy_if(imports.cbegin(), imports.cend(), std::back_inserter(reorderedImports), | 
					
						
							|  |  |  |                                  [&import, &alreadyTestedImports] (const QString &checkForResortingImport){ | 
					
						
							|  |  |  |                         if (checkForResortingImport == import) | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         return !alreadyTestedImports.contains(checkForResortingImport); | 
					
						
							|  |  |  |                     }); | 
					
						
							|  |  |  |                     reorderedImports.append(import); | 
					
						
							|  |  |  |                     sortFilterImports(reorderedImports, workingImports, failedImports, url, errorMessage); | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     Q_ASSERT(!failedImports->contains(import)); | 
					
						
							|  |  |  |                     failedImports->append(import); | 
					
						
							|  |  |  |                     if (errorMessage) | 
					
						
							|  |  |  |                         errorMessage->append(lastErrorMessage); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2015-02-18 13:32:35 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-05 12:14:42 +02:00
										 |  |  | } // anonymous
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace QmlDesigner { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-19 14:12:06 +02:00
										 |  |  | static NodeInstanceServer *nodeInstanceServerInstance = nullptr; | 
					
						
							| 
									
										
										
										
											2015-05-21 11:47:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void notifyPropertyChangeCallBackFunction(QObject *object, const PropertyName &propertyName) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     qint32 id = nodeInstanceServerInstance->instanceForObject(object).instanceId(); | 
					
						
							|  |  |  |     nodeInstanceServerInstance->notifyPropertyChange(id, propertyName); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void (*notifyPropertyChangeCallBackPointer)(QObject *, const PropertyName &) = ¬ifyPropertyChangeCallBackFunction; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | NodeInstanceServer::NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : | 
					
						
							|  |  |  |     NodeInstanceServerInterface(), | 
					
						
							|  |  |  |     m_childrenChangeEventFilter(new Internal::ChildrenChangeEventFilter(this)), | 
					
						
							| 
									
										
										
										
											2017-09-19 14:12:06 +02:00
										 |  |  |     m_nodeInstanceClient(nodeInstanceClient) | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     qmlRegisterType<DummyContextObject>("QmlDesigner", 1, 0, "DummyContextObject"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-19 14:33:31 +01:00
										 |  |  |     connect(m_childrenChangeEventFilter.data(), &Internal::ChildrenChangeEventFilter::childrenChanged, this, &NodeInstanceServer::emitParentChanged); | 
					
						
							| 
									
										
										
										
											2015-05-21 11:47:27 +02:00
										 |  |  |     nodeInstanceServerInstance = this; | 
					
						
							|  |  |  |     Internal::QmlPrivateGate::registerNotifyPropertyChangeCallBack(notifyPropertyChangeCallBackPointer); | 
					
						
							| 
									
										
										
										
											2016-06-10 16:04:33 +02:00
										 |  |  |     Internal::QmlPrivateGate::registerFixResourcePathsForObjectCallBack(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-09 13:28:32 +02:00
										 |  |  | QList<ServerNodeInstance> NodeInstanceServer::createInstances(const QVector<InstanceContainer> &containerVector) | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     Q_ASSERT(declarativeView() || quickView()); | 
					
						
							|  |  |  |     QList<ServerNodeInstance> instanceList; | 
					
						
							| 
									
										
										
										
											2019-07-25 16:58:50 +02:00
										 |  |  |     for (const InstanceContainer &instanceContainer : containerVector) { | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         ServerNodeInstance instance; | 
					
						
							|  |  |  |         if (instanceContainer.nodeSourceType() == InstanceContainer::ComponentSource) { | 
					
						
							|  |  |  |             instance = ServerNodeInstance::create(this, instanceContainer, ServerNodeInstance::WrapAsComponent); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             instance = ServerNodeInstance::create(this, instanceContainer, ServerNodeInstance::DoNotWrapAsComponent); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         insertInstanceRelationship(instance); | 
					
						
							|  |  |  |         instanceList.append(instance); | 
					
						
							|  |  |  |         instance.internalObject()->installEventFilter(childrenChangeEventFilter()); | 
					
						
							|  |  |  |         if (instanceContainer.instanceId() == 0) { | 
					
						
							|  |  |  |             m_rootNodeInstance = instance; | 
					
						
							| 
									
										
										
										
											2014-04-16 12:21:56 +02:00
										 |  |  |             if (quickView()) | 
					
						
							|  |  |  |                 quickView()->setContent(fileUrl(), m_importComponent, m_rootNodeInstance.rootQuickItem()); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |             resizeCanvasSizeToRootItemSize(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach (QQmlContext* context, allSubContextsForObject(instance.internalObject())) | 
					
						
							|  |  |  |             setupDummysForContext(context); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return instanceList; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::createInstances(const CreateInstancesCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     createInstances(command.instances()); | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ServerNodeInstance NodeInstanceServer::instanceForId(qint32 id) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (id < 0) | 
					
						
							|  |  |  |         return ServerNodeInstance(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Q_ASSERT(m_idInstanceHash.contains(id)); | 
					
						
							|  |  |  |     return m_idInstanceHash.value(id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool NodeInstanceServer::hasInstanceForId(qint32 id) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (id < 0) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:59:17 +02:00
										 |  |  |     return m_idInstanceHash.contains(id) && m_idInstanceHash.value(id).isValid(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ServerNodeInstance NodeInstanceServer::instanceForObject(QObject *object) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_ASSERT(m_objectInstanceHash.contains(object)); | 
					
						
							|  |  |  |     return m_objectInstanceHash.value(object); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool NodeInstanceServer::hasInstanceForObject(QObject *object) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-19 14:12:06 +02:00
										 |  |  |     if (object == nullptr) | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:59:17 +02:00
										 |  |  |     return m_objectInstanceHash.contains(object) && m_objectInstanceHash.value(object).isValid(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setRenderTimerInterval(int timerInterval) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_renderTimerInterval = timerInterval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setSlowRenderTimerInterval(int timerInterval) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_slowRenderTimerInterval = timerInterval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setTimerId(int timerId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_timer = timerId; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int NodeInstanceServer::timerId() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_timer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int NodeInstanceServer::renderTimerInterval() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_renderTimerInterval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::startRenderTimer() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_slowRenderTimer) | 
					
						
							|  |  |  |         stopRenderTimer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_timer == 0) | 
					
						
							|  |  |  |         m_timer = startTimer(m_renderTimerInterval); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_slowRenderTimer = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::slowDownRenderTimer() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_slowRenderTimer) | 
					
						
							|  |  |  |         stopRenderTimer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_timer != 0) { | 
					
						
							|  |  |  |         killTimer(m_timer); | 
					
						
							|  |  |  |         m_timer = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_timer == 0) | 
					
						
							|  |  |  |         m_timer = startTimer(m_slowRenderTimerInterval); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_slowRenderTimer = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::stopRenderTimer() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_timer) { | 
					
						
							|  |  |  |         killTimer(m_timer); | 
					
						
							|  |  |  |         m_timer = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::createScene(const CreateSceneCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |     initializeView(); | 
					
						
							| 
									
										
										
										
											2015-05-19 15:04:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Internal::QmlPrivateGate::stopUnifiedTimer(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-09 14:50:13 +01:00
										 |  |  |     setupScene(command); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     refreshBindings(); | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::clearScene(const ClearSceneCommand &/*command*/) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     stopRenderTimer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     removeAllInstanceRelationships(); | 
					
						
							|  |  |  |     m_fileSystemWatcherHash.clear(); | 
					
						
							|  |  |  |     m_rootNodeInstance.makeInvalid(); | 
					
						
							|  |  |  |     m_changedPropertyList.clear(); | 
					
						
							|  |  |  |     m_fileUrl.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ServerNodeInstance oldState = activeStateInstance(); | 
					
						
							|  |  |  |     if (activeStateInstance().isValid()) | 
					
						
							|  |  |  |         activeStateInstance().deactivateState(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (qint32 instanceId, command.instanceIds()) { | 
					
						
							|  |  |  |         removeInstanceRelationsip(instanceId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (oldState.isValid()) | 
					
						
							|  |  |  |         oldState.activateState(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     refreshBindings(); | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::removeProperties(const RemovePropertiesCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     bool hasDynamicProperties = false; | 
					
						
							|  |  |  |     foreach (const PropertyAbstractContainer &container, command.properties()) { | 
					
						
							|  |  |  |         hasDynamicProperties |= container.isDynamic(); | 
					
						
							|  |  |  |         resetInstanceProperty(container); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (hasDynamicProperties) | 
					
						
							|  |  |  |         refreshBindings(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::reparentInstances(const QVector<ReparentContainer> &containerVector) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (const ReparentContainer &container, containerVector) { | 
					
						
							| 
									
										
										
										
											2014-06-17 14:23:33 +02:00
										 |  |  |         if (hasInstanceForId(container.instanceId())) { | 
					
						
							|  |  |  |             ServerNodeInstance instance = instanceForId(container.instanceId()); | 
					
						
							|  |  |  |             if (instance.isValid()) { | 
					
						
							|  |  |  |                 instance.reparent(instanceForId(container.oldParentInstanceId()), container.oldParentProperty(), instanceForId(container.newParentInstanceId()), container.newParentProperty()); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     reparentInstances(command.reparentInstances()); | 
					
						
							|  |  |  |     refreshBindings(); | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::changeState(const ChangeStateCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (hasInstanceForId(command.stateInstanceId())) { | 
					
						
							|  |  |  |         if (activeStateInstance().isValid()) | 
					
						
							|  |  |  |             activeStateInstance().deactivateState(); | 
					
						
							|  |  |  |         ServerNodeInstance instance = instanceForId(command.stateInstanceId()); | 
					
						
							|  |  |  |         instance.activateState(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         if (activeStateInstance().isValid()) | 
					
						
							|  |  |  |             activeStateInstance().deactivateState(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::completeComponent(const CompleteComponentCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<ServerNodeInstance> instanceList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (qint32 instanceId, command.instances()) { | 
					
						
							|  |  |  |         if (hasInstanceForId(instanceId)) { | 
					
						
							|  |  |  |             ServerNodeInstance instance = instanceForId(instanceId); | 
					
						
							|  |  |  |             instance.doComponentComplete(); | 
					
						
							|  |  |  |             instanceList.append(instance); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::changeNodeSource(const ChangeNodeSourceCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (hasInstanceForId(command.instanceId())) { | 
					
						
							|  |  |  |         ServerNodeInstance instance = instanceForId(command.instanceId()); | 
					
						
							|  |  |  |         if (instance.isValid()) | 
					
						
							|  |  |  |             instance.setNodeSource(command.nodeSource()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::token(const TokenCommand &/*command*/) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::removeSharedMemory(const RemoveSharedMemoryCommand &/*command*/) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 11:46:27 +01:00
										 |  |  | void NodeInstanceServer::setupImports(const QVector<AddImportContainer> &containerVector) | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |     Q_ASSERT(quickView()); | 
					
						
							|  |  |  |     QSet<QString> importStatementSet; | 
					
						
							| 
									
										
										
										
											2016-11-21 18:23:56 +01:00
										 |  |  |     QString qtQuickImport; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     foreach (const AddImportContainer &container, containerVector) { | 
					
						
							|  |  |  |         QString importStatement = QString("import "); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!container.fileName().isEmpty()) | 
					
						
							|  |  |  |             importStatement += '"' + container.fileName() + '"'; | 
					
						
							|  |  |  |         else if (!container.url().isEmpty()) | 
					
						
							|  |  |  |             importStatement += container.url().toString(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!container.version().isEmpty()) | 
					
						
							|  |  |  |             importStatement += ' ' + container.version(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!container.alias().isEmpty()) | 
					
						
							|  |  |  |             importStatement += " as " + container.alias(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 16:16:57 +01:00
										 |  |  |         if (importStatement.startsWith(QLatin1String("import QtQuick") + QChar(QChar::Space))) | 
					
						
							| 
									
										
										
										
											2016-11-21 18:23:56 +01:00
										 |  |  |             qtQuickImport = importStatement; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             importStatementSet.insert(importStatement); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     delete m_importComponent.data(); | 
					
						
							|  |  |  |     delete m_importComponentObject.data(); | 
					
						
							| 
									
										
										
										
											2019-07-31 12:31:51 +02:00
										 |  |  |     const QStringList importStatementList = QtHelpers::toList(importStatementSet); | 
					
						
							| 
									
										
										
										
											2016-11-21 18:23:56 +01:00
										 |  |  |     const QStringList fullImportStatementList(QStringList(qtQuickImport) + importStatementList); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |     // check possible import statements combinations
 | 
					
						
							| 
									
										
										
										
											2016-10-05 12:14:42 +02:00
										 |  |  |     // but first try the current order -> maybe it just works
 | 
					
						
							| 
									
										
										
										
											2016-11-21 18:23:56 +01:00
										 |  |  |     if (testImportStatements(fullImportStatementList, fileUrl())) { | 
					
						
							|  |  |  |         setupOnlyWorkingImports(fullImportStatementList); | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2016-10-05 12:14:42 +02:00
										 |  |  |         QString errorMessage; | 
					
						
							| 
									
										
										
										
											2016-11-21 18:23:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!testImportStatements(QStringList(qtQuickImport), fileUrl(), &errorMessage)) | 
					
						
							|  |  |  |             qtQuickImport = "import QtQuick 2.0"; | 
					
						
							|  |  |  |         if (testImportStatements(QStringList(qtQuickImport), fileUrl(), &errorMessage)) { | 
					
						
							|  |  |  |             QStringList workingImportStatementList; | 
					
						
							|  |  |  |             QStringList failedImportList; | 
					
						
							|  |  |  |             sortFilterImports(QStringList(qtQuickImport) + importStatementList, &workingImportStatementList, | 
					
						
							|  |  |  |                 &failedImportList, fileUrl(), &errorMessage); | 
					
						
							|  |  |  |             setupOnlyWorkingImports(workingImportStatementList); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-10-05 12:14:42 +02:00
										 |  |  |         if (!errorMessage.isEmpty()) | 
					
						
							|  |  |  |             sendDebugOutput(DebugOutputCommand::WarningType, errorMessage); | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-10-10 15:57:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  | void NodeInstanceServer::setupOnlyWorkingImports(const QStringList &workingImportStatementList) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-10-10 10:08:24 +02:00
										 |  |  |     QByteArray componentCode = workingImportStatementList.join("\n").toUtf8().append("\n"); | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |     m_importCode = componentCode; | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |     m_importComponent = new QQmlComponent(engine(), quickView()); | 
					
						
							|  |  |  |     quickView()->setContent(fileUrl(), m_importComponent, quickView()->rootObject()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_importComponent->setData(componentCode.append("\nItem {}\n"), fileUrl()); | 
					
						
							|  |  |  |     m_importComponentObject = m_importComponent->create(); | 
					
						
							| 
									
										
										
										
											2015-02-26 17:30:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |     Q_ASSERT(m_importComponent && m_importComponentObject); | 
					
						
							|  |  |  |     Q_ASSERT_X(m_importComponent->errors().isEmpty(), __FUNCTION__, m_importComponent->errorString().toLatin1()); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setupFileUrl(const QUrl &fileUrl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!fileUrl.isEmpty()) { | 
					
						
							|  |  |  |         engine()->setBaseUrl(fileUrl); | 
					
						
							|  |  |  |         m_fileUrl = fileUrl; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setupDummyData(const QUrl &fileUrl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!fileUrl.isEmpty()) { | 
					
						
							|  |  |  |         QStringList dummyDataDirectoryList = dummyDataDirectories(QFileInfo(fileUrl.toLocalFile()).path()); | 
					
						
							|  |  |  |         foreach (const QString &dummyDataDirectory, dummyDataDirectoryList) { | 
					
						
							|  |  |  |             loadDummyDataFiles(dummyDataDirectory); | 
					
						
							|  |  |  |             loadDummyDataContext(dummyDataDirectory); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_dummyContextObject.isNull()) | 
					
						
							|  |  |  |         setupDefaultDummyData(); | 
					
						
							| 
									
										
										
										
											2016-02-10 11:24:46 +01:00
										 |  |  |     rootContext()->setContextObject(m_dummyContextObject); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setupDefaultDummyData() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QQmlComponent component(engine()); | 
					
						
							| 
									
										
										
										
											2014-10-10 10:08:24 +02:00
										 |  |  |     QByteArray defaultContextObjectArray("import QtQml 2.0\n" | 
					
						
							|  |  |  |                                          "import QmlDesigner 1.0\n" | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |                                          "DummyContextObject {\n" | 
					
						
							|  |  |  |                                          "    parent: QtObject {\n" | 
					
						
							|  |  |  |                                          "        property real width: 360\n" | 
					
						
							|  |  |  |                                          "        property real height: 640\n" | 
					
						
							|  |  |  |                                          "    }\n" | 
					
						
							|  |  |  |                                          "}\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     component.setData(defaultContextObjectArray, fileUrl()); | 
					
						
							|  |  |  |     m_dummyContextObject = component.create(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (component.isError()) { | 
					
						
							|  |  |  |         QList<QQmlError> errors = component.errors(); | 
					
						
							|  |  |  |         foreach (const QQmlError &error, errors) { | 
					
						
							|  |  |  |             qWarning() << error; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_dummyContextObject) { | 
					
						
							| 
									
										
										
										
											2014-10-09 13:35:12 +02:00
										 |  |  |         qDebug() << "Loaded default dummy context object."; | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         m_dummyContextObject->setParent(this); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     refreshBindings(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-09 13:28:32 +02:00
										 |  |  | QList<ServerNodeInstance> NodeInstanceServer::setupInstances(const CreateSceneCommand &command) | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QList<ServerNodeInstance> instanceList = createInstances(command.instances()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const IdContainer &container, command.ids()) { | 
					
						
							|  |  |  |         if (hasInstanceForId(container.instanceId())) | 
					
						
							|  |  |  |             instanceForId(container.instanceId()).setId(container.id()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const PropertyValueContainer &container, command.valueChanges()) { | 
					
						
							|  |  |  |         if (container.isDynamic()) | 
					
						
							|  |  |  |             setInstancePropertyVariant(container); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const PropertyValueContainer &container, command.valueChanges()) { | 
					
						
							|  |  |  |         if (!container.isDynamic()) | 
					
						
							|  |  |  |             setInstancePropertyVariant(container); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reparentInstances(command.reparentInstances()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const PropertyBindingContainer &container, command.bindingChanges()) { | 
					
						
							|  |  |  |         if (container.isDynamic()) | 
					
						
							|  |  |  |             setInstancePropertyBinding(container); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const PropertyBindingContainer &container, command.bindingChanges()) { | 
					
						
							|  |  |  |         if (!container.isDynamic()) | 
					
						
							|  |  |  |             setInstancePropertyBinding(container); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const PropertyValueContainer &container, command.auxiliaryChanges()) { | 
					
						
							|  |  |  |         setInstanceAuxiliaryData(container); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-24 13:43:54 +02:00
										 |  |  |     for (int i = instanceList.size(); --i >= 0; ) | 
					
						
							|  |  |  |         instanceList[i].doComponentComplete(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return instanceList; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::changeFileUrl(const ChangeFileUrlCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_fileUrl = command.fileUrl(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (engine()) | 
					
						
							|  |  |  |         engine()->setBaseUrl(m_fileUrl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     refreshBindings(); | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     bool hasDynamicProperties = false; | 
					
						
							|  |  |  |     foreach (const PropertyValueContainer &container, command.valueChanges()) { | 
					
						
							|  |  |  |         hasDynamicProperties |= container.isDynamic(); | 
					
						
							|  |  |  |         setInstancePropertyVariant(container); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (hasDynamicProperties) | 
					
						
							|  |  |  |         refreshBindings(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (const PropertyValueContainer &container, command.auxiliaryChanges()) { | 
					
						
							|  |  |  |         setInstanceAuxiliaryData(container); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::changePropertyBindings(const ChangeBindingsCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     bool hasDynamicProperties = false; | 
					
						
							|  |  |  |     foreach (const PropertyBindingContainer &container, command.bindingChanges()) { | 
					
						
							|  |  |  |         hasDynamicProperties |= container.isDynamic(); | 
					
						
							|  |  |  |         setInstancePropertyBinding(container); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (hasDynamicProperties) | 
					
						
							|  |  |  |         refreshBindings(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::changeIds(const ChangeIdsCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (const IdContainer &container, command.ids()) { | 
					
						
							|  |  |  |         if (hasInstanceForId(container.instanceId())) | 
					
						
							|  |  |  |             instanceForId(container.instanceId()).setId(container.id()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     refreshBindings(); | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QQmlContext *NodeInstanceServer::context() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_importComponentObject) { | 
					
						
							|  |  |  |         QQmlContext *importComponentContext = QQmlEngine::contextForObject(m_importComponentObject.data()); | 
					
						
							|  |  |  |         if (importComponentContext) // this should be the default
 | 
					
						
							|  |  |  |             return importComponentContext; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (engine()) | 
					
						
							|  |  |  |         return rootContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-19 14:12:06 +02:00
										 |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QQmlContext *NodeInstanceServer::rootContext() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return engine()->rootContext(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const QVector<NodeInstanceServer::InstancePropertyPair> NodeInstanceServer::changedPropertyList() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_changedPropertyList; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::clearChangedPropertyList() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_changedPropertyList.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setupDummysForContext(QQmlContext *context) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (const DummyPair& dummyPair, m_dummyObjectList) { | 
					
						
							|  |  |  |         if (dummyPair.second) { | 
					
						
							|  |  |  |             context->setContextProperty(dummyPair.first, dummyPair.second.data()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:19:36 +02:00
										 |  |  | static bool isTypeAvailable(const MockupTypeContainer &mockupType, QQmlEngine *engine) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QString qmlSource; | 
					
						
							|  |  |  |     qmlSource.append("import " + | 
					
						
							|  |  |  |                      mockupType.importUri() | 
					
						
							|  |  |  |                      + " " | 
					
						
							|  |  |  |                      + QString::number(mockupType.majorVersion()) | 
					
						
							|  |  |  |                      + "." + QString::number(mockupType.minorVersion()) | 
					
						
							|  |  |  |                      + "\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     qmlSource.append(QString::fromUtf8(mockupType.typeName()) + "{\n}\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QQmlComponent component(engine); | 
					
						
							|  |  |  |     component.setData(qmlSource.toUtf8(), QUrl()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return !component.isError(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 15:30:29 +02:00
										 |  |  | void NodeInstanceServer::setupMockupTypes(const QVector<MockupTypeContainer> &container) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (const MockupTypeContainer &mockupType :  container) { | 
					
						
							| 
									
										
										
										
											2016-10-25 15:19:36 +02:00
										 |  |  |         if (!isTypeAvailable(mockupType, engine())) | 
					
						
							| 
									
										
										
										
											2016-09-29 15:30:29 +02:00
										 |  |  | #if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:19:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             QQuickDesignerSupportMetaInfo::registerMockupObject(mockupType.importUri().toUtf8(), | 
					
						
							| 
									
										
										
										
											2016-09-29 15:30:29 +02:00
										 |  |  |                                                             mockupType.majorVersion(), | 
					
						
							|  |  |  |                                                             mockupType.minorVersion(), | 
					
						
							|  |  |  |                                                             mockupType.typeName()); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:19:36 +02:00
										 |  |  |             qmlRegisterType(QUrl("qrc:/qtquickplugin/mockfiles/GenericBackend.qml"), | 
					
						
							| 
									
										
										
										
											2016-09-29 15:30:29 +02:00
										 |  |  |                         mockupType.importUri().toUtf8(), | 
					
						
							|  |  |  |                         mockupType.majorVersion(), | 
					
						
							|  |  |  |                         mockupType.minorVersion(), | 
					
						
							|  |  |  |                         mockupType.typeName()); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | QList<QQmlContext*> NodeInstanceServer::allSubContextsForObject(QObject *object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<QQmlContext*> contextList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (object) { | 
					
						
							|  |  |  |         foreach (QObject *subObject, allSubObjectsForObject(object)) { | 
					
						
							|  |  |  |             QQmlContext *contextOfObject = QQmlEngine::contextForObject(subObject); | 
					
						
							|  |  |  |             if (contextOfObject) { | 
					
						
							|  |  |  |                 if (contextOfObject != context() && !contextList.contains(contextOfObject)) | 
					
						
							|  |  |  |                     contextList.append(contextOfObject); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return contextList; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QList<QObject*> NodeInstanceServer::allSubObjectsForObject(QObject *object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<QObject*> subChildren; | 
					
						
							|  |  |  |     if (object) { | 
					
						
							|  |  |  |         subChildren = object->findChildren<QObject*>(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return subChildren; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::removeAllInstanceRelationships() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // prevent destroyed() signals calling back
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (ServerNodeInstance instance, m_objectInstanceHash) { | 
					
						
							|  |  |  |         if (instance.isValid()) | 
					
						
							|  |  |  |             instance.setId(QString()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //first  the root object
 | 
					
						
							|  |  |  |     if (rootNodeInstance().internalObject()) | 
					
						
							|  |  |  |         rootNodeInstance().internalObject()->disconnect(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rootNodeInstance().makeInvalid(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (ServerNodeInstance instance, m_objectInstanceHash) { | 
					
						
							|  |  |  |         if (instance.internalObject()) | 
					
						
							|  |  |  |             instance.internalObject()->disconnect(); | 
					
						
							|  |  |  |         instance.makeInvalid(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_idInstanceHash.clear(); | 
					
						
							|  |  |  |     m_objectInstanceHash.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QFileSystemWatcher *NodeInstanceServer::dummydataFileSystemWatcher() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_dummdataFileSystemWatcher.isNull()) { | 
					
						
							|  |  |  |         m_dummdataFileSystemWatcher = new QFileSystemWatcher(this); | 
					
						
							| 
									
										
										
										
											2015-11-19 14:33:31 +01:00
										 |  |  |         connect(m_dummdataFileSystemWatcher.data(), &QFileSystemWatcher::fileChanged, this, &NodeInstanceServer::refreshDummyData); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return m_dummdataFileSystemWatcher.data(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QFileSystemWatcher *NodeInstanceServer::fileSystemWatcher() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_fileSystemWatcher.isNull()) { | 
					
						
							|  |  |  |         m_fileSystemWatcher = new QFileSystemWatcher(this); | 
					
						
							| 
									
										
										
										
											2015-11-19 14:33:31 +01:00
										 |  |  |         connect(m_fileSystemWatcher.data(), &QFileSystemWatcher::fileChanged, this, &NodeInstanceServer::refreshLocalFileProperty); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return m_fileSystemWatcher.data(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Internal::ChildrenChangeEventFilter *NodeInstanceServer::childrenChangeEventFilter() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_childrenChangeEventFilter.data(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  | void NodeInstanceServer::addFilePropertyToFileSystemWatcher(QObject *object, const PropertyName &propertyName, const QString &path) | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!m_fileSystemWatcherHash.contains(path)) { | 
					
						
							|  |  |  |         m_fileSystemWatcherHash.insert(path, ObjectPropertyPair(object, propertyName)); | 
					
						
							|  |  |  |         fileSystemWatcher()->addPath(path); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  | void NodeInstanceServer::removeFilePropertyFromFileSystemWatcher(QObject *object, const PropertyName &propertyName, const QString &path) | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (m_fileSystemWatcherHash.contains(path)) { | 
					
						
							|  |  |  |         fileSystemWatcher()->removePath(path); | 
					
						
							|  |  |  |         m_fileSystemWatcherHash.remove(path, ObjectPropertyPair(object, propertyName)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::refreshLocalFileProperty(const QString &path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_fileSystemWatcherHash.contains(path)) { | 
					
						
							|  |  |  |         foreach (const ObjectPropertyPair &objectPropertyPair, m_fileSystemWatcherHash) { | 
					
						
							|  |  |  |             QObject *object = objectPropertyPair.first.data(); | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |             PropertyName propertyName = objectPropertyPair.second; | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (hasInstanceForObject(object)) { | 
					
						
							|  |  |  |                 instanceForObject(object).refreshProperty(propertyName); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::refreshDummyData(const QString &path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     engine()->clearComponentCache(); | 
					
						
							|  |  |  |     QFileInfo filePath(path); | 
					
						
							|  |  |  |     if (filePath.completeBaseName().contains("_dummycontext")) { | 
					
						
							|  |  |  |         loadDummyContextObjectFile(filePath); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         loadDummyDataFile(filePath); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     refreshBindings(); | 
					
						
							|  |  |  |     startRenderTimer(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::addChangedProperty(const InstancePropertyPair &property) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_changedPropertyList.contains(property)) | 
					
						
							|  |  |  |         m_changedPropertyList.append(property); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::emitParentChanged(QObject *child) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (hasInstanceForObject(child)) { | 
					
						
							|  |  |  |         addChangedProperty(InstancePropertyPair(instanceForObject(child), "parent")); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Internal::ChildrenChangeEventFilter *NodeInstanceServer::childrenChangeEventFilter() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_childrenChangeEventFilter.isNull()) { | 
					
						
							|  |  |  |         m_childrenChangeEventFilter = new Internal::ChildrenChangeEventFilter(this); | 
					
						
							| 
									
										
										
										
											2015-11-19 14:33:31 +01:00
										 |  |  |         connect(m_childrenChangeEventFilter.data(), &Internal::ChildrenChangeEventFilter::childrenChanged, this, &NodeInstanceServer::emitParentChanged); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return m_childrenChangeEventFilter.data(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::resetInstanceProperty(const PropertyAbstractContainer &propertyContainer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (hasInstanceForId(propertyContainer.instanceId())) { // TODO ugly workaround
 | 
					
						
							|  |  |  |         ServerNodeInstance instance = instanceForId(propertyContainer.instanceId()); | 
					
						
							|  |  |  |         Q_ASSERT(instance.isValid()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |         const PropertyName name = propertyContainer.name(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) { | 
					
						
							|  |  |  |             bool statePropertyWasReseted = activeStateInstance().resetStateProperty(instance, name, instance.resetVariant(name)); | 
					
						
							|  |  |  |             if (!statePropertyWasReseted) | 
					
						
							|  |  |  |                 instance.resetProperty(name); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             instance.resetProperty(name); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (propertyContainer.isDynamic() && propertyContainer.instanceId() == 0 && engine()) | 
					
						
							| 
									
										
										
										
											2016-03-18 10:19:09 +01:00
										 |  |  |             rootContext()->setContextProperty(QString::fromUtf8(name), QVariant()); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setInstancePropertyBinding(const PropertyBindingContainer &bindingContainer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (hasInstanceForId(bindingContainer.instanceId())) { | 
					
						
							|  |  |  |         ServerNodeInstance instance = instanceForId(bindingContainer.instanceId()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |         const PropertyName name = bindingContainer.name(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         const QString expression = bindingContainer.expression(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) { | 
					
						
							|  |  |  |             bool stateBindingWasUpdated = activeStateInstance().updateStateBinding(instance, name, expression); | 
					
						
							|  |  |  |             if (!stateBindingWasUpdated) { | 
					
						
							|  |  |  |                 if (bindingContainer.isDynamic()) | 
					
						
							| 
									
										
										
										
											2016-03-18 10:19:09 +01:00
										 |  |  |                     Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(), engine(), | 
					
						
							|  |  |  |                                                                        QString::fromUtf8(name)); | 
					
						
							| 
									
										
										
										
											2015-05-18 14:43:44 +02:00
										 |  |  |                 instance.setPropertyBinding(name, expression); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             if (bindingContainer.isDynamic()) | 
					
						
							| 
									
										
										
										
											2016-03-18 10:19:09 +01:00
										 |  |  |                 Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(), engine(), | 
					
						
							|  |  |  |                                                                    QString::fromUtf8(name)); | 
					
						
							| 
									
										
										
										
											2015-05-18 14:43:44 +02:00
										 |  |  |             instance.setPropertyBinding(name, expression); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::removeProperties(const QList<PropertyAbstractContainer> &propertyList) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (const PropertyAbstractContainer &property, propertyList) | 
					
						
							|  |  |  |         resetInstanceProperty(property); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setInstancePropertyVariant(const PropertyValueContainer &valueContainer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (hasInstanceForId(valueContainer.instanceId())) { | 
					
						
							|  |  |  |         ServerNodeInstance instance = instanceForId(valueContainer.instanceId()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |         const PropertyName name = valueContainer.name(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         const QVariant value = valueContainer.value(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) { | 
					
						
							|  |  |  |             bool stateValueWasUpdated = activeStateInstance().updateStateVariant(instance, name, value); | 
					
						
							|  |  |  |             if (!stateValueWasUpdated) { | 
					
						
							|  |  |  |                 if (valueContainer.isDynamic()) | 
					
						
							| 
									
										
										
										
											2016-03-18 10:19:09 +01:00
										 |  |  |                     Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(), engine(), QString::fromUtf8(name)); | 
					
						
							| 
									
										
										
										
											2015-05-18 14:43:44 +02:00
										 |  |  |                 instance.setPropertyVariant(name, value); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } else { //base state
 | 
					
						
							|  |  |  |             if (valueContainer.isDynamic()) | 
					
						
							| 
									
										
										
										
											2016-03-18 10:19:09 +01:00
										 |  |  |                 Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(), engine(), QString::fromUtf8(name)); | 
					
						
							| 
									
										
										
										
											2015-05-18 14:43:44 +02:00
										 |  |  |             instance.setPropertyVariant(name, value); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (valueContainer.isDynamic() && valueContainer.instanceId() == 0 && engine()) | 
					
						
							| 
									
										
										
										
											2016-03-18 10:19:09 +01:00
										 |  |  |             rootContext()->setContextProperty(QString::fromUtf8(name), Internal::QmlPrivateGate::fixResourcePaths(value)); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setInstanceAuxiliaryData(const PropertyValueContainer &auxiliaryContainer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     //instanceId() == 0: the item is root
 | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |     if (auxiliaryContainer.instanceId() == 0 && (auxiliaryContainer.name() == "width" || | 
					
						
							|  |  |  |                                         auxiliaryContainer.name() == "height")) { | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!auxiliaryContainer.value().isNull()) { | 
					
						
							|  |  |  |             setInstancePropertyVariant(auxiliaryContainer); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             rootNodeInstance().resetProperty(auxiliaryContainer.name()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |     if (auxiliaryContainer.name().endsWith("@NodeInstance")) { | 
					
						
							| 
									
										
										
										
											2017-09-20 13:28:22 +02:00
										 |  |  |         PropertyName propertyName = auxiliaryContainer.name().left(auxiliaryContainer.name().count() - 13); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         if (!auxiliaryContainer.value().isNull()) { | 
					
						
							|  |  |  |             setInstancePropertyVariant(PropertyValueContainer(auxiliaryContainer.instanceId(), | 
					
						
							|  |  |  |                                                               propertyName, | 
					
						
							|  |  |  |                                                               auxiliaryContainer.value(), | 
					
						
							|  |  |  |                                                               auxiliaryContainer.dynamicTypeName())); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             rootNodeInstance().resetProperty(propertyName); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QUrl NodeInstanceServer::fileUrl() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_fileUrl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ServerNodeInstance NodeInstanceServer::activeStateInstance() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_activeStateInstance; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ServerNodeInstance NodeInstanceServer::rootNodeInstance() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_rootNodeInstance; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::setStateInstance(const ServerNodeInstance &stateInstance) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_activeStateInstance = stateInstance; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::clearStateInstance() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_activeStateInstance = ServerNodeInstance(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::timerEvent(QTimerEvent *event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (event->timerId() == m_timer) { | 
					
						
							|  |  |  |         collectItemChangesAndSendChangeCommands(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NodeInstanceServerInterface::timerEvent(event); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NodeInstanceClientInterface *NodeInstanceServer::nodeInstanceClient() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_nodeInstanceClient; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static QVector<InformationContainer> createInformationVector(const QList<ServerNodeInstance> &instanceList, bool initial) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QVector<InformationContainer> informationVector; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const ServerNodeInstance &instance, instanceList) { | 
					
						
							| 
									
										
										
										
											2014-06-17 14:28:48 +02:00
										 |  |  |         if (instance.isValid()) { | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Position, instance.position())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Transform, instance.transform())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), SceneTransform, instance.sceneTransform())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Size, instance.size())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), BoundingRect, instance.boundingRect())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), ContentItemBoundingRect, instance.contentItemBoundingRect())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Transform, instance.transform())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), ContentTransform, instance.contentTransform())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), ContentItemTransform, instance.contentItemTransform())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasContent, instance.hasContent())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), IsMovable, instance.isMovable())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), IsResizable, instance.isResizable())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), IsInLayoutable, instance.isInLayoutable())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), PenWidth, instance.penWidth())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), IsAnchoredByChildren, instance.isAnchoredByChildren())); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), IsAnchoredBySibling, instance.isAnchoredBySibling())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, PropertyName("anchors.fill"), instance.hasAnchor("anchors.fill"))); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, PropertyName("anchors.centerIn"), instance.hasAnchor("anchors.centerIn"))); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, PropertyName("anchors.right"), instance.hasAnchor("anchors.right"))); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, PropertyName("anchors.top"), instance.hasAnchor("anchors.top"))); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, PropertyName("anchors.left"), instance.hasAnchor("anchors.left"))); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, PropertyName("anchors.bottom"), instance.hasAnchor("anchors.bottom"))); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, PropertyName("anchors.horizontalCenter"), instance.hasAnchor("anchors.horizontalCenter"))); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, PropertyName("anchors.verticalCenter"), instance.hasAnchor("anchors.verticalCenter"))); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, PropertyName("anchors.baseline"), instance.hasAnchor("anchors.baseline"))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QPair<PropertyName, ServerNodeInstance> anchorPair = instance.anchor("anchors.fill"); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Anchor, PropertyName("anchors.fill"), anchorPair.first, anchorPair.second.instanceId())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             anchorPair = instance.anchor("anchors.centerIn"); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Anchor, PropertyName("anchors.centerIn"), anchorPair.first, anchorPair.second.instanceId())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             anchorPair = instance.anchor("anchors.right"); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Anchor, PropertyName("anchors.right"), anchorPair.first, anchorPair.second.instanceId())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             anchorPair = instance.anchor("anchors.top"); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Anchor, PropertyName("anchors.top"), anchorPair.first, anchorPair.second.instanceId())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             anchorPair = instance.anchor("anchors.left"); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Anchor, PropertyName("anchors.left"), anchorPair.first, anchorPair.second.instanceId())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             anchorPair = instance.anchor("anchors.bottom"); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Anchor, PropertyName("anchors.bottom"), anchorPair.first, anchorPair.second.instanceId())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             anchorPair = instance.anchor("anchors.horizontalCenter"); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Anchor, PropertyName("anchors.horizontalCenter"), anchorPair.first, anchorPair.second.instanceId())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             anchorPair = instance.anchor("anchors.verticalCenter"); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Anchor, PropertyName("anchors.verticalCenter"), anchorPair.first, anchorPair.second.instanceId())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             anchorPair = instance.anchor("anchors.baseline"); | 
					
						
							|  |  |  |             informationVector.append(InformationContainer(instance.instanceId(), Anchor, PropertyName("anchors.baseline"), anchorPair.first, anchorPair.second.instanceId())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             PropertyNameList propertyNames = instance.propertyNames(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (initial) { | 
					
						
							|  |  |  |                 foreach (const PropertyName &propertyName,propertyNames) | 
					
						
							|  |  |  |                     informationVector.append(InformationContainer(instance.instanceId(), InstanceTypeForProperty, propertyName, instance.instanceType(propertyName))); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:28:48 +02:00
										 |  |  |             foreach (const PropertyName &propertyName,instance.propertyNames()) { | 
					
						
							|  |  |  |                 bool hasChanged = false; | 
					
						
							|  |  |  |                 bool hasBinding = instance.hasBindingForProperty(propertyName, &hasChanged); | 
					
						
							|  |  |  |                 if (hasChanged) | 
					
						
							|  |  |  |                     informationVector.append(InformationContainer(instance.instanceId(), HasBindingForProperty, propertyName, hasBinding)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return informationVector; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ChildrenChangedCommand NodeInstanceServer::createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QVector<qint32> instanceVector; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const ServerNodeInstance &instance, instanceList) | 
					
						
							|  |  |  |         instanceVector.append(instance.instanceId()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ChildrenChangedCommand(parentInstance.instanceId(), instanceVector, createInformationVector(instanceList, false)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | InformationChangedCommand NodeInstanceServer::createAllInformationChangedCommand(const QList<ServerNodeInstance> &instanceList, bool initial) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return InformationChangedCommand(createInformationVector(instanceList, initial)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-24 17:01:37 +02:00
										 |  |  | static bool supportedVariantType(int type) | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-04-06 12:21:42 +02:00
										 |  |  |     return type < int(QVariant::UserType) && type != QMetaType::QObjectStar | 
					
						
							| 
									
										
										
										
											2016-04-21 11:39:20 +02:00
										 |  |  |             && type != QMetaType::QModelIndex && type != QMetaType::VoidStar; | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QList<ServerNodeInstance> &instanceList) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QVector<PropertyValueContainer> valueVector; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const ServerNodeInstance &instance, instanceList) { | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |         foreach (const PropertyName &propertyName, instance.propertyNames()) { | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |             QVariant propertyValue = instance.property(propertyName); | 
					
						
							| 
									
										
										
										
											2012-09-24 17:01:37 +02:00
										 |  |  |             if (supportedVariantType(propertyValue.userType())) | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |                 valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName, propertyValue, PropertyName())); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ValuesChangedCommand(valueVector); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ComponentCompletedCommand NodeInstanceServer::createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QVector<qint32> idVector; | 
					
						
							|  |  |  |     foreach (const ServerNodeInstance &instance, instanceList) { | 
					
						
							|  |  |  |         if (instance.instanceId() >= 0) | 
					
						
							|  |  |  |             idVector.append(instance.instanceId()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ComponentCompletedCommand(idVector); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QVector<PropertyValueContainer> valueVector; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const InstancePropertyPair &property, propertyList) { | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |         const PropertyName propertyName = property.second; | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         const ServerNodeInstance instance = property.first; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-24 17:01:59 +02:00
										 |  |  |         if (instance.isValid()) { | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |             QVariant propertyValue = instance.property(propertyName); | 
					
						
							| 
									
										
										
										
											2012-09-24 17:01:37 +02:00
										 |  |  |             if (QMetaType::isRegistered(propertyValue.userType()) && supportedVariantType(propertyValue.type())) { | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  |                 valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName, propertyValue, PropertyName())); | 
					
						
							| 
									
										
										
										
											2012-09-24 17:01:37 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ValuesChangedCommand(valueVector); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  | QByteArray NodeInstanceServer::importCode() const | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-09-25 12:57:57 +02:00
										 |  |  |     return m_importCode; | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QObject *NodeInstanceServer::dummyContextObject() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_dummyContextObject.data(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 12:19:19 +01:00
										 |  |  | void NodeInstanceServer::notifyPropertyChange(qint32 instanceid, const PropertyName &propertyName) | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (hasInstanceForId(instanceid)) | 
					
						
							|  |  |  |         addChangedProperty(InstancePropertyPair(instanceForId(instanceid), propertyName)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::insertInstanceRelationship(const ServerNodeInstance &instance) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_ASSERT(instance.isValid()); | 
					
						
							|  |  |  |     Q_ASSERT(!m_idInstanceHash.contains(instance.instanceId())); | 
					
						
							|  |  |  |     Q_ASSERT(!m_objectInstanceHash.contains(instance.internalObject())); | 
					
						
							|  |  |  |     m_objectInstanceHash.insert(instance.internalObject(), instance); | 
					
						
							|  |  |  |     m_idInstanceHash.insert(instance.instanceId(), instance); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::removeInstanceRelationsip(qint32 instanceId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (hasInstanceForId(instanceId)) { | 
					
						
							|  |  |  |         ServerNodeInstance instance = instanceForId(instanceId); | 
					
						
							|  |  |  |         if (instance.isValid()) | 
					
						
							|  |  |  |             instance.setId(QString()); | 
					
						
							|  |  |  |         m_idInstanceHash.remove(instanceId); | 
					
						
							|  |  |  |         m_objectInstanceHash.remove(instance.internalObject()); | 
					
						
							|  |  |  |         instance.makeInvalid(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PixmapChangedCommand NodeInstanceServer::createPixmapChangedCommand(const QList<ServerNodeInstance> &instanceList) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QVector<ImageContainer> imageVector; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const ServerNodeInstance &instance, instanceList) { | 
					
						
							|  |  |  |         if (instance.isValid() && instance.hasContent()) | 
					
						
							|  |  |  |             imageVector.append(ImageContainer(instance.instanceId(), instance.renderImage(), instance.instanceId())); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PixmapChangedCommand(imageVector); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::loadDummyDataFile(const QFileInfo& qmlFileInfo) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QQmlComponent component(engine(), qmlFileInfo.filePath()); | 
					
						
							|  |  |  |     QObject *dummyData = component.create(); | 
					
						
							|  |  |  |     if (component.isError()) { | 
					
						
							|  |  |  |         QList<QQmlError> errors = component.errors(); | 
					
						
							|  |  |  |         foreach (const QQmlError &error, errors) { | 
					
						
							|  |  |  |             qWarning() << error; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVariant oldDummyDataObject = rootContext()->contextProperty(qmlFileInfo.completeBaseName()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dummyData) { | 
					
						
							| 
									
										
										
										
											2014-10-09 13:35:12 +02:00
										 |  |  |         qDebug() << "Loaded dummy data:" << qmlFileInfo.filePath(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |         rootContext()->setContextProperty(qmlFileInfo.completeBaseName(), dummyData); | 
					
						
							|  |  |  |         dummyData->setParent(this); | 
					
						
							|  |  |  |         m_dummyObjectList.append(DummyPair(qmlFileInfo.completeBaseName(), dummyData)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!oldDummyDataObject.isNull()) | 
					
						
							|  |  |  |         delete oldDummyDataObject.value<QObject*>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!dummydataFileSystemWatcher()->files().contains(qmlFileInfo.filePath())) | 
					
						
							|  |  |  |         dummydataFileSystemWatcher()->addPath(qmlFileInfo.filePath()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rootNodeInstance().isValid() && rootNodeInstance().internalObject()) { | 
					
						
							|  |  |  |         foreach (QQmlContext *context, allSubContextsForObject(rootNodeInstance().internalObject())) | 
					
						
							|  |  |  |             setupDummysForContext(context); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::loadDummyContextObjectFile(const QFileInfo& qmlFileInfo) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     delete m_dummyContextObject.data(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QQmlComponent component(engine(), qmlFileInfo.filePath()); | 
					
						
							|  |  |  |     m_dummyContextObject = component.create(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (component.isError()) { | 
					
						
							|  |  |  |         QList<QQmlError> errors = component.errors(); | 
					
						
							|  |  |  |         foreach (const QQmlError &error, errors) { | 
					
						
							|  |  |  |             qWarning() << error; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_dummyContextObject) { | 
					
						
							|  |  |  |         qWarning() << "Loaded dummy context object:" << qmlFileInfo.filePath(); | 
					
						
							|  |  |  |         m_dummyContextObject->setParent(this); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!dummydataFileSystemWatcher()->files().contains(qmlFileInfo.filePath())) | 
					
						
							|  |  |  |         dummydataFileSystemWatcher()->addPath(qmlFileInfo.filePath()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     refreshBindings(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::loadDummyDataFiles(const QString& directory) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QDir dir(directory, "*.qml"); | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:56 +02:00
										 |  |  |     QFileInfoList filePathList = dir.entryInfoList(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     foreach (const QFileInfo &qmlFileInfo, filePathList) { | 
					
						
							|  |  |  |         loadDummyDataFile(qmlFileInfo); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::loadDummyDataContext(const QString& directory) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QDir dir(directory+"/context", "*.qml"); | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:56 +02:00
										 |  |  |     QFileInfoList filePathList = dir.entryInfoList(); | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  |     QString baseName = QFileInfo(fileUrl().toLocalFile()).completeBaseName(); | 
					
						
							|  |  |  |     foreach (const QFileInfo &qmlFileInfo, filePathList) { | 
					
						
							|  |  |  |         if (qmlFileInfo.completeBaseName() == baseName) | 
					
						
							|  |  |  |             loadDummyContextObjectFile(qmlFileInfo); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-18 13:32:35 +01:00
										 |  |  | void NodeInstanceServer::sendDebugOutput(DebugOutputCommand::Type type, const QString &message, qint32 instanceId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QVector<qint32> ids; | 
					
						
							|  |  |  |     ids.append(instanceId); | 
					
						
							|  |  |  |     sendDebugOutput(type, message, ids); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodeInstanceServer::sendDebugOutput(DebugOutputCommand::Type type, const QString &message, const QVector<qint32> &instanceIds) | 
					
						
							| 
									
										
										
										
											2012-11-21 15:26:27 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-02-18 13:32:35 +01:00
										 |  |  |     DebugOutputCommand command(message, type, instanceIds); | 
					
						
							| 
									
										
										
										
											2012-11-21 15:26:27 +01:00
										 |  |  |     nodeInstanceClient()->debugOutput(command); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-23 11:28:23 +01:00
										 |  |  | void NodeInstanceServer::removeInstanceRelationsipForDeletedObject(QObject *object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_objectInstanceHash.contains(object)) { | 
					
						
							|  |  |  |         ServerNodeInstance instance = instanceForObject(object); | 
					
						
							|  |  |  |         m_objectInstanceHash.remove(object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_idInstanceHash.contains(instance.instanceId())) | 
					
						
							|  |  |  |             m_idInstanceHash.remove(instance.instanceId()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-19 15:57:22 +02:00
										 |  |  | QStringList NodeInstanceServer::dummyDataDirectories(const QString& directoryPath) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QStringList dummyDataDirectoryList; | 
					
						
							|  |  |  |     QDir directory(directoryPath); | 
					
						
							|  |  |  |     while (true) { | 
					
						
							|  |  |  |         if (directory.isRoot() || !directory.exists()) | 
					
						
							|  |  |  |             return dummyDataDirectoryList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (directory.exists("dummydata")) | 
					
						
							|  |  |  |             dummyDataDirectoryList.prepend(directory.absoluteFilePath("dummydata")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         directory.cdUp(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |