forked from qt-creator/qt-creator
		
	Conflicts: src/libs/utils/ipaddresslineedit.cpp src/libs/utils/logging.h src/plugins/analyzerbase/AnalyzerBase.pluginspec.in src/plugins/android/Android.pluginspec.in src/plugins/android/androiddeploystep.cpp src/plugins/android/androiddeploystep.h src/plugins/android/androiddeploystepfactory.cpp src/plugins/android/androiddeploystepwidget.cpp src/plugins/android/androidpackagecreationfactory.cpp src/plugins/android/androidpackagecreationstep.cpp src/plugins/android/androidpackagecreationstep.h src/plugins/android/androidpackagecreationwidget.cpp src/plugins/android/androidpackagecreationwidget.h src/plugins/android/javafilewizard.cpp src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in src/plugins/baremetal/BareMetal.pluginspec.in src/plugins/bazaar/Bazaar.pluginspec.in src/plugins/beautifier/Beautifier.pluginspec.in src/plugins/bineditor/BinEditor.pluginspec.in src/plugins/bookmarks/Bookmarks.pluginspec.in src/plugins/clangcodemodel/ClangCodeModel.pluginspec.in src/plugins/clangcodemodel/clanghighlightingsupport.cpp src/plugins/clangcodemodel/clangsymbolsearcher.cpp src/plugins/classview/ClassView.pluginspec.in src/plugins/clearcase/ClearCase.pluginspec.in src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec.in src/plugins/cmakeprojectmanager/cmakeeditorfactory.cpp src/plugins/cmakeprojectmanager/cmakehighlighter.cpp src/plugins/coreplugin/Core.pluginspec.in src/plugins/cpaster/CodePaster.pluginspec.in src/plugins/cppeditor/CppEditor.pluginspec.in src/plugins/cppeditor/cppfilewizard.cpp src/plugins/cpptools/CppTools.pluginspec.in src/plugins/cpptools/cpphighlightingsupportinternal.cpp src/plugins/cpptools/cppmodelmanagerinterface.cpp src/plugins/cpptools/cppmodelmanagerinterface.h src/plugins/cvs/CVS.pluginspec.in src/plugins/debugger/Debugger.pluginspec.in src/plugins/designer/Designer.pluginspec.in src/plugins/diffeditor/DiffEditor.pluginspec.in src/plugins/emacskeys/EmacsKeys.pluginspec.in src/plugins/fakevim/FakeVim.pluginspec.in src/plugins/genericprojectmanager/GenericProjectManager.pluginspec.in src/plugins/git/Git.pluginspec.in src/plugins/git/gitorious/gitorious.cpp src/plugins/git/gitorious/gitorious.h src/plugins/git/gitorious/gitoriousclonewizard.cpp src/plugins/git/gitorious/gitorioushostwidget.cpp src/plugins/git/gitorious/gitorioushostwidget.h src/plugins/git/gitorious/gitorioushostwizardpage.cpp src/plugins/git/gitorious/gitoriousprojectwidget.cpp src/plugins/git/gitorious/gitoriousprojectwidget.h src/plugins/git/gitorious/gitoriousprojectwizardpage.cpp src/plugins/git/gitorious/gitoriousprojectwizardpage.h src/plugins/git/gitorious/gitoriousrepositorywizardpage.cpp src/plugins/git/gitorious/gitoriousrepositorywizardpage.h src/plugins/glsleditor/GLSLEditor.pluginspec.in src/plugins/glsleditor/glsleditorfactory.cpp src/plugins/glsleditor/glslfilewizard.cpp src/plugins/helloworld/HelloWorld.pluginspec.in src/plugins/help/Help.pluginspec.in src/plugins/imageviewer/ImageViewer.pluginspec.in src/plugins/ios/Ios.pluginspec.in src/plugins/macros/Macros.pluginspec.in src/plugins/mercurial/Mercurial.pluginspec.in src/plugins/perforce/Perforce.pluginspec.in src/plugins/projectexplorer/ProjectExplorer.pluginspec.in src/plugins/pythoneditor/PythonEditor.pluginspec.in src/plugins/pythoneditor/pythoneditorwidget.cpp src/plugins/pythoneditor/wizard/pythonfilewizard.cpp src/plugins/qbsprojectmanager/QbsProjectManager.pluginspec.in src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp src/plugins/qmakeprojectmanager/QmakeProjectManager.pluginspec.in src/plugins/qmakeprojectmanager/profileeditorfactory.cpp src/plugins/qmldesigner/QmlDesigner.pluginspec.in src/plugins/qmljseditor/QmlJSEditor.pluginspec.in src/plugins/qmljseditor/qmljseditorfactory.cpp src/plugins/qmljstools/QmlJSTools.pluginspec.in src/plugins/qmlprofiler/QmlProfiler.pluginspec.in src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec.in src/plugins/qnx/Qnx.pluginspec.in src/plugins/qtsupport/QtSupport.pluginspec.in src/plugins/remotelinux/RemoteLinux.pluginspec.in src/plugins/resourceeditor/ResourceEditor.pluginspec.in src/plugins/resourceeditor/resourcewizard.h src/plugins/subversion/Subversion.pluginspec.in src/plugins/tasklist/TaskList.pluginspec.in src/plugins/texteditor/TextEditor.pluginspec.in src/plugins/texteditor/basetexteditor_p.h src/plugins/texteditor/basetextmark.cpp src/plugins/texteditor/codeassist/basicproposalitemlistmodel.h src/plugins/texteditor/codeassist/defaultassistinterface.h src/plugins/texteditor/codeassist/iassistproposalitem.cpp src/plugins/texteditor/itexteditor.cpp src/plugins/texteditor/itexteditor.h src/plugins/texteditor/itextmark.cpp src/plugins/texteditor/plaintexteditor.cpp src/plugins/texteditor/plaintexteditor.h src/plugins/texteditor/texteditoractionhandler.cpp src/plugins/todo/Todo.pluginspec.in src/plugins/updateinfo/UpdateInfo.pluginspec.in src/plugins/valgrind/Valgrind.pluginspec.in src/plugins/vcsbase/VcsBase.pluginspec.in src/plugins/welcome/Welcome.pluginspec.in src/plugins/winrt/WinRt.pluginspec.in tests/auto/debugger/temporarydir.h Change-Id: I254af8be8119fe9855287909e17d4b8ca9d2fc2f
		
			
				
	
	
		
			1228 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1228 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/****************************************************************************
 | 
						|
**
 | 
						|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
 | 
						|
** Contact: http://www.qt-project.org/legal
 | 
						|
**
 | 
						|
** This file is part of Qt Creator.
 | 
						|
**
 | 
						|
** 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
 | 
						|
** a written agreement between you and Digia.  For licensing terms and
 | 
						|
** conditions see http://www.qt.io/licensing.  For further information
 | 
						|
** use the contact form at http://www.qt.io/contact-us.
 | 
						|
**
 | 
						|
** GNU Lesser General Public License Usage
 | 
						|
** Alternatively, this file may be used under the terms of the GNU Lesser
 | 
						|
** General Public License version 2.1 or version 3 as published by the Free
 | 
						|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
 | 
						|
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
 | 
						|
** following information to ensure the GNU Lesser General Public License
 | 
						|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
 | 
						|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
						|
**
 | 
						|
** In addition, as a special exception, Digia gives you certain additional
 | 
						|
** rights.  These rights are described in the Digia Qt LGPL Exception
 | 
						|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 | 
						|
**
 | 
						|
****************************************************************************/
 | 
						|
#include "nodeinstanceserver.h"
 | 
						|
 | 
						|
#include <QDebug>
 | 
						|
#include <QQmlEngine>
 | 
						|
#include <QQmlApplicationEngine>
 | 
						|
#include <QFileSystemWatcher>
 | 
						|
#include <QUrl>
 | 
						|
#include <QSet>
 | 
						|
#include <QDir>
 | 
						|
#include <QVariant>
 | 
						|
#include <QMetaType>
 | 
						|
#include <QQmlComponent>
 | 
						|
#include <QQmlContext>
 | 
						|
#include <qqmllist.h>
 | 
						|
#include <QAbstractAnimation>
 | 
						|
#include <private/qabstractanimation_p.h>
 | 
						|
#include <QMutableVectorIterator>
 | 
						|
#include <private/qquickview_p.h>
 | 
						|
#include <designersupport.h>
 | 
						|
 | 
						|
#include "servernodeinstance.h"
 | 
						|
#include "objectnodeinstance.h"
 | 
						|
#include "childrenchangeeventfilter.h"
 | 
						|
#include "propertyabstractcontainer.h"
 | 
						|
#include "propertybindingcontainer.h"
 | 
						|
#include "propertyvaluecontainer.h"
 | 
						|
#include "instancecontainer.h"
 | 
						|
