diff options
Diffstat (limited to 'libs/qmldebug/qmltoolsclient.cpp')
-rw-r--r-- | libs/qmldebug/qmltoolsclient.cpp | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/libs/qmldebug/qmltoolsclient.cpp b/libs/qmldebug/qmltoolsclient.cpp new file mode 100644 index 00000000000..12f876b2b8e --- /dev/null +++ b/libs/qmldebug/qmltoolsclient.cpp @@ -0,0 +1,348 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 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 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmltoolsclient.h" +#include <QStringList> + +//INSPECTOR SERVICE PROTOCOL +// <HEADER><COMMAND><DATA> +// <HEADER> : <type{request, response, event}><requestId/eventId>[<response_success_bool>] +// <COMMAND> : {"enable", "disable", "select", "reload", "setAnimationSpeed", +// "showAppOnTop", "createObject", "destroyObject", "moveObject", +// "clearCache"} +// <DATA> : select: <debugIds_int_list> +// reload: <hash<changed_filename_string, filecontents_bytearray>> +// setAnimationSpeed: <speed_real> +// showAppOnTop: <set_bool> +// createObject: <qml_string><parentId_int><imports_string_list><filename_string> +// destroyObject: <debugId_int> +// moveObject: <debugId_int><newParentId_int> +// clearCache: void + +const char REQUEST[] = "request"; +const char RESPONSE[] = "response"; +const char EVENT[] = "event"; +const char ENABLE[] = "enable"; +const char DISABLE[] = "disable"; +const char SELECT[] = "select"; +const char RELOAD[] = "reload"; +const char SET_ANIMATION_SPEED[] = "setAnimationSpeed"; +const char SHOW_APP_ON_TOP[] = "showAppOnTop"; +const char CREATE_OBJECT[] = "createObject"; +const char DESTROY_OBJECT[] = "destroyObject"; +const char MOVE_OBJECT[] = "moveObject"; +const char CLEAR_CACHE[] = "clearCache"; + +namespace QmlDebug { + +QmlToolsClient::QmlToolsClient(QmlDebugConnection *client) + : BaseToolsClient(client, QLatin1String("QmlInspector")), + m_connection(client), + m_requestId(0), + m_reloadQueryId(-1), + m_slowDownFactor(1), + m_destroyObjectQueryId(-1) +{ + setObjectName(name()); +} + +void QmlToolsClient::messageReceived(const QByteArray &message) +{ + QDataStream ds(message); + + QByteArray type; + int requestId; + ds >> type >> requestId; + + if (type == QByteArray(RESPONSE)) { + bool success = false; + ds >> success; + + if ((m_reloadQueryId != -1) && (m_reloadQueryId == requestId) && success) + emit reloaded(); + + if ((m_destroyObjectQueryId != -1) && (m_destroyObjectQueryId == requestId) + && success && !ds.atEnd()) { + int objectDebugId; + ds >> objectDebugId; + emit destroyedObject(objectDebugId); + } + + log(LogReceive, type, QString(QLatin1String("requestId: %1 success: %2")) + .arg(QString::number(requestId)).arg(QString::number(success))); + } else if (type == QByteArray(EVENT)) { + QByteArray event; + ds >> event; + if (event == QByteArray(SELECT)) { + m_currentDebugIds.clear(); + QList<int> debugIds; + ds >> debugIds; + + QStringList debugIdStrings; + foreach (int debugId, debugIds) { + if (debugId != -1) { + m_currentDebugIds << debugId; + debugIdStrings << QString::number(debugId); + } + } + log(LogReceive, type + ':' + event, + QString::fromLatin1("[%1]").arg(debugIdStrings.join(QLatin1String(",")))); + emit currentObjectsChanged(m_currentDebugIds); + } + } else { + log(LogReceive, type, QLatin1String("Warning: Not handling message")); + } +} + +QList<int> QmlToolsClient::currentObjects() const +{ + return m_currentDebugIds; +} + +void QmlToolsClient::setCurrentObjects(const QList<int> &debugIds) +{ + if (!m_connection || !m_connection->isConnected()) + return; + + if (debugIds == m_currentDebugIds) + return; + + m_currentDebugIds = debugIds; + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray(REQUEST) << m_requestId++ + << QByteArray(SELECT) << m_currentDebugIds; + + log(LogSend, SELECT, QString::fromLatin1("%1 [list of ids]").arg(debugIds.length())); + + sendMessage(message); +} + +void QmlToolsClient::setObjectIdList( + const QList<ObjectReference> &/*objectRoots*/) +{ + //NOT IMPLEMENTED +} + +void QmlToolsClient::clearComponentCache() +{ + if (!m_connection || !m_connection->isConnected()) + return; + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray(REQUEST) << m_requestId++ + << QByteArray(CLEAR_CACHE); + + log(LogSend, CLEAR_CACHE); + + sendMessage(message); +} + +void QmlToolsClient::reload(const QHash<QString, QByteArray> &changesHash) +{ + if (!m_connection || !m_connection->isConnected()) + return; + + m_reloadQueryId = m_requestId; + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray(REQUEST) << m_requestId++ + << QByteArray(RELOAD) << changesHash; + + log(LogSend, RELOAD); + + sendMessage(message); +} + +void QmlToolsClient::setDesignModeBehavior(bool inDesignMode) +{ + if (!m_connection || !m_connection->isConnected()) + return; + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray(REQUEST) << m_requestId++; + if (inDesignMode) + ds << QByteArray(ENABLE); + else + ds << QByteArray(DISABLE); + + log(LogSend, ENABLE, QLatin1String(inDesignMode ? "true" : "false")); + + sendMessage(message); +} + +void QmlToolsClient::setAnimationSpeed(qreal slowDownFactor) +{ + if (!m_connection || !m_connection->isConnected()) + return; + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray(REQUEST) << m_requestId++ + << QByteArray(SET_ANIMATION_SPEED) << slowDownFactor; + + log(LogSend, SET_ANIMATION_SPEED, QString::number(slowDownFactor)); + + sendMessage(message); + //Cache non-zero values + if (slowDownFactor) + m_slowDownFactor = slowDownFactor; +} + +void QmlToolsClient::setAnimationPaused(bool paused) +{ + if (paused) + setAnimationSpeed(0); + else + setAnimationSpeed(m_slowDownFactor); +} + +void QmlToolsClient::changeToSelectTool() +{ +// NOT IMPLEMENTED +} + +void QmlToolsClient::changeToSelectMarqueeTool() +{ +// NOT IMPLEMENTED +} + +void QmlToolsClient::changeToZoomTool() +{ +// NOT IMPLEMENTED +} + +void QmlToolsClient::showAppOnTop(bool showOnTop) +{ + if (!m_connection || !m_connection->isConnected()) + return; + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray(REQUEST) << m_requestId++ + << QByteArray(SHOW_APP_ON_TOP) << showOnTop; + + log(LogSend, SHOW_APP_ON_TOP, QLatin1String(showOnTop ? "true" : "false")); + + sendMessage(message); +} + +void QmlToolsClient::createQmlObject(const QString &qmlText, + int parentDebugId, + const QStringList &imports, + const QString &filename, int order) +{ + if (!m_connection || !m_connection->isConnected()) + return; + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray(REQUEST) << m_requestId++ + << QByteArray(CREATE_OBJECT) + << qmlText + << parentDebugId + << imports + << filename + << order; + + log(LogSend, CREATE_OBJECT, QString::fromLatin1("%1 %2 [%3] %4").arg(qmlText, + QString::number(parentDebugId), + imports.join(QLatin1String(",")), filename)); + + sendMessage(message); +} + +void QmlToolsClient::destroyQmlObject(int debugId) +{ + if (!m_connection || !m_connection->isConnected()) + return; + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + m_destroyObjectQueryId = m_requestId; + ds << QByteArray(REQUEST) << m_requestId++ + << QByteArray(DESTROY_OBJECT) << debugId; + + log(LogSend, DESTROY_OBJECT, QString::number(debugId)); + + sendMessage(message); +} + +void QmlToolsClient::reparentQmlObject(int debugId, int newParent) +{ + if (!m_connection || !m_connection->isConnected()) + return; + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray(REQUEST) << m_requestId++ + << QByteArray(MOVE_OBJECT) << debugId << newParent; + + log(LogSend, MOVE_OBJECT, QString::fromLatin1("%1 %2").arg(QString::number(debugId), + QString::number(newParent))); + + sendMessage(message); +} + + +void QmlToolsClient::applyChangesToQmlFile() +{ + if (!m_connection || !m_connection->isConnected()) + return; + + // TODO +} + +void QmlToolsClient::applyChangesFromQmlFile() +{ + if (!m_connection || !m_connection->isConnected()) + return; + + // TODO +} + +void QmlToolsClient::log(LogDirection direction, + const QByteArray &message, + const QString &extra) +{ + QString msg; + if (direction == LogSend) + msg += QLatin1String("sending "); + else + msg += QLatin1String("receiving "); + + msg += QLatin1String(message); + msg += QLatin1Char(' '); + msg += extra; + emit logActivity(name(), msg); +} + +} // namespace QmlDebug |