diff --git a/src/libs/qmljsdebugclient/qmlenginedebugclient.cpp b/src/libs/qmljsdebugclient/qmlenginedebugclient.cpp index 9c58db74478..93048adc3ed 100644 --- a/src/libs/qmljsdebugclient/qmlenginedebugclient.cpp +++ b/src/libs/qmljsdebugclient/qmlenginedebugclient.cpp @@ -185,27 +185,27 @@ void QmlEngineDebugClient::messageReceived(const QByteArray &data) ds >> eng.m_debugId; engines << eng; } - emit result(queryId, QVariant::fromValue(engines)); + emit result(queryId, QVariant::fromValue(engines), type); } else if (type == "LIST_OBJECTS_R") { QmlDebugContextReference rootContext; if (!ds.atEnd()) decode(ds, rootContext); - emit result(queryId, QVariant::fromValue(rootContext)); + emit result(queryId, QVariant::fromValue(rootContext), type); } else if (type == "FETCH_OBJECT_R") { QmlDebugObjectReference object; if (!ds.atEnd()) decode(ds, object, false); - emit result(queryId, QVariant::fromValue(object)); + emit result(queryId, QVariant::fromValue(object), type); } else if (type == "EVAL_EXPRESSION_R") {; QVariant exprResult; ds >> exprResult; - emit result(queryId, exprResult); + emit result(queryId, exprResult, type); } else if (type == "WATCH_PROPERTY_R" || type == "WATCH_OBJECT_R" || type == "WATCH_EXPR_OBJECT_R") { bool valid; ds >> valid; - emit result(queryId, valid); + emit result(queryId, valid, type); } else if (type == "UPDATE_WATCH") { int debugId; QByteArray name; diff --git a/src/libs/qmljsdebugclient/qmlenginedebugclient.h b/src/libs/qmljsdebugclient/qmlenginedebugclient.h index ce1dd722788..2e3854d224c 100644 --- a/src/libs/qmljsdebugclient/qmlenginedebugclient.h +++ b/src/libs/qmljsdebugclient/qmlenginedebugclient.h @@ -81,7 +81,7 @@ signals: void newObjects(); void valueChanged(int debugId, const QByteArray &name, const QVariant &value); - void result(quint32 queryId, const QVariant &result); + void result(quint32 queryId, const QVariant &result, const QByteArray &type); protected: virtual void statusChanged(Status status); diff --git a/src/libs/utils/crumblepath.cpp b/src/libs/utils/crumblepath.cpp index 80c273c97b7..069b0f197f6 100644 --- a/src/libs/utils/crumblepath.cpp +++ b/src/libs/utils/crumblepath.cpp @@ -284,6 +284,11 @@ QVariant CrumblePath::dataForLastIndex() const return d->m_buttons.last()->data(); } +int CrumblePath::length() const +{ + return d->m_buttons.length(); +} + void CrumblePath::pushElement(const QString &title, const QVariant &data) { CrumblePathButton *newButton = new CrumblePathButton(title, this); diff --git a/src/libs/utils/crumblepath.h b/src/libs/utils/crumblepath.h index c5066c41c88..874adb64058 100644 --- a/src/libs/utils/crumblepath.h +++ b/src/libs/utils/crumblepath.h @@ -53,6 +53,7 @@ public: void selectIndex(int index); QVariant dataForIndex(int index) const; QVariant dataForLastIndex() const; + int length() const; public slots: void pushElement(const QString &title, const QVariant &data = QVariant()); diff --git a/src/plugins/debugger/qml/qmladapter.cpp b/src/plugins/debugger/qml/qmladapter.cpp index 550527beb9d..46d9cdcb9d3 100644 --- a/src/plugins/debugger/qml/qmladapter.cpp +++ b/src/plugins/debugger/qml/qmladapter.cpp @@ -314,12 +314,12 @@ void QmlAdapter::setEngineDebugClient(QmlJsDebugClient::QmlEngineDebugClient *cl Internal::QmlEngine *engine = qobject_cast(d->m_engine.data()); if (engine && d->m_engineDebugClient) - disconnect(d->m_engineDebugClient, SIGNAL(result(quint32,QVariant)), + disconnect(d->m_engineDebugClient, SIGNAL(result(quint32,QVariant,QByteArray)), engine, SLOT(expressionEvaluated(quint32,QVariant))); d->m_engineDebugClient = client; if (engine && d->m_engineDebugClient) - connect(d->m_engineDebugClient, SIGNAL(result(quint32,QVariant)), + connect(d->m_engineDebugClient, SIGNAL(result(quint32,QVariant,QByteArray)), engine, SLOT(expressionEvaluated(quint32,QVariant))); } diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.cpp b/src/plugins/qmljsinspector/qmljsclientproxy.cpp index d188832ebd9..858fd1dd917 100644 --- a/src/plugins/qmljsinspector/qmljsclientproxy.cpp +++ b/src/plugins/qmljsinspector/qmljsclientproxy.cpp @@ -57,10 +57,6 @@ ClientProxy::ClientProxy(Debugger::QmlAdapter *adapter, QObject *parent) , m_contextQueryId(0) , m_isConnected(false) { - m_requestObjectsTimer.setSingleShot(true); - m_requestObjectsTimer.setInterval(3000); - connect(&m_requestObjectsTimer, SIGNAL(timeout()), - this, SLOT(refreshObjectTree())); connectToServer(); } @@ -135,8 +131,8 @@ void ClientProxy::engineClientStatusChanged(QDeclarativeDebugClient::Status stat if (status == QDeclarativeDebugClient::Enabled) { m_engineClient = qobject_cast(sender()); connect(m_engineClient, SIGNAL(newObjects()), this, SLOT(newObjects())); - connect(m_engineClient, SIGNAL(result(quint32,QVariant)), - SLOT(onResult(quint32,QVariant))); + connect(m_engineClient, SIGNAL(result(quint32,QVariant,QByteArray)), + SLOT(onResult(quint32,QVariant,QByteArray))); connect(m_engineClient, SIGNAL(valueChanged(int,QByteArray,QVariant)), SLOT(objectWatchTriggered(int,QByteArray,QVariant))); m_adapter.data()->setEngineDebugClient(m_engineClient); @@ -147,7 +143,6 @@ void ClientProxy::engineClientStatusChanged(QDeclarativeDebugClient::Status stat void ClientProxy::refreshObjectTree() { if (!m_contextQueryId) { - m_requestObjectsTimer.stop(); m_objectTreeQueryIds.clear(); queryEngineContext(m_engines.value(0).debugId()); } @@ -429,6 +424,12 @@ bool ClientProxy::addObjectWatch(int objectDebugId) return false; } +bool ClientProxy::isObjectBeingWatched(int objectDebugId) +{ + return m_objectWatches.contains(objectDebugId); +} + + void ClientProxy::objectWatchTriggered(int objectDebugId, const QByteArray &propertyName, const QVariant &propertyValue) @@ -476,17 +477,10 @@ void ClientProxy::queryEngineContext(int id) void ClientProxy::contextChanged(const QVariant &value) { - log(LogReceive, QString("LIST_OBJECTS_R")); + if (m_contextQueryId) { - m_rootObjects.clear(); - QmlDebugContextReference rootContext = - qvariant_cast(value); m_contextQueryId = 0; - - m_objectTreeQueryIds.clear(); - m_requestObjectsTimer.stop(); - - fetchContextObjectRecursive(rootContext); + emit rootContext(value); } } @@ -498,26 +492,33 @@ quint32 ClientProxy::fetchContextObject(const QmlDebugObjectReference& obj) } void ClientProxy::fetchContextObjectRecursive( - const QmlDebugContextReference& context) + const QmlDebugContextReference& context, bool clear) { if (!isConnected()) return; - + if (clear) { + m_rootObjects.clear(); + m_objectTreeQueryIds.clear(); + } foreach (const QmlDebugObjectReference & obj, context.objects()) { - - log(LogSend, QString("FETCH_OBJECT %1").arg(obj.idString())); - quint32 queryId = fetchContextObject(obj); if (queryId) m_objectTreeQueryIds << queryId; } foreach (const QmlDebugContextReference& child, context.contexts()) { - fetchContextObjectRecursive(child); + fetchContextObjectRecursive(child, false); } } -void ClientProxy::onResult(quint32 queryId, const QVariant &value) +void ClientProxy::onResult(quint32 queryId, const QVariant &value, const QByteArray &type) { + if (type == "FETCH_OBJECT_R") { + log(LogReceive, QString("FETCH_OBJECT_R %1").arg( + qvariant_cast(value).idString())); + } else { + log(LogReceive, QLatin1String(type)); + } + if (m_objectTreeQueryIds.contains(queryId)) objectTreeFetched(queryId, value); else if (queryId == m_engineQueryId) @@ -531,9 +532,6 @@ void ClientProxy::onResult(quint32 queryId, const QVariant &value) void ClientProxy::objectTreeFetched(quint32 queryId, const QVariant &result) { QmlDebugObjectReference obj = qvariant_cast(result); - - log(LogReceive, QString("FETCH_OBJECT_R %1").arg(obj.idString())); - m_rootObjects.append(obj); m_objectTreeQueryIds.removeOne(queryId); @@ -686,8 +684,6 @@ QList ClientProxy::engines() const void ClientProxy::updateEngineList(const QVariant &value) { - log(LogReceive, QString("LIST_ENGINES_R")); - m_engines = qvariant_cast(value); m_engineQueryId = 0; emit enginesChanged(); @@ -706,6 +702,5 @@ bool ClientProxy::isConnected() const void ClientProxy::newObjects() { log(LogReceive, QString("OBJECT_CREATED")); - if (!m_requestObjectsTimer.isActive()) - m_requestObjectsTimer.start(); + refreshObjectTree(); } diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.h b/src/plugins/qmljsinspector/qmljsclientproxy.h index be8befa2ef7..bdc48bb8f0f 100644 --- a/src/plugins/qmljsinspector/qmljsclientproxy.h +++ b/src/plugins/qmljsinspector/qmljsclientproxy.h @@ -73,6 +73,7 @@ public: void clearComponentCache(); bool addObjectWatch(int objectDebugId); + bool isObjectBeingWatched(int objectDebugId); bool removeObjectWatch(int objectDebugId); void removeAllObjectWatches(); @@ -95,6 +96,7 @@ public: quint32 fetchContextObject(const QmlDebugObjectReference& obj); void addObjectToTree(const QmlDebugObjectReference &obj); + void fetchContextObjectRecursive(const QmlDebugContextReference &context, bool clear); signals: void objectTreeUpdated(); @@ -119,6 +121,7 @@ signals: void propertyChanged(int debugId, const QByteArray &propertyName, const QVariant &propertyValue); void result(quint32 queryId, const QVariant &result); + void rootContext(const QVariant &context); public slots: void refreshObjectTree(); @@ -143,10 +146,9 @@ private slots: void engineClientStatusChanged(QDeclarativeDebugClient::Status status); void onCurrentObjectsChanged(const QList &debugIds, bool requestIfNeeded = true); - void fetchContextObjectRecursive(const QmlDebugContextReference &context); void newObjects(); void objectWatchTriggered(int debugId, const QByteArray &propertyName, const QVariant &propertyValue); - void onResult(quint32 queryId, const QVariant &result); + void onResult(quint32 queryId, const QVariant &value, const QByteArray &type); private: void contextChanged(const QVariant &value); @@ -178,7 +180,6 @@ private: QList m_rootObjects; QmlDebugEngineReferenceList m_engines; - QTimer m_requestObjectsTimer; DebugIdHash m_debugIdHash; QList m_objectWatches; diff --git a/src/plugins/qmljsinspector/qmljsinspector.cpp b/src/plugins/qmljsinspector/qmljsinspector.cpp index e92ddb33fa6..9a6116a321f 100644 --- a/src/plugins/qmljsinspector/qmljsinspector.cpp +++ b/src/plugins/qmljsinspector/qmljsinspector.cpp @@ -277,6 +277,15 @@ void InspectorUi::onResult(quint32 queryId, const QVariant &result) return; } + if (m_updateObjectQueryIds.contains(queryId)) { + m_updateObjectQueryIds.removeOne(queryId); + QmlDebugObjectReference obj = qvariant_cast(result); + m_clientProxy->addObjectToTree(obj); + if (m_updateObjectQueryIds.empty()) + showObject(obj); + return; + } + if (m_debugQuery != queryId) return; @@ -349,13 +358,28 @@ void InspectorUi::disconnected() setDebuggerEngine(0); } +void InspectorUi::onRootContext(const QVariant &value) +{ + if (m_crumblePath->dataForLastIndex().toInt() < 0) { + m_clientProxy->fetchContextObjectRecursive( + qvariant_cast( + value), true); + } else { + for (int i = 1; i < m_crumblePath->length(); i++) { + m_updateObjectQueryIds << m_clientProxy->fetchContextObject( + m_crumblePath->dataForIndex(i).toInt()); + } + } +} + void InspectorUi::objectTreeReady() { - // Should only run once, after debugger startup - if (!m_clientProxy->rootObjectReference().isEmpty()) { + if (m_crumblePath->dataForLastIndex().toInt() >= 0) { + selectItems(QList() << + m_clientProxy->objectReferenceForId( + m_crumblePath->dataForLastIndex().toInt())); + } else if (!m_clientProxy->rootObjectReference().isEmpty()) { selectItems(m_clientProxy->rootObjectReference()); - disconnect(m_clientProxy, SIGNAL(objectTreeUpdated()), - this, SLOT(objectTreeReady())); } } @@ -553,8 +577,8 @@ void InspectorUi::selectItems(const QList &objectRefere int debugId = objref.debugId(); if (debugId != -1) { // select only the first valid element of the list - - m_clientProxy->removeAllObjectWatches(); + if (!m_clientProxy->isObjectBeingWatched(debugId)) + m_clientProxy->removeAllObjectWatches(); //Check if the object is complete if (objref.needsMoreData()) m_showObjectQueryId = m_clientProxy->fetchContextObject(objref); @@ -842,6 +866,8 @@ void InspectorUi::connectSignals() this, SLOT(serverReloaded())); connect(m_clientProxy, SIGNAL(objectTreeUpdated()), this, SLOT(objectTreeReady())); + connect(m_clientProxy, SIGNAL(rootContext(QVariant)), + this, SLOT(onRootContext(QVariant))); connect(m_clientProxy, SIGNAL(connected()), this, SLOT(enable())); connect(m_clientProxy, SIGNAL(disconnected()), diff --git a/src/plugins/qmljsinspector/qmljsinspector.h b/src/plugins/qmljsinspector/qmljsinspector.h index 815c1dd33e6..aaa8c7625c3 100644 --- a/src/plugins/qmljsinspector/qmljsinspector.h +++ b/src/plugins/qmljsinspector/qmljsinspector.h @@ -121,6 +121,7 @@ private slots: void changeSelectedItems(const QList &objects); void changePropertyValue(int debugId,const QString &propertyName, const QString &valueExpression); void objectTreeReady(); + void onRootContext(const QVariant &value); void updateEngineList(); @@ -160,6 +161,7 @@ private: QObject *m_qmlEngine; quint32 m_debugQuery; quint32 m_showObjectQueryId; + QList m_updateObjectQueryIds; // Qml/JS integration QHash m_textPreviews;