#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 "nodeinstanceclientinterface.h"
 | 
						|
#include "removepropertiescommand.h"
 | 
						|
#include "valueschangedcommand.h"
 | 
						|
#include "informationchangedcommand.h"
 | 
						|
#include "pixmapchangedcommand.h"
 | 
						|
#include "commondefines.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"
 | 
						|
 | 
						|
#include "dummycontextobject.h"
 | 
						|
 | 
						|
namespace {
 | 
						|
    bool testImportStatements(const QStringList &importStatementList, const QUrl &url, bool enableErrorOutput = false) {
 | 
						|
        QQmlEngine engine;
 | 
						|
        QQmlComponent testImportComponent(&engine);
 | 
						|
 | 
						|
        QByteArray testComponentCode = QStringList(importStatementList).join("\n").toUtf8();
 | 
						|
 | 
						|
        testImportComponent.setData(testComponentCode.append("\nItem {}\n"), url);
 | 
						|
        testImportComponent.create();
 | 
						|
 | 
						|
        if (testImportComponent.errors().isEmpty()) {
 | 
						|
            return true;
 | 
						|
        } else {
 | 
						|
            if (enableErrorOutput)
 | 
						|
                qWarning() << "found not working imports: " << testImportComponent.errorString();
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
namespace QmlDesigner {
 | 
						|
 | 
						|
NodeInstanceServer::NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) :
 | 
						|
    NodeInstanceServerInterface(),
 | 
						|
    m_childrenChangeEventFilter(new Internal::ChildrenChangeEventFilter(this)),
 | 
						|
    m_nodeInstanceClient(nodeInstanceClient),
 | 
						|
    m_timer(0),
 | 
						|
    m_renderTimerInterval(16),
 | 
						|
    m_slowRenderTimer(false),
 | 
						|
    m_slowRenderTimerInterval(200)
 | 
						|
{
 | 
						|
    qmlRegisterType<DummyContextObject>("QmlDesigner", 1, 0, "DummyContextObject");
 | 
						|
 | 
						|
    connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitParentChanged(QObject*)));
 | 
						|
}
 | 
						|
 | 
						|
NodeInstanceServer::~NodeInstanceServer()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
QList<ServerNodeInstance> NodeInstanceServer::createInstances(const QVector<InstanceContainer> &containerVector)
 | 
						|
{
 | 
						|
    Q_ASSERT(declarativeView() || quickView());
 | 
						|
    QList<ServerNodeInstance> instanceList;
 | 
						|
    foreach (const InstanceContainer &instanceContainer, containerVector) {
 | 
						|
        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;
 | 
						|
            if (quickView())
 | 
						|
                quickView()->setContent(fileUrl(), m_importComponent, m_rootNodeInstance.rootQuickItem());
 | 
						|
            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;
 | 
						|
 | 
						|
    return m_idInstanceHash.contains(id) && m_idInstanceHash.value(id).isValid();
 | 
						|
}
 | 
						|
 | 
						|
ServerNodeInstance NodeInstanceServer::instanceForObject(QObject *object) const
 | 
						|
{
 | 
						|
    Q_ASSERT(m_objectInstanceHash.contains(object));
 | 
						|
    return m_objectInstanceHash.value(object);
 | 
						|
}
 | 
						|
 | 
						|
bool NodeInstanceServer::hasInstanceForObject(QObject *object) const
 | 
						|
{
 | 
						|
    if (object == 0)
 | 
						|
        return false;
 | 
						|
 | 
						|
    return m_objectInstanceHash.contains(object) && m_objectInstanceHash.value(object).isValid();
 | 
						|
}
 | 
						|
 | 
						|
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)
 | 
						|
{
 | 
						|
    initializeView();
 | 
						|
    QUnifiedTimer::instance()->setSlowdownFactor(0.00001);
 | 
						|
    QUnifiedTimer::instance()->setSlowModeEnabled(true);
 | 
						|
 | 
						|
    QList<ServerNodeInstance> instanceList = setupScene(command);
 | 
						|
 | 
						|
    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) {
 | 
						|
        if (hasInstanceForId(container.instanceId())) {
 | 
						|
            ServerNodeInstance instance = instanceForId(container.instanceId());
 | 
						|
            if (instance.isValid()) {
 | 
						|
                instance.reparent(instanceForId(container.oldParentInstanceId()), container.oldParentProperty(), instanceForId(container.newParentInstanceId()), container.newParentProperty());
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
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*/)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void NodeInstanceServer::setupImports(const QVector<AddImportContainer> &containerVector)
 | 
						|
{
 | 
						|
    Q_ASSERT(quickView());
 | 
						|
    QSet<QString> importStatementSet;
 | 
						|
    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();
 | 
						|
 | 
						|
        importStatementSet.insert(importStatement);
 | 
						|
    }
 | 
						|
 | 
						|
    delete m_importComponent.data();
 | 
						|
    delete m_importComponentObject.data();
 | 
						|
    QStringList importStatementList(importStatementSet.toList());
 | 
						|
    QStringList workingImportStatementList;
 | 
						|
 | 
						|
    // check possible import statements combinations
 | 
						|
    bool enableErrorOutput(true);
 | 
						|
 | 
						|
    // maybe it just works
 | 
						|
    if (testImportStatements(importStatementList, fileUrl())) {
 | 
						|
        workingImportStatementList = importStatementList;
 | 
						|
    } else {
 | 
						|
        QString firstWorkingImportStatement; //usually this will be "import QtQuick x.x"
 | 
						|
        QStringList otherImportStatements;
 | 
						|
        foreach (const QString &importStatement, importStatementList) {
 | 
						|
            if (testImportStatements(QStringList(importStatement), fileUrl()))
 | 
						|
                firstWorkingImportStatement = importStatement;
 | 
						|
            else
 | 
						|
                otherImportStatements.append(importStatement);
 | 
						|
        }
 | 
						|
 | 
						|
        // find the bad imports from otherImportStatements
 | 
						|
        foreach (const QString &importStatement, otherImportStatements) {
 | 
						|
            if (testImportStatements(QStringList(firstWorkingImportStatement) <<
 | 
						|
                importStatement, fileUrl(), enableErrorOutput)) {
 | 
						|
                workingImportStatementList.append(importStatement);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        workingImportStatementList.prepend(firstWorkingImportStatement);
 | 
						|
    }
 | 
						|
 | 
						|
    setupOnlyWorkingImports(workingImportStatementList);
 | 
						|
}
 | 
						|
 | 
						|
void NodeInstanceServer::setupOnlyWorkingImports(const QStringList &workingImportStatementList)
 | 
						|
{
 | 
						|
    QByteArray componentCode = workingImportStatementList.join("\n").toUtf8().append("\n");
 | 
						|
    m_importCode = componentCode;
 | 
						|
 | 
						|
    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();
 | 
						|
    Q_ASSERT(m_importComponent && m_importComponentObject);
 | 
						|
    Q_ASSERT_X(m_importComponent->errors().isEmpty(), __FUNCTION__, m_importComponent->errorString().toLatin1());
 | 
						|
}
 | 
						|
 | 
						|
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();
 | 
						|
}
 | 
						|
 | 
						|
void NodeInstanceServer::setupDefaultDummyData()
 | 
						|
{
 | 
						|
    QQmlComponent component(engine());
 | 
						|
    QByteArray defaultContextObjectArray("import QtQml 2.0\n"
 | 
						|
                                         "import QmlDesigner 1.0\n"
 | 
						|
                                         "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) {
 | 
						|
        qDebug() << "Loaded default dummy context object.";
 | 
						|
        m_dummyContextObject->setParent(this);
 | 
						|
    }
 | 
						|
 | 
						|
    refreshBindings();
 | 
						|
}
 | 
						|
 | 
						|
QList<ServerNodeInstance> NodeInstanceServer::setupInstances(const CreateSceneCommand &command)
 | 
						|
{
 | 
						|
    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);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    QListIterator<ServerNodeInstance> instanceListIterator(instanceList);
 | 
						|
    instanceListIterator.toBack();
 | 
						|
    while (instanceListIterator.hasPrevious()) {
 | 
						|
        ServerNodeInstance instance = instanceListIterator.previous();
 | 
						|
        instance.doComponentComplete();
 | 
						|
    }
 | 
						|
 | 
						|
    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();
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
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());
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
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);
 | 
						|
        connect(m_dummdataFileSystemWatcher.data(), SIGNAL(fileChanged(QString)), this, SLOT(refreshDummyData(QString)));
 | 
						|
    }
 | 
						|
 | 
						|
    return m_dummdataFileSystemWatcher.data();
 | 
						|
}
 | 
						|
 | 
						|
