nodeinstanceserverproxy.cpp 24.5 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
2
**
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
hjk's avatar
hjk committed
4
** Contact: http://www.qt-project.org/legal
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
7
**
hjk's avatar
hjk committed
8 9 10 11 12 13 14
** 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://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
15 16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17 18 19 20 21 22 23 24 25
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
26 27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
29

30 31 32 33 34 35 36
#include "nodeinstanceserverproxy.h"

#include <QLocalServer>
#include <QLocalSocket>
#include <QProcess>
#include <QCoreApplication>
#include <QUuid>
37
#include <QFileInfo>
38
#include <QDir>
39
#include <QTimer>
40
#include <QTextStream>
41
#include <QMessageBox>
42 43 44 45 46

#include "createinstancescommand.h"
#include "createscenecommand.h"
#include "changevaluescommand.h"
#include "changebindingscommand.h"
47
#include "changeauxiliarycommand.h"
48 49 50 51 52 53 54
#include "changefileurlcommand.h"
#include "removeinstancescommand.h"
#include "clearscenecommand.h"
#include "removepropertiescommand.h"
#include "reparentinstancescommand.h"
#include "changeidscommand.h"
#include "changestatecommand.h"
55
#include "completecomponentcommand.h"
56
#include "changenodesourcecommand.h"
57 58 59 60

#include "informationchangedcommand.h"
#include "pixmapchangedcommand.h"
#include "valueschangedcommand.h"
61
#include "childrenchangedcommand.h"
62
#include "statepreviewimagechangedcommand.h"
63
#include "componentcompletedcommand.h"
64
#include "tokencommand.h"
65
#include "removesharedmemorycommand.h"
66
#include "endpuppetcommand.h"
67
#include "synchronizecommand.h"
Marco Bubke's avatar
Marco Bubke committed
68
#include "debugoutputcommand.h"
69

70
#include "nodeinstanceview.h"
71 72

#include "import.h"
73 74 75

#include <utils/hostosinfo.h>

76 77
#include <QMessageBox>

78
namespace {
79
#ifdef Q_OS_MAC
80
#  define SHARE_PATH "/../Resources"
81
#else
82
#  define SHARE_PATH "/../share/qtcreator"
83 84 85 86 87 88 89 90 91 92 93 94 95 96
#endif

static QString applicationDirPath()
{
    return QCoreApplication::applicationDirPath();
}

static inline QString sharedDirPath()
{
    QString appPath = applicationDirPath();

    return QFileInfo(appPath + SHARE_PATH).absoluteFilePath();
}

97 98
static QLatin1String qmlPuppetApplicationDirectoryForTests()
{
99 100 101
    if (Utils::HostOsInfo::isWindowsHost())
        //one more - debug/release dir
        return QLatin1String("/../../../../../../bin/");
102 103 104
    return QLatin1String("/../../../../../bin/");
}
} //namespace
105 106 107

namespace QmlDesigner {

108
static bool hasQtQuick2(NodeInstanceView *nodeInstanceView)
109 110 111
{
    if (nodeInstanceView && nodeInstanceView->model()) {
        foreach (const Import &import ,nodeInstanceView->model()->imports()) {
112
            if (import.url() ==  "QtQuick" && import.version().toDouble() >= 2.0)
113 114 115 116 117 118 119
                return true;
        }
    }

    return false;
}

120 121 122 123 124 125 126 127 128
QString NodeInstanceServerProxy::creatorQmlPuppetPath()
{
    QString applicationPath =  QCoreApplication::applicationDirPath();
    applicationPath = macOSBundlePath(applicationPath);
    applicationPath += QLatin1Char('/') + qmlPuppetApplicationName();

    return applicationPath;
}

129
NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceView, RunModus runModus, const QString &pathToQt)
130 131 132
    : NodeInstanceServerInterface(nodeInstanceView),
      m_localServer(new QLocalServer(this)),
      m_nodeInstanceView(nodeInstanceView),
133
      m_firstBlockSize(0),
134
      m_secondBlockSize(0),
135
      m_thirdBlockSize(0),
136 137 138 139
      m_writeCommandCounter(0),
      m_firstLastReadCommandCounter(0),
      m_secondLastReadCommandCounter(0),
      m_thirdLastReadCommandCounter(0),
140 141
      m_runModus(runModus),
      m_synchronizeId(-1)
