Commit b9bc68c3 authored by Aurindam Jana's avatar Aurindam Jana
Browse files

QmlInspector: Fetch objects for location



Since the object tree is fetched lazily, we might have
objects whose debugIds are not known. In such cases,
objects can be fetched by passing the location info.

Change-Id: I2001460cc14401e011efef9be9194c9f7868d617
Reviewed-by: default avatarKai Koehne <kai.koehne@nokia.com>
parent 38905e52
...@@ -138,6 +138,19 @@ void BaseEngineDebugClient::decode(QDataStream &ds, ...@@ -138,6 +138,19 @@ void BaseEngineDebugClient::decode(QDataStream &ds,
} }
} }
void BaseEngineDebugClient::decode(QDataStream &ds,
QVariantList &o,
bool simple)
{
int count;
ds >> count;
for (int i = 0; i < count; i++) {
ObjectReference obj;
decode(ds, obj, simple);
o << QVariant::fromValue(obj);
}
}
void BaseEngineDebugClient::decode(QDataStream &ds, void BaseEngineDebugClient::decode(QDataStream &ds,
ContextReference &c) ContextReference &c)
{ {
...@@ -202,6 +215,11 @@ void BaseEngineDebugClient::messageReceived(const QByteArray &data) ...@@ -202,6 +215,11 @@ void BaseEngineDebugClient::messageReceived(const QByteArray &data)
if (!ds.atEnd()) if (!ds.atEnd())
decode(ds, object, false); decode(ds, object, false);
emit result(queryId, QVariant::fromValue(object), type); emit result(queryId, QVariant::fromValue(object), type);
} else if (type == "FETCH_OBJECTS_FOR_LOCATION_R") {
QVariantList objects;
if (!ds.atEnd())
decode(ds, objects, false);
emit result(queryId, objects, type);
} else if (type == "EVAL_EXPRESSION_R") {; } else if (type == "EVAL_EXPRESSION_R") {;
QVariant exprResult; QVariant exprResult;
ds >> exprResult; ds >> exprResult;
...@@ -413,4 +431,20 @@ quint32 BaseEngineDebugClient::setMethodBody( ...@@ -413,4 +431,20 @@ quint32 BaseEngineDebugClient::setMethodBody(
return id; return id;
} }
quint32 BaseEngineDebugClient::queryObjectsForLocation(
const QString &fileName, int lineNumber, int columnNumber)
{
quint32 id = 0;
if (status() == Enabled) {
id = getId();
QByteArray message;
QDataStream ds(&message, QIODevice::WriteOnly);
ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id <<
fileName << lineNumber << columnNumber << false <<
true;
sendMessage(message);
}
return id;
}
} // namespace QmlDebug } // namespace QmlDebug
...@@ -76,6 +76,9 @@ public: ...@@ -76,6 +76,9 @@ public:
virtual quint32 setMethodBody(int objectDebugId, const QString &methodName, virtual quint32 setMethodBody(int objectDebugId, const QString &methodName,
const QString &methodBody); const QString &methodBody);
virtual quint32 queryObjectsForLocation(const QString &fileName, int lineNumber,
int columnNumber);
signals: signals:
void newStatus(QmlDebug::ClientStatus status); void newStatus(QmlDebug::ClientStatus status);
void newObjects(); void newObjects();
...@@ -91,6 +94,7 @@ protected: ...@@ -91,6 +94,7 @@ protected:
void decode(QDataStream &d, ContextReference &context); void decode(QDataStream &d, ContextReference &context);
void decode(QDataStream &d, ObjectReference &object, bool simple); void decode(QDataStream &d, ObjectReference &object, bool simple);
void decode(QDataStream &d, QVariantList &object, bool simple);
private: private:
quint32 m_nextId; quint32 m_nextId;
......
...@@ -364,6 +364,7 @@ void QmlInspectorAdapter::createPreviewForEditor(Core::IEditor *newEditor) ...@@ -364,6 +364,7 @@ void QmlInspectorAdapter::createPreviewForEditor(Core::IEditor *newEditor)
connect(preview, connect(preview,
SIGNAL(selectedItemsChanged(QList<int>)), SIGNAL(selectedItemsChanged(QList<int>)),
SLOT(selectObjectsFromEditor(QList<int>))); SLOT(selectObjectsFromEditor(QList<int>)));
preview->setApplyChangesToQmlInspector( preview->setApplyChangesToQmlInspector(
debuggerCore()->action(QmlUpdateOnSave)->isChecked()); debuggerCore()->action(QmlUpdateOnSave)->isChecked());
......
...@@ -399,10 +399,22 @@ void QmlInspectorAgent::onResult(quint32 queryId, const QVariant &value, ...@@ -399,10 +399,22 @@ void QmlInspectorAgent::onResult(quint32 queryId, const QVariant &value,
rootContextChanged(qvariant_cast<ContextReference>(value)); rootContextChanged(qvariant_cast<ContextReference>(value));
} else if (m_fetchCurrentObjectsQueryIds.contains(queryId)) { } else if (m_fetchCurrentObjectsQueryIds.contains(queryId)) {
m_fetchCurrentObjectsQueryIds.removeOne(queryId); m_fetchCurrentObjectsQueryIds.removeOne(queryId);
ObjectReference obj if (value.type() == QVariant::List) {
= qvariant_cast<ObjectReference>(value); QVariantList objList = value.toList();
m_fetchCurrentObjects.push_front(obj); foreach (QVariant var, objList) {
onCurrentObjectsFetched(obj); // TODO: check which among the list is the actual
// object that needs to be selected.
ObjectReference obj
= qvariant_cast<ObjectReference>(var);
m_fetchCurrentObjects.push_front(obj);
onCurrentObjectsFetched(obj);
}
} else {
ObjectReference obj
= qvariant_cast<ObjectReference>(value);
m_fetchCurrentObjects.push_front(obj);
onCurrentObjectsFetched(obj);
}
} else { } else {
emit expressionResult(queryId, value); emit expressionResult(queryId, value);
} }
...@@ -469,6 +481,30 @@ quint32 QmlInspectorAgent::fetchContextObject(const ObjectReference &obj) ...@@ -469,6 +481,30 @@ quint32 QmlInspectorAgent::fetchContextObject(const ObjectReference &obj)
return queryId; return queryId;
} }
void QmlInspectorAgent::fetchContextObjectsForLocation(const QString &file,
int lineNumber, int columnNumber)
{
// This can be an expensive operation as it may return multiple
// objects. Use fetchContextObject() where possible.
if (debug)
qDebug() << __FUNCTION__ << "(" << file << ":" << lineNumber
<< ":" << columnNumber << ")";
if (!isConnected()
|| !debuggerCore()->boolSetting(ShowQmlObjectTree))
return;
log(LogSend, QString("FETCH_OBJECTS_FOR_LOCATION %1:%2:%3").arg(file)
.arg(QString::number(lineNumber)).arg(QString::number(columnNumber)));
quint32 queryId = m_engineClient->queryObjectsForLocation(QFileInfo(file).fileName(),
lineNumber, columnNumber);
if (debug)
qDebug() << __FUNCTION__ << "(" << file << ":" << lineNumber
<< ":" << columnNumber << ")" << " - query id" << queryId;
m_fetchCurrentObjectsQueryIds << queryId;
}
// fetch the root objects from the context + any child contexts // fetch the root objects from the context + any child contexts
void QmlInspectorAgent::fetchRootObjects(const ContextReference &context, void QmlInspectorAgent::fetchRootObjects(const ContextReference &context,
bool clear) bool clear)
......
...@@ -89,6 +89,9 @@ public: ...@@ -89,6 +89,9 @@ public:
void setEngineClient(QmlDebug::BaseEngineDebugClient *client); void setEngineClient(QmlDebug::BaseEngineDebugClient *client);
public slots:
void fetchContextObjectsForLocation(const QString &file,
int lineNumber, int columnNumber);
signals: signals:
void objectTreeUpdated(); void objectTreeUpdated();
void objectFetched(const QmlDebug::ObjectReference &ref); void objectFetched(const QmlDebug::ObjectReference &ref);
......
...@@ -362,6 +362,10 @@ QmlLiveTextPreview::QmlLiveTextPreview(const QmlJS::Document::Ptr &doc, ...@@ -362,6 +362,10 @@ QmlLiveTextPreview::QmlLiveTextPreview(const QmlJS::Document::Ptr &doc,
connect(m_inspectorAdapter->agent(), SIGNAL(objectTreeUpdated()), connect(m_inspectorAdapter->agent(), SIGNAL(objectTreeUpdated()),
SLOT(updateDebugIds())); SLOT(updateDebugIds()));
connect(this,
SIGNAL(fetchObjectsForLocation(QString,int,int)),
m_inspectorAdapter->agent(),
SLOT(fetchContextObjectsForLocation(QString,int,int)));
} }
void QmlLiveTextPreview::associateEditor(Core::IEditor *editor) void QmlLiveTextPreview::associateEditor(Core::IEditor *editor)
...@@ -380,8 +384,8 @@ void QmlLiveTextPreview::associateEditor(Core::IEditor *editor) ...@@ -380,8 +384,8 @@ void QmlLiveTextPreview::associateEditor(Core::IEditor *editor)
m_editors << editWidget; m_editors << editWidget;
if (m_inspectorAdapter) if (m_inspectorAdapter)
connect(editWidget, connect(editWidget,
SIGNAL(selectedElementsChanged(QList<int>,QString)), SIGNAL(selectedElementsChanged(QList<QmlJS::AST::UiObjectMember*>,QString)),
SLOT(changeSelectedElements(QList<int>,QString))); SLOT(changeSelectedElements(QList<QmlJS::AST::UiObjectMember*>,QString)));
} }
} }
} }
...@@ -509,12 +513,27 @@ void QmlLiveTextPreview::updateDebugIds() ...@@ -509,12 +513,27 @@ void QmlLiveTextPreview::updateDebugIds()
changeSelectedElements(m_lastOffsets, QString()); changeSelectedElements(m_lastOffsets, QString());
} }
void QmlLiveTextPreview::changeSelectedElements(QList<int> offsets, void QmlLiveTextPreview::changeSelectedElements(const QList<QmlJS::AST::UiObjectMember*> offsetObjects,
const QString &wordAtCursor) const QString &wordAtCursor)
{ {
if (m_editors.isEmpty() || !m_previousDoc) if (m_editors.isEmpty() || !m_previousDoc)
return; return;
QList<int> offsets;
foreach (QmlJS::AST::UiObjectMember *member, offsetObjects)
offsets << member->firstSourceLocation().offset;
if (!changeSelectedElements(offsets, wordAtCursor) && m_initialDoc && offsetObjects.count()) {
m_updateNodeForOffset = true;
emit fetchObjectsForLocation(m_initialDoc->fileName(),
offsetObjects.first()->firstSourceLocation().startLine,
offsetObjects.first()->firstSourceLocation().startColumn);
}
}
bool QmlLiveTextPreview::changeSelectedElements(const QList<int> offsets,
const QString &wordAtCursor)
{
m_updateNodeForOffset = false; m_updateNodeForOffset = false;
m_lastOffsets = offsets; m_lastOffsets = offsets;
ObjectReference objectRefUnderCursor; ObjectReference objectRefUnderCursor;
...@@ -549,8 +568,10 @@ void QmlLiveTextPreview::changeSelectedElements(QList<int> offsets, ...@@ -549,8 +568,10 @@ void QmlLiveTextPreview::changeSelectedElements(QList<int> offsets,
selectedReferences << objectRefUnderCursor.debugId(); selectedReferences << objectRefUnderCursor.debugId();
} }
if (!selectedReferences.isEmpty()) if (selectedReferences.isEmpty())
emit selectedItemsChanged(selectedReferences); return false;
emit selectedItemsChanged(selectedReferences);
return true;
} }
void QmlLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc) void QmlLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc)
......
...@@ -68,13 +68,16 @@ public: ...@@ -68,13 +68,16 @@ public:
signals: signals:
void selectedItemsChanged(const QList<int> &debugIds); void selectedItemsChanged(const QList<int> &debugIds);
void fetchObjectsForLocation(const QString &file,
int lineNumber, int columnNumber);
public slots: public slots:
void setApplyChangesToQmlInspector(bool applyChanges); void setApplyChangesToQmlInspector(bool applyChanges);
void updateDebugIds(); void updateDebugIds();
private slots: private slots:
void changeSelectedElements(QList<int> offsets, const QString &wordAtCursor); void changeSelectedElements(const QList<QmlJS::AST::UiObjectMember *> offsets,
const QString &wordAtCursor);
void documentChanged(QmlJS::Document::Ptr doc); void documentChanged(QmlJS::Document::Ptr doc);
private: private:
...@@ -84,6 +87,7 @@ private: ...@@ -84,6 +87,7 @@ private:
ElementChangeWarning ElementChangeWarning
}; };
bool changeSelectedElements(const QList<int> offsets, const QString &wordAtCursor);
QList<int> objectReferencesForOffset(quint32 offset); QList<int> objectReferencesForOffset(quint32 offset);
void showSyncWarning(UnsyncronizableChangeType unsyncronizableChangeType, void showSyncWarning(UnsyncronizableChangeType unsyncronizableChangeType,
const QString &elementName, const QString &elementName,
......
...@@ -965,12 +965,12 @@ protected: ...@@ -965,12 +965,12 @@ protected:
void QmlJSTextEditorWidget::setSelectedElements() void QmlJSTextEditorWidget::setSelectedElements()
{ {
if (!receivers(SIGNAL(selectedElementsChanged(QList<int>,QString)))) if (!receivers(SIGNAL(selectedElementsChanged(QList<QmlJS::AST::UiObjectMember*>,QString))))
return; return;
QTextCursor tc = textCursor(); QTextCursor tc = textCursor();
QString wordAtCursor; QString wordAtCursor;
QList<int> offsets; QList<UiObjectMember *> offsets;
unsigned startPos; unsigned startPos;
unsigned endPos; unsigned endPos;
...@@ -992,7 +992,7 @@ void QmlJSTextEditorWidget::setSelectedElements() ...@@ -992,7 +992,7 @@ void QmlJSTextEditorWidget::setSelectedElements()
startPos, endPos); startPos, endPos);
if (!members.isEmpty()) { if (!members.isEmpty()) {
foreach(UiObjectMember *m, members) { foreach(UiObjectMember *m, members) {
offsets << m->firstSourceLocation().begin(); offsets << m;
} }
} }
} }
......
...@@ -57,6 +57,9 @@ namespace QmlJS { ...@@ -57,6 +57,9 @@ namespace QmlJS {
class ModelManagerInterface; class ModelManagerInterface;
class IContextPane; class IContextPane;
class LookupContext; class LookupContext;
namespace AST {
class UiObjectMember;
}
} }
/*! /*!
...@@ -127,7 +130,8 @@ public slots: ...@@ -127,7 +130,8 @@ public slots:
signals: signals:
void outlineModelIndexChanged(const QModelIndex &index); void outlineModelIndexChanged(const QModelIndex &index);
void selectedElementsChanged(QList<int> offsets, const QString &wordAtCursor); void selectedElementsChanged(QList<QmlJS::AST::UiObjectMember*> offsets,
const QString &wordAtCursor);
void semanticInfoUpdated(); void semanticInfoUpdated();
private slots: private slots:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment