nodeinstanceserverproxy.cpp 24.4 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
NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceView, RunModus runModus, const QString &pathToQt)
121 122 123
    : NodeInstanceServerInterface(nodeInstanceView),
      m_localServer(new QLocalServer(this)),
      m_nodeInstanceView(nodeInstanceView),
124
      m_firstBlockSize(0),
125
      m_secondBlockSize(0),
126
      m_thirdBlockSize(0),
127 128 129 130
      m_writeCommandCounter(0),
      m_firstLastReadCommandCounter(0),
      m_secondLastReadCommandCounter(0),
      m_thirdLastReadCommandCounter(0),
131 132
      m_runModus(runModus),
      m_synchronizeId(-1)
133
{
134
   Q_UNUSED(pathToQt);
135 136 137
   QString socketToken(QUuid::createUuid().toString());

   m_localServer->listen(socketToken);
138
   m_localServer->setMaxPendingConnections(3);
139

140 141
   QString applicationPath =  pathToQt + QLatin1String("/bin");
   if (runModus == TestModus) {
142
       applicationPath = QCoreApplication::applicationDirPath()
143 144
           + qmlPuppetApplicationDirectoryForTests()
           + qmlPuppetApplicationName();
145
   } else {
146
       applicationPath = macOSBundlePath(applicationPath);
Robert Loehning's avatar
Robert Loehning committed
147
       applicationPath += QLatin1Char('/') + qmlPuppetApplicationName();
148
#ifdef QT_NO_DEBUG // to prevent of choosing the wrong puppet in debug
149 150 151 152
       if (!QFileInfo(applicationPath).exists()) { //No qmlpuppet in Qt
           //We have to find out how to give not too intrusive feedback
           applicationPath =  QCoreApplication::applicationDirPath();
           applicationPath = macOSBundlePath(applicationPath);
Robert Loehning's avatar
Robert Loehning committed
153
           applicationPath += QLatin1Char('/') + qmlPuppetApplicationName();
154
       }
155
#endif
156
   }
157

158

159
   QByteArray envImportPath = qgetenv("QTCREATOR_QMLPUPPET_PATH");
160
   if (!envImportPath.isEmpty())
161 162
       applicationPath = envImportPath;

163
   QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
164

165
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) && (defined(Q_OS_MAC) || defined(Q_OS_LINUX))
Laurent Montel's avatar
Laurent Montel committed
166
   environment.insert(QLatin1String("DESIGNER_DONT_USE_SHARED_MEMORY"), QLatin1String("1"));
167 168
#endif

169 170
   if (QFileInfo(applicationPath).exists()) {
       m_qmlPuppetEditorProcess = new QProcess;
171
       m_qmlPuppetEditorProcess->setProcessEnvironment(environment);
172
       m_qmlPuppetEditorProcess->setObjectName("EditorProcess");
173 174 175
       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();
176 177 178 179
       if (fowardQmlpuppetOutput) {
           m_qmlPuppetEditorProcess->setProcessChannelMode(QProcess::MergedChannels);
           connect(m_qmlPuppetEditorProcess.data(), SIGNAL(readyRead()), this, SLOT(printEditorProcessOutput()));
       }
180
       m_qmlPuppetEditorProcess->start(applicationPath, QStringList() << socketToken << "editormode" << "-graphicssystem raster");
181

182 183
       if (runModus == NormalModus) {
           m_qmlPuppetPreviewProcess = new QProcess;
184
           m_qmlPuppetPreviewProcess->setProcessEnvironment(environment);
185
           m_qmlPuppetPreviewProcess->setObjectName("PreviewProcess");
186 187
           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()));
188 189 190 191
           if (fowardQmlpuppetOutput) {
               m_qmlPuppetPreviewProcess->setProcessChannelMode(QProcess::MergedChannels);
               connect(m_qmlPuppetPreviewProcess.data(), SIGNAL(readyRead()), this, SLOT(printPreviewProcessOutput()));
           }
192
           m_qmlPuppetPreviewProcess->start(applicationPath, QStringList() << socketToken << "previewmode" << "-graphicssystem raster");
193

194
           m_qmlPuppetRenderProcess = new QProcess;
195
           m_qmlPuppetRenderProcess->setProcessEnvironment(environment);
196
           m_qmlPuppetRenderProcess->setObjectName("RenderProcess");
197 198
           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()));
199 200 201 202
           if (fowardQmlpuppetOutput) {
               m_qmlPuppetRenderProcess->setProcessChannelMode(QProcess::MergedChannels);
               connect(m_qmlPuppetRenderProcess.data(), SIGNAL(readyRead()), this, SLOT(printRenderProcessOutput()));
           }
203
           m_qmlPuppetRenderProcess->start(applicationPath, QStringList() << socketToken << "rendermode" << "-graphicssystem raster");
204

205
       }
206

207
       connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(deleteLater()));
208

209 210
       if (m_qmlPuppetEditorProcess->waitForStarted(10000)) {
           connect(m_qmlPuppetEditorProcess.data(), SIGNAL(finished(int)), m_qmlPuppetEditorProcess.data(),SLOT(deleteLater()));
211

212 213 214
           if (runModus == NormalModus) {
               m_qmlPuppetPreviewProcess->waitForStarted();
               connect(m_qmlPuppetPreviewProcess.data(), SIGNAL(finished(int)), m_qmlPuppetPreviewProcess.data(),SLOT(deleteLater()));
215

216 217 218
               m_qmlPuppetRenderProcess->waitForStarted();
               connect(m_qmlPuppetRenderProcess.data(), SIGNAL(finished(int)), m_qmlPuppetRenderProcess.data(),SLOT(deleteLater()));
           }
219

220 221
           if (!m_localServer->hasPendingConnections())
               m_localServer->waitForNewConnection(10000);
222

223 224
           m_firstSocket = m_localServer->nextPendingConnection();
           connect(m_firstSocket.data(), SIGNAL(readyRead()), this, SLOT(readFirstDataStream()));
225

226 227 228
           if (runModus == NormalModus) {
               if (!m_localServer->hasPendingConnections())
                   m_localServer->waitForNewConnection(10000);
229

230 231
               m_secondSocket = m_localServer->nextPendingConnection();
               connect(m_secondSocket.data(), SIGNAL(readyRead()), this, SLOT(readSecondDataStream()));
232

233 234
               if (!m_localServer->hasPendingConnections())
                   m_localServer->waitForNewConnection(10000);
235

236 237 238
               m_thirdSocket = m_localServer->nextPendingConnection();
               connect(m_thirdSocket.data(), SIGNAL(readyRead()), this, SLOT(readThirdDataStream()));
           }
239

240
       } else {
241 242 243 244 245
           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));
246
       }
247

248 249 250
       m_localServer->close();

   } else {
251
           QMessageBox::warning(0, tr("Cannot Find QML Puppet Executable"), missingQmlPuppetErrorMessage(applicationPath));
252
   }
253 254 255 256 257 258 259

   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;
   }
260 261 262 263
}

NodeInstanceServerProxy::~NodeInstanceServerProxy()
{
264 265
    disconnect(this, SLOT(processFinished(int,QProcess::ExitStatus)));

266 267
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

268 269 270 271 272 273
    if (m_firstSocket)
        m_firstSocket->close();

    if (m_secondSocket)
        m_secondSocket->close();

274
    if (m_thirdSocket)
275 276
        m_thirdSocket->close();

277

278
    if (m_qmlPuppetEditorProcess)
279
        QTimer::singleShot(3000, m_qmlPuppetEditorProcess.data(), SLOT(terminate()));
280

281
    if (m_qmlPuppetPreviewProcess)
282
        QTimer::singleShot(3000, m_qmlPuppetPreviewProcess.data(), SLOT(terminate()));
283 284

    if (m_qmlPuppetRenderProcess)
285
         QTimer::singleShot(3000, m_qmlPuppetRenderProcess.data(), SLOT(terminate()));
286 287 288 289 290 291 292
}

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");
293
    static const int childrenChangedCommandType = QMetaType::type("ChildrenChangedCommand");
294
    static const int statePreviewImageChangedCommandType = QMetaType::type("StatePreviewImageChangedCommand");
295
    static const int componentCompletedCommandType = QMetaType::type("ComponentCompletedCommand");
296
    static const int synchronizeCommandType = QMetaType::type("SynchronizeCommand");
297
    static const int tokenCommandType = QMetaType::type("TokenCommand");
Marco Bubke's avatar
Marco Bubke committed
298
    static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
299

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

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

328 329
QString NodeInstanceServerProxy::missingQmlPuppetErrorMessage(const QString &applicationPath) const
{
330 331 332 333 334 335 336 337
    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>";
338
    if (hasQtQuick2(m_nodeInstanceView.data())) {
339 340 341 342 343 344 345 346 347
        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>";
348
    }
349
    str << "</p></body></html>";
350 351 352
    return message;
}

353
static void writeCommandToIODecive(const QVariant &command, QIODevice *ioDevice, unsigned int commandCounter)
354
{
355
    if (ioDevice) {
356 357
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
358
        out.setVersion(QDataStream::Qt_4_8);
359
        out << quint32(0);
360
        out << quint32(commandCounter);
361 362 363 364
        out << command;
        out.device()->seek(0);
        out << quint32(block.size() - sizeof(quint32));

365
        ioDevice->write(block);
366
    }
367 368 369 370
}

void NodeInstanceServerProxy::writeCommand(const QVariant &command)
{
371 372 373 374 375 376 377 378 379 380
    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();
    }

381
    m_writeCommandCounter++;
382 383 384 385 386
    if (m_runModus == TestModus) {
        static int synchronizeId = 0;
        synchronizeId++;
        SynchronizeCommand synchronizeCommand(synchronizeId);

387
        writeCommandToIODecive(QVariant::fromValue(synchronizeCommand), m_firstSocket.data(), m_writeCommandCounter);
388
        m_writeCommandCounter++;
389

390
        while (m_firstSocket->waitForReadyRead(100)) {
391 392 393 394 395
                readFirstDataStream();
                if (m_synchronizeId == synchronizeId)
                    return;
        }
    }
396 397
}

398
void NodeInstanceServerProxy::processFinished(int /*exitCode*/, QProcess::ExitStatus exitStatus)
399
{
400
    qDebug() << "Process finished:" << sender();
401

402 403 404
    if (m_captureFileForTest.isOpen()) {
        m_captureFileForTest.close();
        m_captureFileForTest.remove();
405 406
        QMessageBox::warning(0, tr("QML Puppet Crashed"), tr("Your are recording a Puppet stream and the puppet crashed. "
                                                             "It is recommended to reopen the QML Designer and start again."));
407 408 409
    }


410 411
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

412 413 414 415
    if (m_firstSocket)
        m_firstSocket->close();
    if (m_secondSocket)
        m_secondSocket->close();
416 417 418
    if (m_thirdSocket)
        m_thirdSocket->close();

419 420
    if (exitStatus == QProcess::CrashExit)
        emit processCrashed();
421 422
}

423

424 425 426 427 428 429 430 431 432
void NodeInstanceServerProxy::readFirstDataStream()
{
    QList<QVariant> commandList;

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

        QDataStream in(m_firstSocket.data());
433
        in.setVersion(QDataStream::Qt_4_8);
434

435
        if (m_firstBlockSize == 0)
436 437 438 439 440
            in >> m_firstBlockSize;

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

441 442 443 444 445 446 447 448
        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;


449 450 451 452 453 454 455 456 457 458 459 460 461
        QVariant command;
        in >> command;
        m_firstBlockSize = 0;

        commandList.append(command);
    }

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

void NodeInstanceServerProxy::readSecondDataStream()
462 463 464
{
    QList<QVariant> commandList;

465 466
    while (!m_secondSocket->atEnd()) {
        if (m_secondSocket->bytesAvailable() < int(sizeof(quint32)))
467 468
            break;

469
        QDataStream in(m_secondSocket.data());
470
        in.setVersion(QDataStream::Qt_4_8);
471

472
        if (m_secondBlockSize == 0)
473
            in >> m_secondBlockSize;
474

475
        if (m_secondSocket->bytesAvailable() < m_secondBlockSize)
476 477
            break;

478 479 480 481 482 483 484 485
        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;


486 487
        QVariant command;
        in >> command;
488
        m_secondBlockSize = 0;
489 490 491 492 493 494 495 496 497

        commandList.append(command);
    }

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

498 499 500 501 502 503 504 505 506
void NodeInstanceServerProxy::readThirdDataStream()
{
    QList<QVariant> commandList;

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

        QDataStream in(m_thirdSocket.data());
507
        in.setVersion(QDataStream::Qt_4_8);
508

509
        if (m_thirdBlockSize == 0)
510 511 512 513 514
            in >> m_thirdBlockSize;

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

515 516 517 518 519 520 521 522
        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;


523 524 525 526 527 528 529 530 531 532 533 534
        QVariant command;
        in >> command;
        m_thirdBlockSize = 0;

        commandList.append(command);
    }

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

535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
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";
}

566 567
QString NodeInstanceServerProxy::qmlPuppetApplicationName() const
{
568 569 570
    if (hasQtQuick2(m_nodeInstanceView.data()))
        return QLatin1String("qml2puppet" QTC_HOST_EXE_SUFFIX);
    return QLatin1String("qmlpuppet" QTC_HOST_EXE_SUFFIX);
571 572 573 574 575
}

QString NodeInstanceServerProxy::macOSBundlePath(const QString &path) const
{
    QString applicationPath = path;
576 577 578 579 580 581 582
    if (Utils::HostOsInfo::isMacHost()) {
        if (hasQtQuick2(m_nodeInstanceView.data()))
            applicationPath += QLatin1String("/qml2puppet.app/Contents/MacOS");
        else
            applicationPath += QLatin1String("/qmlpuppet.app/Contents/MacOS");

    }
583 584
   return applicationPath;
}
585

586 587 588 589 590 591 592 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
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));
}

626 627 628 629 630
void NodeInstanceServerProxy::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
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));
}

646 647 648 649
void NodeInstanceServerProxy::completeComponent(const CompleteComponentCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}
650

651
void NodeInstanceServerProxy::changeNodeSource(const ChangeNodeSourceCommand &command)
652 653 654 655
{
    writeCommand(QVariant::fromValue(command));
}

656 657 658 659 660
void NodeInstanceServerProxy::token(const TokenCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

661 662 663 664 665
void NodeInstanceServerProxy::removeSharedMemory(const RemoveSharedMemoryCommand &command)
{
   writeCommand(QVariant::fromValue(command));
}

666
} // namespace QmlDesigner