qmlenginedebugclient.cpp 11.9 KB
Newer Older
hjk's avatar
hjk committed
1
/**************************************************************************
2
**
hjk's avatar
hjk committed
3
** This file is part of Qt Creator
4
**
hjk's avatar
hjk committed
5
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
8 9
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
10 11 12 13 14 15 16
**
** 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.
17 18
**
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20 21
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
22
** Other Usage
23
**
hjk's avatar
hjk committed
24 25
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
26
**
hjk's avatar
hjk committed
27
** If you have questions regarding the use of this file, please contact
28
** Nokia at qt-info@nokia.com.
29
**
hjk's avatar
hjk committed
30
**************************************************************************/
31

32
#include "qmlenginedebugclient.h"
33 34 35

namespace QmlJsDebugClient {

36
struct QmlObjectData {
37 38 39 40 41 42 43 44 45
    QUrl url;
    int lineNumber;
    int columnNumber;
    QString idString;
    QString objectName;
    QString objectType;
    int objectId;
    int contextId;
};
46

47
QDataStream &operator>>(QDataStream &ds, QmlObjectData &data)
48 49
{
    ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString
50
       >> data.objectName >> data.objectType >> data.objectId >> data.contextId;
51 52
    return ds;
}
53

54
struct QmlObjectProperty {
55 56 57 58 59 60 61 62
    enum Type { Unknown, Basic, Object, List, SignalProperty };
    Type type;
    QString name;
    QVariant value;
    QString valueTypeName;
    QString binding;
    bool hasNotifySignal;
};
63

64
QDataStream &operator>>(QDataStream &ds, QmlObjectProperty &data)
65 66 67 68
{
    int type;
    ds >> type >> data.name >> data.value >> data.valueTypeName
       >> data.binding >> data.hasNotifySignal;
69
    data.type = (QmlObjectProperty::Type)type;
70 71 72
    return ds;
}

73 74 75
void QmlEngineDebugClient::decode(QDataStream &ds,
                                   QmlDebugObjectReference &o,
                                   bool simple)
76
{
77
    QmlObjectData data;
78 79
    ds >> data;
    o.m_debugId = data.objectId;
80
    o.m_className = data.objectType;
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
    o.m_idString = data.idString;
    o.m_name = data.objectName;
    o.m_source.m_url = data.url;
    o.m_source.m_lineNumber = data.lineNumber;
    o.m_source.m_columnNumber = data.columnNumber;
    o.m_contextDebugId = data.contextId;

    if (simple)
        return;

    int childCount;
    bool recur;
    ds >> childCount >> recur;

    for (int ii = 0; ii < childCount; ++ii) {
96
        o.m_children.append(QmlDebugObjectReference());
97 98 99 100 101 102 103
        decode(ds, o.m_children.last(), !recur);
    }

    int propCount;
    ds >> propCount;

    for (int ii = 0; ii < propCount; ++ii) {
104
        QmlObjectProperty data;
105
        ds >> data;
106
        QmlDebugPropertyReference prop;
107 108 109 110 111 112
        prop.m_objectDebugId = o.m_debugId;
        prop.m_name = data.name;
        prop.m_binding = data.binding;
        prop.m_hasNotifySignal = data.hasNotifySignal;
        prop.m_valueTypeName = data.valueTypeName;
        switch (data.type) {
113 114 115
        case QmlObjectProperty::Basic:
        case QmlObjectProperty::List:
        case QmlObjectProperty::SignalProperty:
116 117 118 119
        {
            prop.m_value = data.value;
            break;
        }
120
        case QmlObjectProperty::Object:
121
        {
122
            QmlDebugObjectReference obj;
123 124 125 126
            obj.m_debugId = prop.m_value.toInt();
            prop.m_value = qVariantFromValue(obj);
            break;
        }
127
        case QmlObjectProperty::Unknown:
128
            break;
129 130 131 132 133
        }
        o.m_properties << prop;
    }
}

134 135
void QmlEngineDebugClient::decode(QDataStream &ds,
                                   QmlDebugContextReference &c)
136 137 138 139 140 141 142
{
    ds >> c.m_name >> c.m_debugId;

    int contextCount;
    ds >> contextCount;

    for (int ii = 0; ii < contextCount; ++ii) {
143
        c.m_contexts.append(QmlDebugContextReference());
144 145 146 147 148 149 150
        decode(ds, c.m_contexts.last());
    }

    int objectCount;
    ds >> objectCount;

    for (int ii = 0; ii < objectCount; ++ii) {
151
        QmlDebugObjectReference obj;
152 153 154 155 156 157
        decode(ds, obj, true);
        obj.m_contextDebugId = c.m_debugId;
        c.m_objects << obj;
    }
}

158
void QmlEngineDebugClient::statusChanged(Status status)
159
{
160
    emit newStatus(status);
161 162
}

163
void QmlEngineDebugClient::messageReceived(const QByteArray &data)
164 165
{
    QDataStream ds(data);
166
    int queryId;
167 168 169
    QByteArray type;
    ds >> type;

170 171 172 173
    if (type == "OBJECT_CREATED") {
        emit newObjects();
        return;
    }
174

175
    ds >> queryId;
176

177
    if (type == "LIST_ENGINES_R") {
178 179
        int count;
        ds >> count;
180
        QmlDebugEngineReferenceList engines;
181
        for (int ii = 0; ii < count; ++ii) {
182 183 184 185
            QmlDebugEngineReference eng;
            ds >> eng.m_name;
            ds >> eng.m_debugId;
            engines << eng;
186
        }
187
        emit result(queryId, QVariant::fromValue(engines));
188
    } else if (type == "LIST_OBJECTS_R") {
189
        QmlDebugContextReference rootContext;
190
        if (!ds.atEnd())
191 192
            decode(ds, rootContext);
        emit result(queryId, QVariant::fromValue(rootContext));
193
    } else if (type == "FETCH_OBJECT_R") {
194
        QmlDebugObjectReference object;
195
        if (!ds.atEnd())
196 197 198 199 200 201 202 203 204 205 206 207
            decode(ds, object, false);
        emit result(queryId, QVariant::fromValue(object));
    } else if (type == "EVAL_EXPRESSION_R") {;
        QVariant exprResult;
        ds >> exprResult;
        emit result(queryId, exprResult);
    } else if (type == "WATCH_PROPERTY_R" ||
               type == "WATCH_OBJECT_R" ||
               type == "WATCH_EXPR_OBJECT_R") {
        bool valid;
        ds >> valid;
        emit result(queryId, valid);
208 209 210 211
    } else if (type == "UPDATE_WATCH") {
        int debugId;
        QByteArray name;
        QVariant value;
212 213
        ds >> debugId >> name >> value;
        emit valueChanged(debugId, name, value);
214 215 216
    }
}

217 218 219 220
QmlEngineDebugClient::QmlEngineDebugClient(
        QDeclarativeDebugConnection *connection)
    : QDeclarativeDebugClient(QLatin1String("QDeclarativeEngine"), connection),
      m_nextId(1)
221 222
{
}
223

224
quint32 QmlEngineDebugClient::addWatch(const QmlDebugPropertyReference &property)
225
{
226
    quint32 id;
227
    if (status() == QDeclarativeDebugClient::Enabled) {
228
        id = getId();
229 230
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
231 232
        ds << QByteArray("WATCH_PROPERTY") << id << property.m_objectDebugId
           << property.m_name.toUtf8();
233
        sendMessage(message);
234
    }
235
    return id;
236 237
}

238 239
quint32 QmlEngineDebugClient::addWatch(const QmlDebugContextReference &/*context*/,
                                       const QString &/*id*/)
240
{
241
    qWarning("QmlEngineDebugClient::addWatch(): Not implemented");
242 243 244
    return 0;
}

245 246
quint32 QmlEngineDebugClient::addWatch(const QmlDebugObjectReference &object,
                                       const QString &expr)
247
{
248
    quint32 id = 0;
249
    if (status() == QDeclarativeDebugClient::Enabled) {
250
        id = getId();
251 252
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
253
        ds << QByteArray("WATCH_EXPR_OBJECT") << id << object.m_debugId << expr;
254
        sendMessage(message);
255
    }
256
    return id;
257 258
}

259
quint32 QmlEngineDebugClient::addWatch(const QmlDebugObjectReference &object)
260
{
261
    quint32 id = 0;
262
    if (status() == QDeclarativeDebugClient::Enabled) {
263
        id = getId();
264 265
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
266
        ds << QByteArray("WATCH_OBJECT") << id << object.m_debugId;
267
        sendMessage(message);
268
    }
269
    return id;
270 271
}

272
quint32 QmlEngineDebugClient::addWatch(const QmlDebugFileReference &/*file*/)
273
{
274
    qWarning("QmlEngineDebugClient::addWatch(): Not implemented");
275 276 277
    return 0;
}

278
void QmlEngineDebugClient::removeWatch(quint32 id)
279
{
280
    if (status() == QDeclarativeDebugClient::Enabled) {
281 282
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
283
        ds << QByteArray("NO_WATCH") << id;
284
        sendMessage(message);
285 286 287
    }
}

288
quint32 QmlEngineDebugClient::queryAvailableEngines()
289
{
290
    quint32 id = 0;
291
    if (status() == QDeclarativeDebugClient::Enabled) {
292
        id = getId();
293 294
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
295
        ds << QByteArray("LIST_ENGINES") << id;
296
        sendMessage(message);
297
    }
298
    return id;
299 300
}

301
quint32 QmlEngineDebugClient::queryRootContexts(const QmlDebugEngineReference &engine)
302
{
303 304 305
    quint32 id = 0;
    if (status() == QDeclarativeDebugClient::Enabled && engine.m_debugId != -1) {
        id = getId();
306 307
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
308
        ds << QByteArray("LIST_OBJECTS") << id << engine.m_debugId;
309
        sendMessage(message);
310
    }
311
    return id;
312 313
}

314
quint32 QmlEngineDebugClient::queryObject(const QmlDebugObjectReference &object)
315
{
316 317 318
    quint32 id = 0;
    if (status() == QDeclarativeDebugClient::Enabled && object.m_debugId != -1) {
        id = getId();
319 320
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
321 322
        ds << QByteArray("FETCH_OBJECT") << id << object.m_debugId << false <<
              true;
323
        sendMessage(message);
324
    }
325
    return id;
326 327
}

328
quint32 QmlEngineDebugClient::queryObjectRecursive(const QmlDebugObjectReference &object)
329
{
330 331 332
    quint32 id = 0;
    if (status() == QDeclarativeDebugClient::Enabled && object.m_debugId != -1) {
        id = getId();
333 334
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
335 336
        ds << QByteArray("FETCH_OBJECT") << id << object.m_debugId << true <<
              true;
337
        sendMessage(message);
338
    }
339
    return id;
340 341
}

342 343
quint32 QmlEngineDebugClient::queryExpressionResult(int objectDebugId,
                                                    const QString &expr)
344
{
345
    quint32 id = 0;
346
    if (status() == QDeclarativeDebugClient::Enabled && objectDebugId != -1) {
347
        id = getId();
348 349
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
350
        ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr;
351
        sendMessage(message);
352
    }
353
    return id;
354 355
}

356 357 358 359 360 361
quint32 QmlEngineDebugClient::setBindingForObject(
        int objectDebugId,
        const QString &propertyName,
        const QVariant &bindingExpression,
        bool isLiteralValue,
        QString source, int line)
362
{
363
    quint32 id = 0;
364
    if (status() == QDeclarativeDebugClient::Enabled && objectDebugId != -1) {
365
        id = getId();
366 367
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
368 369
        ds << QByteArray("SET_BINDING") << objectDebugId << propertyName
           << bindingExpression << isLiteralValue << source << line;
370
        sendMessage(message);
371
    }
372
    return id;
373 374
}

375 376 377
quint32 QmlEngineDebugClient::resetBindingForObject(
        int objectDebugId,
        const QString &propertyName)
378
{
379
    quint32 id = 0;
380
    if (status() == QDeclarativeDebugClient::Enabled && objectDebugId != -1) {
381
        id = getId();
382 383 384
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
        ds << QByteArray("RESET_BINDING") << objectDebugId << propertyName;
385
        sendMessage(message);
386
    }
387
    return id;
388 389
}

390 391 392
quint32 QmlEngineDebugClient::setMethodBody(
        int objectDebugId, const QString &methodName,
        const QString &methodBody)
393
{
394
    quint32 id = 0;
395
    if (status() == QDeclarativeDebugClient::Enabled && objectDebugId != -1) {
396
        id = getId();
397 398
        QByteArray message;
        QDataStream ds(&message, QIODevice::WriteOnly);
399 400
        ds << QByteArray("SET_METHOD_BODY") << objectDebugId
           << methodName << methodBody;
401
        sendMessage(message);
402
    }
403
    return id;
404 405
}

406
} // namespace QmlJsDebugClient