142 143 144 145
{
   QString socketToken(QUuid::createUuid().toString());

   m_localServer->listen(socketToken);
146
   m_localServer->setMaxPendingConnections(3);
147

148 149
   QString applicationPath =  pathToQt + QLatin1String("/bin");
   if (runModus == TestModus) {
150
       applicationPath = QCoreApplication::applicationDirPath()
151 152
           + qmlPuppetApplicationDirectoryForTests()
           + qmlPuppetApplicationName();
153
   } else {
154
       applicationPath = macOSBundlePath(applicationPath);
Robert Loehning's avatar
Robert Loehning committed
155
       applicationPath += QLatin1Char('/') + qmlPuppetApplicationName();
156 157 158


#if defined(QT_NO_DEBUG) || defined(SEARCH_PUPPET_IN_CREATOR_BINPATH) // to prevent of choosing the wrong puppet in debug
159 160
       if (!QFileInfo(applicationPath).exists()) { //No qmlpuppet in Qt
           //We have to find out how to give not too intrusive feedback
161
           applicationPath = creatorQmlPuppetPath();
162
       }
163
#endif
164
   }
165

166

167
   QByteArray envImportPath = qgetenv("QTCREATOR_QMLPUPPET_PATH");
168
   if (!envImportPath.isEmpty())
169 170
       applicationPath = envImportPath;

171
   QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
172

173
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) && (defined(Q_OS_MAC) || defined(Q_OS_LINUX))
Laurent Montel's avatar
Laurent Montel committed
174
   environment.insert(QLatin1String("DESIGNER_DONT_USE_SHARED_MEMORY"), QLatin1String("1"));
175 176
#endif

177 178
   if (QFileInfo(applicationPath).exists()) {
       m_qmlPuppetEditorProcess = new QProcess;
179
       m_qmlPuppetEditorProcess->setProcessEnvironment(environment);
180
       m_qmlPuppetEditorProcess->setObjectName("EditorProcess");
181 182 183
       connect(m_qmlPuppetEditorProcess.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)));
       connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), m_qmlPuppetEditorProcess.data(), SLOT(kill()));
       bool fowardQmlpuppetOutput = !qgetenv("FORWARD_QMLPUPPET_OUTPUT").isEmpty();
184 185 186 187
       if (fowardQmlpuppetOutput) {
           m_qmlPuppetEditorProcess->setProcessChannelMode(QProcess::MergedChannels);
           connect(m_qmlPuppetEditorProcess.data(), SIGNAL(readyRead()), this, SLOT(printEditorProcessOutput()));
       }
188
       m_qmlPuppetEditorProcess->start(applicationPath, QStringList() << socketToken << "editormode" << "-graphicssystem raster");
189

190 191
       if (runModus == NormalModus) {
           m_qmlPuppetPreviewProcess = new QProcess;
192
           m_qmlPuppetPreviewProcess->setProcessEnvironment(environment);
193
           m_qmlPuppetPreviewProcess->setObjectName("PreviewProcess");
194 195
           connect(m_qmlPuppetPreviewProcess.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)));
           connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), m_qmlPuppetPreviewProcess.data(), SLOT(kill()));
196 197 198 199
           if (fowardQmlpuppetOutput) {
               m_qmlPuppetPreviewProcess->setProcessChannelMode(QProcess::MergedChannels);
               connect(m_qmlPuppetPreviewProcess.data(), SIGNAL(readyRead()), this, SLOT(printPreviewProcessOutput()));
           }
200
           m_qmlPuppetPreviewProcess->start(applicationPath, QStringList() << socketToken << "previewmode" << "-graphicssystem raster");
201

202
           m_qmlPuppetRenderProcess = new QProcess;
203
           m_qmlPuppetRenderProcess->setProcessEnvironment(environment);
204
           m_qmlPuppetRenderProcess->setObjectName("RenderProcess");
205 206
           connect(m_qmlPuppetRenderProcess.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)));
           connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), m_qmlPuppetRenderProcess.data(), SLOT(kill()));
207 208 209 210
           if (fowardQmlpuppetOutput) {
               m_qmlPuppetRenderProcess->setProcessChannelMode(QProcess::MergedChannels);
               connect(m_qmlPuppetRenderProcess.data(), SIGNAL(readyRead()), this, SLOT(printRenderProcessOutput()));
           }
211
           m_qmlPuppetRenderProcess->start(applicationPath, QStringList() << socketToken << "rendermode" << "-graphicssystem raster");
212

213
       }
214

215
       connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(deleteLater()));
216

217 218
       if (m_qmlPuppetEditorProcess->waitForStarted(10000)) {
           connect(m_qmlPuppetEditorProcess.data(), SIGNAL(finished(int)), m_qmlPuppetEditorProcess.data(),SLOT(deleteLater()));
219

220 221 222
           if (runModus == NormalModus) {
               m_qmlPuppetPreviewProcess->waitForStarted();
               connect(m_qmlPuppetPreviewProcess.data(), SIGNAL(finished(int)), m_qmlPuppetPreviewProcess.data(),SLOT(deleteLater()));
223

224 225 226
               m_qmlPuppetRenderProcess->waitForStarted();
               connect(m_qmlPuppetRenderProcess.data(), SIGNAL(finished(int)), m_qmlPuppetRenderProcess.data(),SLOT(deleteLater()));
           }
227

228 229
           if (!m_localServer->hasPendingConnections())
               m_localServer->waitForNewConnection(10000);
230

231 232
           m_firstSocket = m_localServer->nextPendingConnection();
           connect(m_firstSocket.data(), SIGNAL(readyRead()), this, SLOT(readFirstDataStream()));
233

234 235 236
           if (runModus == NormalModus) {
               if (!m_localServer->hasPendingConnections())
                   m_localServer->waitForNewConnection(10000);
237

238 239
               m_secondSocket = m_localServer->nextPendingConnection();
               connect(m_secondSocket.data(), SIGNAL(readyRead()), this, SLOT(readSecondDataStream()));
240

241 242
               if (!m_localServer->hasPendingConnections())
                   m_localServer->waitForNewConnection(10000);
243

244 245 246
               m_thirdSocket = m_localServer->nextPendingConnection();
               connect(m_thirdSocket.data(), SIGNAL(readyRead()), this, SLOT(readThirdDataStream()));
           }
247

248
       } else {
249 250 251 252 253
           QMessageBox::warning(0, tr("Cannot Start QML Puppet Executable"),
                                tr("The executable of the QML Puppet process (%1) cannot be started. "
                                   "Please check your installation. "
                                   "QML Puppet is a process which runs in the background to render the items.").
                                arg(applicationPath));
254
       }
255

256 257 258
       m_localServer->close();

   } else {
259
           QMessageBox::warning(0, tr("Cannot Find QML Puppet Executable"), missingQmlPuppetErrorMessage(applicationPath));
260
   }
261 262 263 264 265 266 267

   int indexOfCapturePuppetStream = QCoreApplication::arguments().indexOf("-capture-puppet-stream");
   if (indexOfCapturePuppetStream > 0) {
       m_captureFileForTest.setFileName(QCoreApplication::arguments().at(indexOfCapturePuppetStream + 1));
       bool isOpen = m_captureFileForTest.open(QIODevice::WriteOnly);
       qDebug() << "file is open: " << isOpen;
   }
268 269 270 271
}

NodeInstanceServerProxy::~NodeInstanceServerProxy()
{
272 273
    disconnect(this, SLOT(processFinished(int,QProcess::ExitStatus)));

274 275
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

276 277 278 279 280 281
    if (m_firstSocket)
        m_firstSocket->close();

    if (m_secondSocket)
        m_secondSocket->close();

282
    if (m_thirdSocket)
283 284
        m_thirdSocket->close();

285

286
    if (m_qmlPuppetEditorProcess)
287
        QTimer::singleShot(3000, m_qmlPuppetEditorProcess.data(), SLOT(terminate()));
288

289
    if (m_qmlPuppetPreviewProcess)
290
        QTimer::singleShot(3000, m_qmlPuppetPreviewProcess.data(), SLOT(terminate()));
291 292

    if (m_qmlPuppetRenderProcess)
293
         QTimer::singleShot(3000, m_qmlPuppetRenderProcess.data(), SLOT(terminate()));
294 295 296 297 298 299 300
}

void NodeInstanceServerProxy::dispatchCommand(const QVariant &command)
{
    static const int informationChangedCommandType = QMetaType::type("InformationChangedCommand");
    static const int valuesChangedCommandType = QMetaType::type("ValuesChangedCommand");
    static const int pixmapChangedCommandType = QMetaType::type("PixmapChangedCommand");
301
    static const int childrenChangedCommandType = QMetaType::type("ChildrenChangedCommand");
302
    static const int statePreviewImageChangedCommandType = QMetaType::type("StatePreviewImageChangedCommand");
303
    static const int componentCompletedCommandType = QMetaType::type("ComponentCompletedCommand");
304
    static const int synchronizeCommandType = QMetaType::type("SynchronizeCommand");
305
    static const int tokenCommandType = QMetaType::type("TokenCommand");
Marco Bubke's avatar
Marco Bubke committed
306
    static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
307

308
    if (command.userType() ==  informationChangedCommandType) {
309
        nodeInstanceClient()->informationChanged(command.value<InformationChangedCommand>());
310
    } else if (command.userType() ==  valuesChangedCommandType) {
311
        nodeInstanceClient()->valuesChanged(command.value<ValuesChangedCommand>());
312
    } else if (command.userType() ==  pixmapChangedCommandType) {
313
        nodeInstanceClient()->pixmapChanged(command.value<PixmapChangedCommand>());
314
    } else if (command.userType() == childrenChangedCommandType) {
315
        nodeInstanceClient()->childrenChanged(command.value<ChildrenChangedCommand>());
316
    } else if (command.userType() == statePreviewImageChangedCommandType) {
317
        nodeInstanceClient()->statePreviewImagesChanged(command.value<StatePreviewImageChangedCommand>());
318
    } else if (command.userType() == componentCompletedCommandType) {
319
        nodeInstanceClient()->componentCompleted(command.value<ComponentCompletedCommand>());
320
    } else if (command.userType() == tokenCommandType) {
321
        nodeInstanceClient()->token(command.value<TokenCommand>());
322
    } else if (command.userType() == debugOutputCommandType) {
Marco Bubke's avatar
Marco Bubke committed
323
        nodeInstanceClient()->debugOutput(command.value<DebugOutputCommand>());
324
    } else if (command.userType() == synchronizeCommandType) {
325 326 327
        SynchronizeCommand synchronizeCommand = command.value<SynchronizeCommand>();
        m_synchronizeId = synchronizeCommand.synchronizeId();
    }  else
328 329 330 331 332 333 334 335
        Q_ASSERT(false);
}

NodeInstanceClientInterface *NodeInstanceServerProxy::nodeInstanceClient() const
{
    return m_nodeInstanceView.data();
}

336 337
QString NodeInstanceServerProxy::missingQmlPuppetErrorMessage(const QString &applicationPath) const
{
338 339 340 341 342 343 344 345
    QString message;
    QTextStream str(&message);
    str << "<html><head/><body><p>"
        << tr("The executable of the QML Puppet process (<code>%1</code>) cannot be found. "
              "Check your installation. "
              "QML Puppet is a process which runs in the background to render the items.").
           arg(QDir::toNativeSeparators(applicationPath))
        << "</p>";
346
    if (hasQtQuick2(m_nodeInstanceView.data())) {
347 348 349 350 351 352 353 354 355
        str << "<p>"
            << tr("You can build <code>qml2puppet</code> yourself with Qt 5.0.1 or higher. "
                 "The source can be found in <code>%1</code>.").
               arg(QDir::toNativeSeparators(sharedDirPath() + QLatin1String("/qml/qmlpuppet/qml2puppet/")))
            << "</p><p>"
            << tr("<code>qml2puppet</code> will be installed to the <code>bin</code> directory of your Qt version. "
                  "Qt Quick Designer will check the <code>bin</code> directory of the currently active Qt version "
                  "of your project.")
            << "</p>";
356
    }
357
    str << "</p></body></html>";
358 359 360
    return message;
}

361
static void writeCommandToIODecive(const QVariant &command, QIODevice *ioDevice, unsigned int commandCounter)
362
{
363
    if (ioDevice) {
364 365
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
366
        out.setVersion(QDataStream::Qt_4_8);
367
        out << quint32(0);
368
        out << quint32(commandCounter);
369 370 371 372
        out << command;
        out.device()->seek(0);
        out << quint32(block.size() - sizeof(quint32));

373
        ioDevice->write(block);
374
    }
375 376 377 378
}