QFileSystemWatcher *NodeInstanceServer::fileSystemWatcher()
 | 
						|
{
 | 
						|
    if (m_fileSystemWatcher.isNull()) {
 | 
						|
        m_fileSystemWatcher = new QFileSystemWatcher(this);
 | 
						|
        connect(m_fileSystemWatcher.data(), SIGNAL(fileChanged(QString)), this, SLOT(refreshLocalFileProperty(QString)));
 | 
						|
    }
 | 
						|
 | 
						|
    return m_fileSystemWatcher.data();
 | 
						|
}
 | 
						|
 | 
						|
Internal::ChildrenChangeEventFilter *NodeInstanceServer::childrenChangeEventFilter() const
 | 
						|
{
 | 
						|
    return m_childrenChangeEventFilter.data();
 | 
						|
}
 | 
						|
 | 
						|
void NodeInstanceServer::addFilePropertyToFileSystemWatcher(QObject *object, const PropertyName &propertyName, const QString &path)
 | 
						|
{
 | 
						|
    if (!m_fileSystemWatcherHash.contains(path)) {
 | 
						|
        m_fileSystemWatcherHash.insert(path, ObjectPropertyPair(object, propertyName));
 | 
						|
        fileSystemWatcher()->addPath(path);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void NodeInstanceServer::removeFilePropertyFromFileSystemWatcher(QObject *object, const PropertyName &propertyName, const QString &path)
 | 
						|
{
 | 
						|
    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();
 | 
						|
            PropertyName propertyName = objectPropertyPair.second;
 | 
						|
 | 
						|
            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);
 | 
						|
        connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitParentChanged(QObject*)));
 | 
						|
    }
 | 
						|
 | 
						|
    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());
 | 
						|
 | 
						|
        const PropertyName name = propertyContainer.name();
 | 
						|
 | 
						|
        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())
 | 
						|
            rootContext()->setContextProperty(name, QVariant());
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void NodeInstanceServer::setInstancePropertyBinding(const PropertyBindingContainer &bindingContainer)
 | 
						|
{
 | 
						|
    if (hasInstanceForId(bindingContainer.instanceId())) {
 | 
						|
        ServerNodeInstance instance = instanceForId(bindingContainer.instanceId());
 | 
						|
 | 
						|
        const PropertyName name = bindingContainer.name();
 | 
						|
        const QString expression = bindingContainer.expression();
 | 
						|
 | 
						|
 | 
						|
        if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) {
 | 
						|
            bool stateBindingWasUpdated = activeStateInstance().updateStateBinding(instance, name, expression);
 | 
						|
            if (!stateBindingWasUpdated) {
 | 
						|
                if (bindingContainer.isDynamic())
 | 
						|
                    instance.setPropertyDynamicBinding(name, bindingContainer.dynamicTypeName(), expression);
 | 
						|
                else
 | 
						|
                    instance.setPropertyBinding(name, expression);
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            if (bindingContainer.isDynamic())
 | 
						|
                instance.setPropertyDynamicBinding(name, bindingContainer.dynamicTypeName(), expression);
 | 
						|
            else
 | 
						|
                instance.setPropertyBinding(name, expression);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
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());
 | 
						|
 | 
						|
 | 
						|
        const PropertyName name = valueContainer.name();
 | 
						|
        const QVariant value = valueContainer.value();
 | 
						|
 | 
						|
 | 
						|
        if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) {
 | 
						|
            bool stateValueWasUpdated = activeStateInstance().updateStateVariant(instance, name, value);
 | 
						|
            if (!stateValueWasUpdated) {
 | 
						|
                if (valueContainer.isDynamic())
 | 
						|
                    instance.setPropertyDynamicVariant(name, valueContainer.dynamicTypeName(), value);
 | 
						|
                else
 | 
						|
                    instance.setPropertyVariant(name, value);
 | 
						|
            }
 | 
						|
        } else { //base state
 | 
						|
            if (valueContainer.isDynamic())
 | 
						|
                instance.setPropertyDynamicVariant(name, valueContainer.dynamicTypeName(), value);
 | 
						|
            else
 | 
						|
                instance.setPropertyVariant(name, value);
 | 
						|
        }
 | 
						|
 | 
						|
        if (valueContainer.isDynamic() && valueContainer.instanceId() == 0 && engine())
 | 
						|
            rootContext()->setContextProperty(name, Internal::ObjectNodeInstance::fixResourcePaths(value));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void NodeInstanceServer::setInstanceAuxiliaryData(const PropertyValueContainer &auxiliaryContainer)
 | 
						|
{
 | 
						|
    //instanceId() == 0: the item is root
 | 
						|
    if (auxiliaryContainer.instanceId() == 0 && (auxiliaryContainer.name() == "width" ||
 | 
						|
                                        auxiliaryContainer.name() == "height")) {
 | 
						|
 | 
						|
        if (!auxiliaryContainer.value().isNull()) {
 | 
						|
            setInstancePropertyVariant(auxiliaryContainer);
 | 
						|
        } else {
 | 
						|
            rootNodeInstance().resetProperty(auxiliaryContainer.name());
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (auxiliaryContainer.name().endsWith("@NodeInstance")) {
 | 
						|
        PropertyName propertyName = auxiliaryContainer.name().left(auxiliaryContainer.name().count() - 12);
 | 
						|
        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) {
 | 
						|
        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)));
 | 
						|
            }
 | 
						|
 | 
						|
            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));
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    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));
 | 
						|
}
 | 
						|
 | 
						|
static bool supportedVariantType(int type)
 | 
						|
{
 | 
						|
    return type < int(QVariant::UserType) && type != QMetaType::QObjectStar;
 | 
						|
}
 | 
						|
 | 
						|
ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QList<ServerNodeInstance> &instanceList) const
 | 
						|
{
 | 
						|
    QVector<PropertyValueContainer> valueVector;
 | 
						|
 | 
						|
    foreach (const ServerNodeInstance &instance, instanceList) {
 | 
						|
        foreach (const PropertyName &propertyName, instance.propertyNames()) {
 | 
						|
            QVariant propertyValue = instance.property(propertyName);
 | 
						|
            if (supportedVariantType(propertyValue.userType()))
 | 
						|
                valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName, propertyValue, PropertyName()));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    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) {
 | 
						|
        const PropertyName propertyName = property.second;
 | 
						|
        const ServerNodeInstance instance = property.first;
 | 
						|
 | 
						|
        if (instance.isValid()) {
 | 
						|
            QVariant propertyValue = instance.property(propertyName);
 | 
						|
            if (QMetaType::isRegistered(propertyValue.userType()) && supportedVariantType(propertyValue.type())) {
 | 
						|
                valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName, propertyValue, PropertyName()));
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return ValuesChangedCommand(valueVector);
 | 
						|
}
 | 
						|
 | 
						|
QByteArray NodeInstanceServer::importCode() const
 | 
						|
{
 | 
						|
    return m_importCode;
 | 
						|
}
 | 
						|
 | 
						|
QObject *NodeInstanceServer::dummyContextObject() const
 | 
						|
{
 | 
						|
    return m_dummyContextObject.data();
 | 
						|
}
 | 
						|
 | 
						|
void NodeInstanceServer::notifyPropertyChange(qint32 instanceid, const PropertyName &propertyName)
 | 
						|
{
 | 
						|
    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) {
 | 
						|
        qDebug() << "Loaded dummy data:" << qmlFileInfo.filePath();
 | 
						|
        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");
 | 
						|
    QList<QFileInfo> filePathList = dir.entryInfoList();
 | 
						|
    foreach (const QFileInfo &qmlFileInfo, filePathList) {
 | 
						|
        loadDummyDataFile(qmlFileInfo);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void NodeInstanceServer::loadDummyDataContext(const QString& directory)
 | 
						|
{
 | 
						|
    QDir dir(directory+"/context", "*.qml");
 | 
						|
    QList<QFileInfo> filePathList = dir.entryInfoList();
 | 
						|
    QString baseName = QFileInfo(fileUrl().toLocalFile()).completeBaseName();
 | 
						|
    foreach (const QFileInfo &qmlFileInfo, filePathList) {
 | 
						|
        if (qmlFileInfo.completeBaseName() == baseName)
 | 
						|
            loadDummyContextObjectFile(qmlFileInfo);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void NodeInstanceServer::sendDebugOutput(DebugOutputCommand::Type type, const QString &message)
 | 
						|
{
 | 
						|
    DebugOutputCommand command(message, type);
 | 
						|
    nodeInstanceClient()->debugOutput(command);
 | 
						|
}
 | 
						|
 | 
						|
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();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 |