void NodeInstanceServerProxy::writeCommand(const QVariant &command)
{
379 380 381 382 383 384 385 386 387 388
    writeCommandToIODecive(command, m_firstSocket.data(), m_writeCommandCounter);
    writeCommandToIODecive(command, m_secondSocket.data(), m_writeCommandCounter);
    writeCommandToIODecive(command, m_thirdSocket.data(), m_writeCommandCounter);

    if (m_captureFileForTest.isWritable()) {
        qDebug() << "Write strean to file: " << m_captureFileForTest.fileName();
        writeCommandToIODecive(command, &m_captureFileForTest, m_writeCommandCounter);
        qDebug() << "\twrite file: " << m_captureFileForTest.pos();
    }

389
    m_writeCommandCounter++;
390 391 392 393 394
    if (m_runModus == TestModus) {
        static int synchronizeId = 0;
        synchronizeId++;
        SynchronizeCommand synchronizeCommand(synchronizeId);

395
        writeCommandToIODecive(QVariant::fromValue(synchronizeCommand), m_firstSocket.data(), m_writeCommandCounter);
396
        m_writeCommandCounter++;
397

398
        while (m_firstSocket->waitForReadyRead(100)) {
399 400 401 402 403
                readFirstDataStream();
                if (m_synchronizeId == synchronizeId)
                    return;
        }
    }
404 405
}

406
void NodeInstanceServerProxy::processFinished(int /*exitCode*/, QProcess::ExitStatus exitStatus)
407
{
408
    qDebug() << "Process finished:" << sender();
409

410 411 412
    if (m_captureFileForTest.isOpen()) {
        m_captureFileForTest.close();
        m_captureFileForTest.remove();
413 414
        QMessageBox::warning(0, tr("QML Puppet Crashed"), tr("You are recording a puppet stream and the puppet crashed. "
                                                             "It is recommended to reopen the Qt Quick Designer and start again."));
415 416 417
    }


418 419
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

420 421 422 423
    if (m_firstSocket)
        m_firstSocket->close();
    if (m_secondSocket)
        m_secondSocket->close();
424 425 426
    if (m_thirdSocket)
        m_thirdSocket->close();

427 428
    if (exitStatus == QProcess::CrashExit)
        emit processCrashed();
429 430
}

431

432 433 434 435 436 437 438 439 440
void NodeInstanceServerProxy::readFirstDataStream()
{
    QList<QVariant> commandList;

    while (!m_firstSocket->atEnd()) {
        if (m_firstSocket->bytesAvailable() < int(sizeof(quint32)))
            break;

        QDataStream in(m_firstSocket.data());
441
        in.setVersion(QDataStream::Qt_4_8);
442

443
        if (m_firstBlockSize == 0)
444 445 446 447 448
            in >> m_firstBlockSize;

        if (m_firstSocket->bytesAvailable() < m_firstBlockSize)
            break;

449 450 451 452 453 454 455 456
        quint32 commandCounter;
        in >> commandCounter;
        bool commandLost = !((m_firstLastReadCommandCounter == 0 && commandCounter == 0) || (m_firstLastReadCommandCounter + 1 == commandCounter));
        if (commandLost)
            qDebug() << "server command lost: " << m_firstLastReadCommandCounter <<  commandCounter;
        m_firstLastReadCommandCounter = commandCounter;


457 458 459 460 461 462 463 464 465 466 467 468 469
        QVariant command;
        in >> command;
        m_firstBlockSize = 0;

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
        dispatchCommand(command);
    }
}

void NodeInstanceServerProxy::readSecondDataStream()
470 471 472
{
    QList<QVariant> commandList;

473 474
    while (!m_secondSocket->atEnd()) {
        if (m_secondSocket->bytesAvailable() < int(sizeof(quint32)))
475 476
            break;

477
        QDataStream in(m_secondSocket.data());
478
        in.setVersion(QDataStream::Qt_4_8);
479

480
        if (m_secondBlockSize == 0)
481
            in >> m_secondBlockSize;
482

483
        if (m_secondSocket->bytesAvailable() < m_secondBlockSize)
484 485
            break;

486 487 488 489 490 491 492 493
        quint32 commandCounter;
        in >> commandCounter;
        bool commandLost = !((m_secondLastReadCommandCounter == 0 && commandCounter == 0) || (m_secondLastReadCommandCounter + 1 == commandCounter));
        if (commandLost)
            qDebug() << "server command lost: " << m_secondLastReadCommandCounter <<  commandCounter;
        m_secondLastReadCommandCounter = commandCounter;


494 495
        QVariant command;
        in >> command;
496
        m_secondBlockSize = 0;
497 498 499 500 501 502 503 504 505

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
        dispatchCommand(command);
    }
}

506 507 508 509 510 511 512 513 514
void NodeInstanceServerProxy::readThirdDataStream()
{
    QList<QVariant> commandList;

    while (!m_thirdSocket->atEnd()) {
        if (m_thirdSocket->bytesAvailable() < int(sizeof(quint32)))
            break;

        QDataStream in(m_thirdSocket.data());
515
        in.setVersion(QDataStream::Qt_4_8);
516

517
        if (m_thirdBlockSize == 0)
518 519 520 521 522
            in >> m_thirdBlockSize;

        if (m_thirdSocket->bytesAvailable() < m_thirdBlockSize)
            break;

523 524 525 526 527 528 529 530
        quint32 commandCounter;
        in >> commandCounter;
        bool commandLost = !((m_thirdLastReadCommandCounter == 0 && commandCounter == 0) || (m_thirdLastReadCommandCounter + 1 == commandCounter));
        if (commandLost)
            qDebug() << "server command lost: " << m_thirdLastReadCommandCounter <<  commandCounter;
        m_thirdLastReadCommandCounter = commandCounter;


531 532 533 534 535 536 537 538 539 540 541 542
        QVariant command;
        in >> command;
        m_thirdBlockSize = 0;

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
        dispatchCommand(command);
    }
}

543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
void NodeInstanceServerProxy::printEditorProcessOutput()
{
    while (m_qmlPuppetEditorProcess->canReadLine()) {
        QByteArray line = m_qmlPuppetEditorProcess->readLine();
        line.chop(1);
        qDebug().nospace() << "Editor Puppet: " << qPrintable(line);
    }
    qDebug() << "\n";
}

void NodeInstanceServerProxy::printPreviewProcessOutput()
{
    while (m_qmlPuppetPreviewProcess->canReadLine()) {
        QByteArray line = m_qmlPuppetPreviewProcess->readLine();
        line.chop(1);
        qDebug().nospace() << "Preview Puppet: " << qPrintable(line);
    }
    qDebug() << "\n";
}

void NodeInstanceServerProxy::printRenderProcessOutput()
{
    while (m_qmlPuppetRenderProcess->canReadLine()) {
        QByteArray line = m_qmlPuppetRenderProcess->readLine();
        line.chop(1);
        qDebug().nospace() << "Render Puppet: " << qPrintable(line);
    }

    qDebug() << "\n";
}

574 575
QString NodeInstanceServerProxy::qmlPuppetApplicationName() const
{
576 577 578
    if (hasQtQuick2(m_nodeInstanceView.data()))
        return QLatin1String("qml2puppet" QTC_HOST_EXE_SUFFIX);
    return QLatin1String("qmlpuppet" QTC_HOST_EXE_SUFFIX);
579 580 581 582 583
}

QString NodeInstanceServerProxy::macOSBundlePath(const QString &path) const
{
    QString applicationPath = path;
584 585 586 587 588 589 590
    if (Utils::HostOsInfo::isMacHost()) {
        if (hasQtQuick2(m_nodeInstanceView.data()))
            applicationPath += QLatin1String("/qml2puppet.app/Contents/MacOS");
        else
            applicationPath += QLatin1String("/qmlpuppet.app/Contents/MacOS");

    }
591 592
   return applicationPath;
}
593

594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
void NodeInstanceServerProxy::createInstances(const CreateInstancesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changeFileUrl(const ChangeFileUrlCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::createScene(const CreateSceneCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::clearScene(const ClearSceneCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::removeInstances(const RemoveInstancesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::removeProperties(const RemovePropertiesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changePropertyBindings(const ChangeBindingsCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changePropertyValues(const ChangeValuesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

634 635 636 637 638
void NodeInstanceServerProxy::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
void NodeInstanceServerProxy::reparentInstances(const ReparentInstancesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changeIds(const ChangeIdsCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changeState(const ChangeStateCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

654 655 656 657
void NodeInstanceServerProxy::completeComponent(const CompleteComponentCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}
658

659
void NodeInstanceServerProxy::changeNodeSource(const ChangeNodeSourceCommand &command)
660 661 662 663
{
    writeCommand(QVariant::fromValue(command));
}

664 665 666 667 668
void NodeInstanceServerProxy::token(const TokenCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

669 670 671 672 673
void NodeInstanceServerProxy::removeSharedMemory(const RemoveSharedMemoryCommand &command)
{
   writeCommand(QVariant::fromValue(command));
}

674
} // namespace QmlDesigner