diff options
author | hjk <hjk@theqtcompany.com> | 2015-03-19 12:42:53 +0100 |
---|---|---|
committer | hjk <hjk@theqtcompany.com> | 2015-03-20 08:36:57 +0000 |
commit | b3f88df41df29f8a20e7ddf6fd8b83100a75740d (patch) | |
tree | d4ba0fc1071fafd8c7ba9c5b6c87ecf674519ae6 /src/plugins/debugger | |
parent | b08e5a9bc3dd04e6630f43c459753731e87eda1a (diff) | |
download | qt-creator-b3f88df41df29f8a20e7ddf6fd8b83100a75740d.tar.gz |
Debugger: Remove most remaining occurrences of WatchData
... in WatchHandler and DebuggerEngine interface.
Adjust using code.
Change-Id: I6371f3e96ba46a783e23a5767cdde24a10d3fce7
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
Reviewed-by: hjk <hjk@theqtcompany.com>
Diffstat (limited to 'src/plugins/debugger')
25 files changed, 456 insertions, 568 deletions
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 657972e899..a4535f10ef 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -974,46 +974,47 @@ static inline bool isWatchIName(const QByteArray &iname) return iname.startsWith("watch"); } -void CdbEngine::updateWatchData(const WatchData &dataIn) +void CdbEngine::updateWatchItem(WatchItem *item) { if (debug || debugLocals || debugWatches) qDebug("CdbEngine::updateWatchData() %dms accessible=%d %s: %s", elapsedLogTime(), m_accessible, stateName(state()), - qPrintable(dataIn.toString())); + qPrintable(item->toString())); if (!m_accessible) // Add watch data while running? return; // New watch item? - if (dataIn.isWatcher() && dataIn.isValueNeeded()) { + if (item->isWatcher() && item->isValueNeeded()) { QByteArray args; ByteArrayInputStream str(args); - str << dataIn.iname << " \"" << dataIn.exp << '"'; + WatchData data = *item; // Don't pass pointers to async functions. + str << data.iname << " \"" << data.exp << '"'; postExtensionCommand("addwatch", args, 0, - [this, dataIn](const CdbResponse &r) { handleAddWatch(r, dataIn); }); + [this, data](const CdbResponse &r) { handleAddWatch(r, data); }); return; } - if (!dataIn.hasChildren && !dataIn.isValueNeeded()) { - WatchData data = dataIn; - data.setAllUnneeded(); - watchHandler()->insertData(data); - return; + if (item->wantsChildren || item->isValueNeeded()) { + updateLocalVariable(item->iname); + } else { + item->setAllUnneeded(); + item->update(); } - updateLocalVariable(dataIn.iname); } -void CdbEngine::handleAddWatch(const CdbResponse &response, WatchData item) +void CdbEngine::handleAddWatch(const CdbResponse &response, WatchData data) { if (debugWatches) - qDebug() << "handleAddWatch ok=" << response.success << item.iname; + qDebug() << "handleAddWatch ok=" << response.success << data.iname; if (response.success) { - updateLocalVariable(item.iname); + updateLocalVariable(data.iname); } else { - item.setError(tr("Unable to add expression")); - watchHandler()->insertData(item); + auto item = new WatchItem(data); + item->setError(tr("Unable to add expression")); + watchHandler()->insertItem(item); showMessage(QString::fromLatin1("Unable to add watch item \"%1\"/\"%2\": %3"). - arg(QString::fromLatin1(item.iname), QString::fromLatin1(item.exp), + arg(QString::fromLatin1(data.iname), QString::fromLatin1(data.exp), QString::fromLocal8Bit(response.errorMessage)), LogError); } } @@ -1269,7 +1270,7 @@ static inline bool isAsciiWord(const QString &s) return true; } -void CdbEngine::assignValueInDebugger(const WatchData *w, const QString &expr, const QVariant &value) +void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const QVariant &value) { if (debug) qDebug() << "CdbEngine::assignValueInDebugger" << w->iname << expr << value; @@ -1871,13 +1872,13 @@ void CdbEngine::handleLocals(const CdbResponse &response, bool newFrame) QSet<QByteArray> toDelete; if (newFrame) { foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(2)) - toDelete.insert(item->d.iname); + toDelete.insert(item->iname); } foreach (const GdbMi &child, all.children()) { WatchItem *item = new WatchItem(child); handler->insertItem(item); - toDelete.remove(item->d.iname); + toDelete.remove(item->iname); } handler->purgeOutdatedItems(toDelete); diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 76ecd6a472..e57b2ca1ab 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -89,7 +89,7 @@ public: virtual void shutdownEngine(); virtual void abortDebugger(); virtual void detachDebugger(); - virtual void updateWatchData(const WatchData &data); + virtual void updateWatchItem(WatchItem *item); virtual bool hasCapability(unsigned cap) const; virtual void watchPoint(const QPoint &); virtual void setRegisterValue(const QByteArray &name, const QString &value); @@ -106,7 +106,7 @@ public: virtual void executeRunToLine(const ContextData &data); virtual void executeRunToFunction(const QString &functionName); virtual void executeJumpToLine(const ContextData &data); - virtual void assignValueInDebugger(const WatchData *w, const QString &expr, const QVariant &value); + virtual void assignValueInDebugger(WatchItem *w, const QString &expr, const QVariant &value); virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); virtual void activateFrame(int index); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index c2a826b390..8c7989bd72 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1439,10 +1439,6 @@ bool DebuggerEngine::setToolTipExpression(const DebuggerToolTipContext &) return false; } -void DebuggerEngine::updateWatchData(const WatchData &) -{ -} - void DebuggerEngine::watchDataSelected(const QByteArray &) { } @@ -1635,7 +1631,7 @@ void DebuggerEngine::changeBreakpoint(Breakpoint bp) QTC_CHECK(false); } -void DebuggerEngine::assignValueInDebugger(const WatchData *, +void DebuggerEngine::assignValueInDebugger(WatchItem *, const QString &, const QVariant &) { } diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 2ff08231cc..fb11e6553b 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -62,6 +62,7 @@ class DebuggerPluginPrivate; class DisassemblerAgent; class MemoryAgent; class WatchData; +class WatchItem; class BreakHandler; class ModulesHandler; class RegisterHandler; @@ -139,7 +140,7 @@ public: virtual bool setToolTipExpression(const Internal::DebuggerToolTipContext &); - virtual void updateWatchData(const Internal::WatchData &data); + virtual void updateWatchItem(WatchItem *) {} virtual void watchDataSelected(const QByteArray &iname); virtual void startDebugger(DebuggerRunControl *runControl); @@ -198,7 +199,7 @@ public: virtual bool acceptsDebuggerCommands() const { return true; } virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); - virtual void assignValueInDebugger(const Internal::WatchData *data, + virtual void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); virtual void selectThread(Internal::ThreadId threadId) = 0; diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index fc1bd3626b..a91c740907 100644 --- a/src/plugins/debugger/debuggertooltipmanager.cpp +++ b/src/plugins/debugger/debuggertooltipmanager.cpp @@ -218,9 +218,9 @@ ToolTipWatchItem::ToolTipWatchItem(WatchItem *item) name = item->displayName(); value = item->displayValue(); type = item->displayType(); - iname = item->d.iname; + iname = item->iname; valueColor = item->valueColor(); - expandable = item->d.hasChildren; + expandable = item->hasChildren(); expression = item->expression(); foreach (TreeItem *child, item->children()) appendChild(new ToolTipWatchItem(static_cast<WatchItem *>(child))); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index d4ecc5fd90..f8e6d60277 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3724,11 +3724,11 @@ void GdbEngine::reloadLocals() updateLocals(); } -void GdbEngine::updateWatchData(const WatchData &data) +void GdbEngine::updateWatchItem(WatchItem *item) { UpdateParameters params; params.tryPartial = m_pendingBreakpointRequests == 0; - params.varList = data.iname; + params.varList = item->iname; updateLocalsPython(params); } @@ -3759,14 +3759,14 @@ void GdbEngine::updateLocals() updateLocalsPython(UpdateParameters()); } -void GdbEngine::assignValueInDebugger(const WatchData *data, +void GdbEngine::assignValueInDebugger(WatchItem *item, const QString &expression, const QVariant &value) { DebuggerCommand cmd("assignValue"); - cmd.arg("type", data->type.toHex()); + cmd.arg("type", item->type.toHex()); cmd.arg("expr", expression.toLatin1().toHex()); cmd.arg("value", value.toString().toLatin1().toHex()); - cmd.arg("simpleType", isIntOrFloatType(data->type)); + cmd.arg("simpleType", isIntOrFloatType(item->type)); cmd.callback = CB(handleVarAssign); runCommand(cmd); } @@ -4805,17 +4805,17 @@ void GdbEngine::handleStackFramePython(const DebuggerResponse &response, bool pa QSet<QByteArray> toDelete; if (!partial) { foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(2)) - toDelete.insert(item->d.iname); + toDelete.insert(item->iname); } foreach (const GdbMi &child, data.children()) { WatchItem *item = new WatchItem(child); - const TypeInfo ti = m_typeInfoCache.value(item->d.type); + const TypeInfo ti = m_typeInfoCache.value(item->type); if (ti.size) - item->d.size = ti.size; + item->size = ti.size; handler->insertItem(item); - toDelete.remove(item->d.iname); + toDelete.remove(item->iname); } handler->purgeOutdatedItems(toDelete); diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index bfa310770a..e71455c393 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -59,7 +59,6 @@ class MemoryAgentCookie; class BreakpointParameters; class BreakpointResponse; -class WatchData; class DisassemblerAgentCookie; class DisassemblerLines; @@ -384,7 +383,7 @@ protected: // Watch specific stuff // virtual bool setToolTipExpression(const DebuggerToolTipContext &); - virtual void assignValueInDebugger(const WatchData *data, + virtual void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); virtual void fetchMemory(MemoryAgent *agent, QObject *token, @@ -398,8 +397,8 @@ protected: virtual void watchPoint(const QPoint &); void handleWatchPoint(const DebuggerResponse &response); - void updateWatchData(const WatchData &data); void rebuildWatchModel(); + void updateWatchItem(WatchItem *item); void showToolTip(); void handleVarAssign(const DebuggerResponse &response); diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 863d13968f..1be58dd442 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -844,19 +844,17 @@ void LldbEngine::reloadFullStack() // ////////////////////////////////////////////////////////////////////// -void LldbEngine::assignValueInDebugger(const Internal::WatchData *data, +void LldbEngine::assignValueInDebugger(WatchItem *, const QString &expression, const QVariant &value) { - Q_UNUSED(data); DebuggerCommand cmd("assignValue"); cmd.arg("exp", expression.toLatin1().toHex()); cmd.arg("value", value.toString().toLatin1().toHex()); runCommand(cmd); } -void LldbEngine::updateWatchData(const WatchData &data) +void LldbEngine::updateWatchItem(WatchItem *) { - Q_UNUSED(data); updateLocals(); } @@ -1001,12 +999,12 @@ void LldbEngine::refreshLocals(const GdbMi &vars) QSet<QByteArray> toDelete; foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(2)) - toDelete.insert(item->d.iname); + toDelete.insert(item->iname); foreach (const GdbMi &child, vars.children()) { WatchItem *item = new WatchItem(child); handler->insertItem(item); - toDelete.remove(item->d.iname); + toDelete.remove(item->iname); } handler->purgeOutdatedItems(toDelete); diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 31c404e424..280f7ba78c 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -105,8 +105,7 @@ private: void removeBreakpoint(Breakpoint bp); void changeBreakpoint(Breakpoint bp); - void assignValueInDebugger(const WatchData *data, - const QString &expr, const QVariant &value); + void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); void loadSymbols(const QString &moduleName); @@ -122,7 +121,7 @@ private: bool supportsThreads() const { return true; } bool isSynchronous() const { return true; } - void updateWatchData(const WatchData &data); + void updateWatchItem(WatchItem *item); void setRegisterValue(const QByteArray &name, const QString &value); void fetchMemory(Internal::MemoryAgent *, QObject *, quint64 addr, quint64 length); diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index c4bb9acd68..88d3bb7abf 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -382,7 +382,7 @@ bool PdbEngine::setToolTipExpression(const DebuggerToolTipContext &ctx) return true; } -void PdbEngine::assignValueInDebugger(const WatchData *, const QString &expression, const QVariant &value) +void PdbEngine::assignValueInDebugger(WatchItem *, const QString &expression, const QVariant &value) { //DebuggerCommand cmd("assignValue"); //cmd.arg("expression", expression); @@ -393,9 +393,9 @@ void PdbEngine::assignValueInDebugger(const WatchData *, const QString &expressi updateLocals(); } -void PdbEngine::updateWatchData(const WatchData &data) +void PdbEngine::updateWatchItem(WatchItem *item) { - Q_UNUSED(data); + Q_UNUSED(item); updateAll(); } @@ -573,12 +573,12 @@ void PdbEngine::refreshLocals(const GdbMi &vars) QSet<QByteArray> toDelete; foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(2)) - toDelete.insert(item->d.iname); + toDelete.insert(item->iname); foreach (const GdbMi &child, vars.children()) { WatchItem *item = new WatchItem(child); handler->insertItem(item); - toDelete.remove(item->d.iname); + toDelete.remove(item->iname); } handler->purgeOutdatedItems(toDelete); diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h index 9d190d31e8..751ebbc943 100644 --- a/src/plugins/debugger/pdb/pdbengine.h +++ b/src/plugins/debugger/pdb/pdbengine.h @@ -82,7 +82,7 @@ private: void insertBreakpoint(Breakpoint bp); void removeBreakpoint(Breakpoint bp); - void assignValueInDebugger(const WatchData *data, + void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); @@ -96,7 +96,7 @@ private: bool supportsThreads() const { return true; } bool isSynchronous() const { return true; } - void updateWatchData(const WatchData &data); + void updateWatchItem(WatchItem *item); QString mainPythonFile() const; void runCommand(const DebuggerCommand &cmd); diff --git a/src/plugins/debugger/qml/baseqmldebuggerclient.h b/src/plugins/debugger/qml/baseqmldebuggerclient.h index 409a3dc9c5..47435fbf99 100644 --- a/src/plugins/debugger/qml/baseqmldebuggerclient.h +++ b/src/plugins/debugger/qml/baseqmldebuggerclient.h @@ -38,6 +38,7 @@ namespace Debugger { namespace Internal { class WatchData; +class WatchItem; class BreakHandler; class BreakpointModelId; class QmlEngine; diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp index dab64a71a4..222fc097e6 100644 --- a/src/plugins/debugger/qml/qmlcppengine.cpp +++ b/src/plugins/debugger/qml/qmlcppengine.cpp @@ -112,18 +112,18 @@ bool QmlCppEngine::setToolTipExpression(const DebuggerToolTipContext &ctx) return success; } -void QmlCppEngine::updateWatchData(const WatchData &data) +void QmlCppEngine::updateWatchItem(WatchItem *item) { - if (data.isInspect()) - m_qmlEngine->updateWatchData(data); + if (item->isInspect()) + m_qmlEngine->updateWatchItem(item); else - m_activeEngine->updateWatchData(data); + m_activeEngine->updateWatchItem(item); } void QmlCppEngine::watchDataSelected(const QByteArray &iname) { - const WatchData *wd = watchHandler()->findData(iname); - if (wd && wd->isInspect()) + const WatchItem *item = watchHandler()->findItem(iname); + if (item && item->isInspect()) m_qmlEngine->watchDataSelected(iname); } @@ -264,13 +264,13 @@ void QmlCppEngine::selectThread(ThreadId threadId) m_activeEngine->selectThread(threadId); } -void QmlCppEngine::assignValueInDebugger(const WatchData *data, +void QmlCppEngine::assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value) { - if (data->isInspect()) - m_qmlEngine->assignValueInDebugger(data, expr, value); + if (item->isInspect()) + m_qmlEngine->assignValueInDebugger(item, expr, value); else - m_activeEngine->assignValueInDebugger(data, expr, value); + m_activeEngine->assignValueInDebugger(item, expr, value); } void QmlCppEngine::notifyInferiorIll() diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h index 6960cde7fc..3ea2b14ff3 100644 --- a/src/plugins/debugger/qml/qmlcppengine.h +++ b/src/plugins/debugger/qml/qmlcppengine.h @@ -48,7 +48,7 @@ public: bool canDisplayTooltip() const; bool setToolTipExpression(const DebuggerToolTipContext &); - void updateWatchData(const WatchData &data); + void updateWatchItem(WatchItem *item); void watchDataSelected(const QByteArray &iname); void watchPoint(const QPoint &); @@ -79,7 +79,7 @@ public: bool acceptsBreakpoint(Breakpoint bp) const; void selectThread(ThreadId threadId); - void assignValueInDebugger(const WatchData *data, + void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); DebuggerEngine *cppEngine() { return m_cppEngine; } diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 6f6e7d2ccd..eb32ddfe11 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -988,45 +988,41 @@ bool QmlEngine::setToolTipExpression(const DebuggerToolTipContext &context) // ////////////////////////////////////////////////////////////////////// -void QmlEngine::assignValueInDebugger(const WatchData *data, +void QmlEngine::assignValueInDebugger(WatchItem *item, const QString &expression, const QVariant &valueV) { if (!expression.isEmpty()) { - if (data->isInspect() && m_inspectorAdapter.agent()) - m_inspectorAdapter.agent()->assignValue(data, expression, valueV); + if (item->isInspect() && m_inspectorAdapter.agent()) + m_inspectorAdapter.agent()->assignValue(item, expression, valueV); else if (m_adapter.activeDebuggerClient()) - m_adapter.activeDebuggerClient()->assignValueInDebugger(data, expression, valueV); + m_adapter.activeDebuggerClient()->assignValueInDebugger(item, expression, valueV); } } -void QmlEngine::updateWatchData(const WatchData &data) +void QmlEngine::updateWatchItem(WatchItem *item) { // qDebug() << "UPDATE WATCH DATA" << data.toString(); //showStatusMessage(tr("Stopped."), 5000); - if (data.isInspect()) { - m_inspectorAdapter.agent()->updateWatchData(data); + if (item->isInspect()) { + m_inspectorAdapter.agent()->updateWatchData(*item); } else { - if (!data.name.isEmpty() && m_adapter.activeDebuggerClient()) { - if (data.isValueNeeded()) - m_adapter.activeDebuggerClient()->updateWatchData(data); - if (data.isChildrenNeeded() - && watchHandler()->isExpandedIName(data.iname)) { - m_adapter.activeDebuggerClient()->expandObject(data.iname, data.id); + if (!item->name.isEmpty() && m_adapter.activeDebuggerClient()) { + if (item->isValueNeeded()) + m_adapter.activeDebuggerClient()->updateWatchData(*item); + if (item->isChildrenNeeded() && watchHandler()->isExpandedIName(item->iname)) { + m_adapter.activeDebuggerClient()->expandObject(item->iname, item->id); } } synchronizeWatchers(); } - - if (!data.isSomethingNeeded()) - watchHandler()->insertData(data); } void QmlEngine::watchDataSelected(const QByteArray &iname) { - const WatchData *wd = watchHandler()->findData(iname); - if (wd && wd->isInspect()) - m_inspectorAdapter.agent()->watchDataSelected(wd); + const WatchItem *item = watchHandler()->findItem(iname); + if (item && item->isInspect()) + m_inspectorAdapter.agent()->watchDataSelected(item->id); } void QmlEngine::synchronizeWatchers() @@ -1153,11 +1149,11 @@ void QmlEngine::updateCurrentContext() context = stackHandler()->currentFrame().function; } else { QModelIndex currentIndex = inspectorTreeView()->currentIndex(); - const WatchData *currentData = watchHandler()->watchData(currentIndex); + const WatchData *currentData = watchHandler()->watchItem(currentIndex); if (!currentData) return; - const WatchData *parentData = watchHandler()->watchData(currentIndex.parent()); - const WatchData *grandParentData = watchHandler()->watchData( + const WatchData *parentData = watchHandler()->watchItem(currentIndex.parent()); + const WatchData *grandParentData = watchHandler()->watchItem( currentIndex.parent().parent()); if (currentData->id != parentData->id) context = currentData->name; @@ -1217,7 +1213,7 @@ bool QmlEngine::evaluateScript(const QString &expression) if (state() != InferiorStopOk) { QModelIndex currentIndex = inspectorTreeView()->currentIndex(); QmlInspectorAgent *agent = m_inspectorAdapter.agent(); - quint32 queryId = agent->queryExpressionResult(watchHandler()->watchData(currentIndex)->id, + quint32 queryId = agent->queryExpressionResult(watchHandler()->watchItem(currentIndex)->id, expression); if (queryId) { queryIds << queryId; diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 60fd23dd2c..621947dfe4 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -145,10 +145,9 @@ private: void changeBreakpoint(Breakpoint bp); bool acceptsBreakpoint(Breakpoint bp) const; - void assignValueInDebugger(const WatchData *data, + void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); - void loadSymbols(const QString &moduleName); void loadAllSymbols(); void requestModuleSymbols(const QString &moduleName); @@ -158,7 +157,7 @@ private: void reloadFullStack() {} bool supportsThreads() const { return false; } - void updateWatchData(const WatchData &data); + void updateWatchItem(WatchItem *item); void watchDataSelected(const QByteArray &iname); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); bool evaluateScript(const QString &expression); diff --git a/src/plugins/debugger/qml/qmlinspectoragent.cpp b/src/plugins/debugger/qml/qmlinspectoragent.cpp index 778e691c79..ece99ccb76 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.cpp +++ b/src/plugins/debugger/qml/qmlinspectoragent.cpp @@ -125,13 +125,13 @@ void QmlInspectorAgent::updateWatchData(const WatchData &data) } } -void QmlInspectorAgent::watchDataSelected(const WatchData *data) +void QmlInspectorAgent::watchDataSelected(quint64 id) { - qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << data->id << ')'; + qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << id << ')'; - if (data->id) { - QTC_ASSERT(m_debugIdLocations.keys().contains(data->id), return); - emit jumpToObjectDefinition(m_debugIdLocations.value(data->id), data->id); + if (id) { + QTC_ASSERT(m_debugIdLocations.keys().contains(id), return); + emit jumpToObjectDefinition(m_debugIdLocations.value(id), id); } } @@ -154,7 +154,7 @@ bool QmlInspectorAgent::selectObjectInTree(int debugId) using namespace QmlDebug::Constants; if (m_engineClient->objectName() == QLatin1String(QDECLARATIVE_ENGINE)) { // reset current Selection - QByteArray root = m_debuggerEngine->watchHandler()->watchData(QModelIndex())->iname; + QByteArray root = m_debuggerEngine->watchHandler()->watchItem(QModelIndex())->iname; m_debuggerEngine->watchHandler()->setCurrentItem(root); } else { fetchObject(debugId); @@ -256,8 +256,8 @@ ObjectReference QmlInspectorAgent::objectForName( const WatchHandler *watchHandler = m_debuggerEngine->watchHandler(); while (iter.hasNext()) { iter.next(); - const WatchData *wd = watchHandler->findData(iter.value()); - if (wd && wd->name == objectId) + const WatchItem *item = watchHandler->findItem(iter.value()); + if (item && item->name == objectId) return ObjectReference(iter.key()); } } @@ -313,13 +313,11 @@ QHash<int,QString> QmlInspectorAgent::rootObjectIds() const { QHash<int,QString> rIds; const WatchHandler *watchHandler = m_debuggerEngine->watchHandler(); - foreach (const QByteArray &in, m_debugIdToIname) { - const WatchData *data = watchHandler->findData(in); - if (!data) - continue; - int debugId = data->id; - QString className = QLatin1String(data->type); - rIds.insert(debugId, className); + foreach (const QByteArray &iname, m_debugIdToIname) { + if (const WatchItem *item = watchHandler->findItem(iname)) { + int debugId = item->id; + rIds.insert(debugId, QLatin1String(item->type)); + } } return rIds; } @@ -415,10 +413,10 @@ QString QmlInspectorAgent::displayName(int objectDebugId) const return QString(); if (m_debugIdToIname.contains(objectDebugId)) { - const WatchData *data = m_debuggerEngine->watchHandler()->findData( + const WatchItem *item = m_debuggerEngine->watchHandler()->findItem( m_debugIdToIname.value(objectDebugId)); - QTC_ASSERT(data, return QString()); - return data->name; + QTC_ASSERT(item, return QString()); + return item->name; } return QString(); } @@ -505,14 +503,12 @@ void QmlInspectorAgent::onValueChanged(int debugId, const QByteArray &propertyNa const QByteArray iname = m_debugIdToIname.value(debugId) + ".[properties]." + propertyName; WatchHandler *watchHandler = m_debuggerEngine->watchHandler(); - const WatchData *data = watchHandler->findData(iname); qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << debugId << ')' << iname << value.toString(); - if (data) { - WatchData d(*data); - d.value = value.toString(); - watchHandler->insertData(d); + if (WatchItem *item = watchHandler->findItem(iname)) { + item->value = value.toString(); + item->update(); } } @@ -745,7 +741,6 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj, QByteArray objIname = buildIName(parentIname, objDebugId); if (append) { - WatchData objWatch; QString name = obj.idString(); if (name.isEmpty()) name = obj.className(); @@ -754,17 +749,16 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj, return; // object - objWatch.id = objDebugId; - objWatch.exp = name.toLatin1(); - objWatch.name = name; - objWatch.iname = objIname; - objWatch.type = obj.className().toLatin1(); - objWatch.value = _("object"); - objWatch.setHasChildren(true); - objWatch.setAllUnneeded(); - - m_debuggerEngine->watchHandler()->insertData(objWatch); - addObjectWatch(objWatch.id); + auto objWatch = new WatchItem(objIname, name); + objWatch->id = objDebugId; + objWatch->exp = name.toLatin1(); + objWatch->type = obj.className().toLatin1(); + objWatch->value = _("object"); + objWatch->wantsChildren = true; + objWatch->setAllUnneeded(); + + m_debuggerEngine->watchHandler()->insertItem(objWatch); + addObjectWatch(objWatch->id); if (m_debugIdToIname.contains(objDebugId)) { // The data needs to be removed since we now know the parent and // hence we can insert the data in the correct position @@ -786,22 +780,22 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj, if (append && obj.properties().count()) { QByteArray iname = objIname + ".[properties]"; auto propertiesWatch = new WatchItem(iname, tr("Properties")); - propertiesWatch->d.id = objDebugId; - propertiesWatch->d.value = _("list"); - propertiesWatch->d.setHasChildren(true); - propertiesWatch->d.setAllUnneeded(); + propertiesWatch->id = objDebugId; + propertiesWatch->value = _("list"); + propertiesWatch->wantsChildren = true; + propertiesWatch->setAllUnneeded(); foreach (const PropertyReference &property, obj.properties()) { const QString propertyName = property.name(); if (propertyName.isEmpty()) continue; auto propertyWatch = new WatchItem(buildIName(iname, propertyName), propertyName); - propertyWatch->d.id = objDebugId; - propertyWatch->d.exp = propertyName.toLatin1(); - propertyWatch->d.type = property.valueTypeName().toLatin1(); - propertyWatch->d.value = property.value().toString(); - propertyWatch->d.setAllUnneeded(); - propertyWatch->d.setHasChildren(false); + propertyWatch->id = objDebugId; + propertyWatch->exp = propertyName.toLatin1(); + propertyWatch->type = property.valueTypeName().toLatin1(); + propertyWatch->value = property.value().toString(); + propertyWatch->wantsChildren = false; + propertyWatch->setAllUnneeded(); propertiesWatch->appendChild(propertyWatch); } diff --git a/src/plugins/debugger/qml/qmlinspectoragent.h b/src/plugins/debugger/qml/qmlinspectoragent.h index b888161ae1..4719ed2782 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.h +++ b/src/plugins/debugger/qml/qmlinspectoragent.h @@ -57,7 +57,7 @@ public: void assignValue(const WatchData *data, const QString &expression, const QVariant &valueV); void updateWatchData(const WatchData &data); - void watchDataSelected(const WatchData *data); + void watchDataSelected(quint64 id); bool selectObjectInTree(int debugId); quint32 setBindingForObject(int objectDebugId, diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index da87ce05f1..65b02fbfe4 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -253,7 +253,7 @@ void QmlV8DebuggerClientPrivate::evaluate(const QString expr, bool global, QScriptValue ctxtList = parser.call(QScriptValue(), QScriptValueList() << _(ARRAY )); while (rowCount) { QModelIndex index = watchModel->index(--rowCount, 0); - const WatchData *data = watchHandler->watchData(index); + const WatchData *data = watchHandler->watchItem(index); QScriptValue ctxt = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT))); ctxt.setProperty(_(NAME), QScriptValue(data->name)); ctxt.setProperty(_(HANDLE), QScriptValue(int(data->id))); @@ -969,7 +969,7 @@ void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId { if (objectId == 0) { //We may have got the global object - const WatchData *watch = d->engine->watchHandler()->findData(iname); + const WatchItem *watch = d->engine->watchHandler()->findItem(iname); if (watch->value == QLatin1String("global")) { StackHandler *stackHandler = d->engine->stackHandler(); if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { @@ -1469,10 +1469,9 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const QHash<quint64, QByteArray> handlesToLookup; // Store handles of all expanded watch data foreach (const QByteArray &iname, expandedInames) { - const WatchData *wd = watchHandler->findData(iname); - if (!wd || !wd->isLocal()) - continue; - handlesToLookup.insert(wd->id, iname); + const WatchItem *item = watchHandler->findItem(iname); + if (item && item->isLocal()) + handlesToLookup.insert(item->id, iname); } watchHandler->removeAllData(); if (frameIndex < 0) @@ -1483,22 +1482,19 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const //Set "this" variable { - WatchData data; - data.exp = QByteArray("this"); - data.name = QLatin1String(data.exp); - data.iname = QByteArray("local.") + data.exp; + auto item = new WatchItem("local.this", QLatin1String("this")); QmlV8ObjectData objectData = extractData(currentFrame.value(_("receiver")), refsVal); - data.id = objectData.handle; - data.type = objectData.type; - data.value = objectData.value.toString(); - data.setHasChildren(objectData.properties.count()); + item->id = objectData.handle; + item->type = objectData.type; + item->value = objectData.value.toString(); + item->setHasChildren(objectData.properties.count()); //Incase of global object, we do not get children //Set children nevertheless and query later - if (data.value == QLatin1String("global")) { - data.setHasChildren(true); - data.id = 0; + if (item->value == QLatin1String("global")) { + item->setHasChildren(true); + item->id = 0; } - watchHandler->insertData(data); + watchHandler->insertItem(item); } const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList(); @@ -1555,25 +1551,25 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r QList<int> handlesToLookup; foreach (const QVariant &property, objectData.properties) { QmlV8ObjectData localData = extractData(property, refsVal); - WatchData data; - data.exp = localData.name; + auto item = new WatchItem; + item->exp = localData.name; //Check for v8 specific local data - if (data.exp.startsWith('.') || data.exp.isEmpty()) + if (item->exp.startsWith('.') || item->exp.isEmpty()) continue; - data.name = QLatin1String(data.exp); - data.iname = QByteArray("local.") + data.exp; + item->name = QLatin1String(item->exp); + item->iname = QByteArray("local.") + item->exp; int handle = localData.handle; if (localData.value.isValid()) { - data.id = handle; - data.type = localData.type; - data.value = localData.value.toString(); - data.setHasChildren(localData.properties.count()); - d->engine->watchHandler()->insertData(data); + item->id = handle; + item->type = localData.type; + item->value = localData.value.toString(); + item->setHasChildren(localData.properties.count()); + d->engine->watchHandler()->insertItem(item); } else { handlesToLookup << handle; - d->localsAndWatchers.insertMulti(handle, data.exp); + d->localsAndWatchers.insertMulti(handle, item->exp); } } @@ -1636,7 +1632,7 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, d->scope(index); //Also update "this" QByteArray iname("local.this"); - const WatchData *parent = watchHandler->findData(iname); + const WatchItem *parent = watchHandler->findItem(iname); d->localsAndWatchers.insertMulti(parent->id, iname); d->lookup(QList<int>() << parent->id); @@ -1658,29 +1654,27 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, QmlV8ObjectData body = extractData(bodyVal, refsVal); if (d->evaluatingExpression.contains(sequence)) { QString exp = d->evaluatingExpression.take(sequence); - WatchData data; //Do we have request to evaluate a local? if (exp.startsWith(QLatin1String("local."))) { - const WatchData *watch = watchHandler->findData(exp.toLatin1()); - createWatchDataList(watch, body.properties, refsVal); + const WatchItem *item = watchHandler->findItem(exp.toLatin1()); + createWatchDataList(item, body.properties, refsVal); } else { QByteArray iname = watchHandler->watcherName(exp.toLatin1()); SDEBUG(QString(iname)); - data.exp = exp.toLatin1(); - data.name = exp; - data.iname = iname; - data.id = body.handle; + auto item = new WatchItem(iname, exp); + item->exp = exp.toLatin1(); + item->id = body.handle; if (success) { - data.type = body.type; - data.value = body.value.toString(); - data.hasChildren = body.properties.count(); + item->type = body.type; + item->value = body.value.toString(); + item->wantsChildren = body.properties.count(); } else { //Do not set type since it is unknown - data.setError(body.value.toString()); + item->setError(body.value.toString()); } - watchHandler->insertData(data); - createWatchDataList(&data, body.properties, refsVal); + watchHandler->insertItem(item); + createWatchDataList(item, body.properties, refsVal); } //Insert the newly evaluated expression to the Watchers Window } @@ -1709,27 +1703,27 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const if (prepend.startsWith("local.") || prepend.startsWith("watch.")) { // Data for expanded local/watch. // Could be an object or function. - const WatchData *parent = watchHandler->findData(prepend); + const WatchItem *parent = watchHandler->findItem(prepend); createWatchDataList(parent, bodyObjectData.properties, refsVal); } else { //rest - WatchData data; - data.exp = prepend; - data.name = QLatin1String(data.exp); - data.iname = QByteArray("local.") + data.exp; - data.id = handle.toInt(); + auto item = new WatchItem; + item->exp = prepend; + item->name = QLatin1String(item->exp); + item->iname = QByteArray("local.") + item->exp; + item->id = handle.toInt(); - data.type = bodyObjectData.type; - data.value = bodyObjectData.value.toString(); + item->type = bodyObjectData.type; + item->value = bodyObjectData.value.toString(); - data.setHasChildren(bodyObjectData.properties.count()); + item->setHasChildren(bodyObjectData.properties.count()); - d->engine->watchHandler()->insertData(data); + d->engine->watchHandler()->insertItem(item); } } } -void QmlV8DebuggerClient::createWatchDataList(const WatchData *parent, +void QmlV8DebuggerClient::createWatchDataList(const WatchItem *parent, const QVariantList &properties, const QVariant &refsVal) { @@ -1737,27 +1731,27 @@ void QmlV8DebuggerClient::createWatchDataList(const WatchData *parent, QTC_ASSERT(parent, return); foreach (const QVariant &property, properties) { QmlV8ObjectData propertyData = extractData(property, refsVal); - WatchData data; - data.name = QString::fromUtf8(propertyData.name); + auto item = new WatchItem; + item->name = QString::fromUtf8(propertyData.name); //Check for v8 specific local data - if (data.name.startsWith(QLatin1Char('.')) || data.name.isEmpty()) + if (item->name.startsWith(QLatin1Char('.')) || item->name.isEmpty()) continue; if (parent->type == "object") { if (parent->value == _("Array")) - data.exp = parent->exp + '[' + data.name.toLatin1() + ']'; + item->exp = parent->exp + '[' + item->name.toLatin1() + ']'; else if (parent->value == _("Object")) - data.exp = parent->exp + '.' + data.name.toLatin1(); + item->exp = parent->exp + '.' + item->name.toLatin1(); } else { - data.exp = data.name.toLatin1(); + item->exp = item->name.toLatin1(); } - data.iname = parent->iname + '.' + data.name.toLatin1(); - data.id = propertyData.handle; - data.type = propertyData.type; - data.value = propertyData.value.toString(); - data.setHasChildren(propertyData.properties.count()); - d->engine->watchHandler()->insertData(data); + item->iname = parent->iname + '.' + item->name.toLatin1(); + item->id = propertyData.handle; + item->type = propertyData.type; + item->value = propertyData.value.toString(); + item->setHasChildren(propertyData.properties.count()); + d->engine->watchHandler()->insertItem(item); } } } diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h index 08df8d243f..ae78443e77 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.h +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h @@ -111,7 +111,7 @@ private: void updateEvaluationResult(int sequence, bool success, const QVariant &bodyVal, const QVariant &refsVal); void expandLocalsAndWatchers(const QVariant &bodyVal, const QVariant &refsVal); - void createWatchDataList(const WatchData *parent, + void createWatchDataList(const WatchItem *parent, const QVariantList &properties, const QVariant &refsVal); diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp index 923a1bcb89..fd9b246557 100644 --- a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp +++ b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp @@ -482,16 +482,18 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) d->logReceiveMessage(QLatin1String(command) + QLatin1Char(' ') + QLatin1String(iname) + QLatin1Char(' ') + data.value); - data.iname = iname; + + auto item = new WatchItem(data); + item->iname = iname; if (iname.startsWith("watch.")) { - watchHandler->insertData(data); + watchHandler->insertItem(item); } else if (iname == "console") { - d->engine->showMessage(data.value, ConsoleOutput); + d->engine->showMessage(item->value, ConsoleOutput); } else if (iname.startsWith("local.")) { - data.name = data.name.left(data.name.indexOf(QLatin1Char(' '))); - watchHandler->insertData(data); + item->name = item->name.left(item->name.indexOf(QLatin1Char(' '))); + watchHandler->insertItem(item); } else { - qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value; + qWarning() << "QmlEngine: Unexcpected result: " << iname << item->value; } } else if (command == "EXPANDED") { QList<WatchData> result; @@ -504,7 +506,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) foreach (WatchData data, result) { data.iname = iname + '.' + data.exp; - watchHandler->insertData(data); + watchHandler->insertItem(new WatchItem(data)); if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { needPing = true; @@ -552,9 +554,10 @@ void QScriptDebuggerClient::insertLocalsAndWatches(QList<WatchData> &locals, return; bool needPing = false; - foreach (WatchData data, watches) { - data.iname = watchHandler->watcherName(data.exp); - watchHandler->insertData(data); + foreach (const WatchData &data, watches) { + auto item = new WatchItem(data); + item->iname = watchHandler->watcherName(data.exp); + watchHandler->insertItem(item); if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { needPing = true; @@ -562,11 +565,12 @@ void QScriptDebuggerClient::insertLocalsAndWatches(QList<WatchData> &locals, } } - foreach (WatchData data, locals) { - if (data.name == QLatin1String("<no initialized data>")) - data.name = tr("No Local Variables"); - data.iname = "local." + data.exp; - watchHandler->insertData(data); + foreach (const WatchData &data, locals) { + auto item = new WatchItem(data); + if (item->name == QLatin1String("<no initialized data>")) + item->name = tr("No Local Variables"); + item->iname = "local." + item->exp; + watchHandler->insertItem(item); if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { needPing = true; diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index 5e6d3e951b..ef12026510 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -128,7 +128,7 @@ WatchData::WatchData() : bitpos(0), bitsize(0), elided(0), - hasChildren(false), + wantsChildren(false), valueEnabled(true), valueEditable(true), error(false), @@ -150,7 +150,7 @@ bool WatchData::isEqual(const WatchData &other) const && address == other.address && size == other.size && elided == other.elided - && hasChildren == other.hasChildren + && wantsChildren == other.wantsChildren && valueEnabled == other.valueEnabled && valueEditable == other.valueEditable && error == other.error; @@ -177,7 +177,7 @@ void WatchData::setError(const QString &msg) { setAllUnneeded(); value = msg; - setHasChildren(false); + wantsChildren = false; valueEnabled = false; valueEditable = false; error = true; @@ -188,7 +188,7 @@ void WatchData::setValue(const QString &value0) value = value0; if (value == QLatin1String("{...}")) { value.clear(); - hasChildren = true; // at least one... + wantsChildren = true; // at least one... } // strip off quoted characters for chars. if (value.endsWith(QLatin1Char('\'')) && type.endsWith("char")) { @@ -334,7 +334,7 @@ QString WatchData::toString() const str << "type=\"" << type << doubleQuoteComma; - str << "hasChildren=\"" << (hasChildren ? "true" : "false") << doubleQuoteComma; + str << "wantsChildren=\"" << (wantsChildren ? "true" : "false") << doubleQuoteComma; if (isChildrenNeeded()) str << "children=<needed>,"; @@ -604,10 +604,6 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item, mi = item["editformat"]; data.editformat = mi.toInt(); - mi = item["typeformats"]; - if (mi.isValid()) - data.typeFormats = QString::fromUtf8(mi.data()); - mi = item["valueelided"]; if (mi.isValid()) data.elided = mi.toInt(); diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h index 1423127b8e..7191e58637 100644 --- a/src/plugins/debugger/watchdata.h +++ b/src/plugins/debugger/watchdata.h @@ -72,7 +72,7 @@ public: bool isChildrenNeeded() const { return state & ChildrenNeeded; } void setChildrenNeeded() { state = State(state | ChildrenNeeded); } void setChildrenUnneeded() { state = State(state & ~ChildrenNeeded); } - void setHasChildren(bool c) { hasChildren = c; if (!c) setChildrenUnneeded(); } + void setHasChildren(bool c) { wantsChildren = c; if (!c) setChildrenUnneeded(); } bool isLocal() const { return iname.startsWith("local."); } bool isWatcher() const { return iname.startsWith("watch."); } @@ -113,7 +113,6 @@ public: QString value; // Displayed value QByteArray editvalue; // Displayed value qint32 editformat; // Format of displayed value - QString typeFormats; // Selection of formats of displayed value QByteArray type; // Type for further processing QString displayedType;// Displayed type (optional) quint64 address; // Displayed address of the actual object @@ -122,7 +121,7 @@ public: uint bitpos; // Position within bit fields uint bitsize; // Size in case of bit fields int elided; // Full size if value was cut off, -1 if cut on unknown size, 0 otherwise - bool hasChildren; + bool wantsChildren; bool valueEnabled; // Value will be enabled or not bool valueEditable; // Value will be editable bool error; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index f42a96b746..ed2a051d08 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -110,8 +110,6 @@ static QByteArray stripForFormat(const QByteArray &ba) class SeparatedView : public QTabWidget { - Q_OBJECT - public: SeparatedView() : QTabWidget(Internal::mainWindow()) { @@ -199,26 +197,27 @@ public: explicit WatchModel(WatchHandler *handler); static QString nameForFormat(int format); - TypeFormatList typeFormatList(const WatchData &value) const; QVariant data(const QModelIndex &idx, int role) const; bool setData(const QModelIndex &idx, const QVariant &value, int role); - void insertDataItem(const WatchData &data); void reinsertAllData(); void reinsertAllDataHelper(WatchItem *item, QList<WatchData> *data); QString displayForAutoTest(const QByteArray &iname) const; void reinitialize(bool includeInspectData = false); - friend QDebug operator<<(QDebug d, const WatchModel &m); + WatchItem *findItem(const QByteArray &iname) const; + void insertItem(WatchItem *item); + void reexpandItems(); - void showInEditorHelper(QString *contents, WatchItem *item, int level); void setCurrentItem(const QByteArray &iname); + void showEditValue(const WatchData &data); QString removeNamespaces(QString str) const; DebuggerEngine *engine() const; bool contentIsValid() const; +public: WatchHandler *m_handler; // Not owned. WatchItem *root() const { return static_cast<WatchItem *>(rootItem()); } @@ -228,21 +227,13 @@ public: WatchItem *m_returnRoot; // Not owned. WatchItem *m_tooltipRoot; // Not owned. + SeparatedView m_separatedView; + QSet<QByteArray> m_expandedINames; QTimer m_requestUpdateTimer; - TypeFormatList builtinTypeFormatList(const WatchData &data) const; - QStringList dumperTypeFormatList(const WatchData &data) const; DumperTypeFormats m_reportedTypeFormats; - - WatchItem *createItem(const QByteArray &iname); - WatchItem *findItem(const QByteArray &iname) const; - friend class WatchItem; - typedef QHash<QByteArray, QString> ValueCache; - ValueCache m_valueCache; - - void insertItem(WatchItem *item); - void reexpandItems(); + QHash<QByteArray, QString> m_valueCache; }; WatchModel::WatchModel(WatchHandler *handler) @@ -293,31 +284,21 @@ WatchItem *WatchModel::findItem(const QByteArray &iname) const WatchItem *WatchItem::findItem(const QByteArray &iname) { - if (d.iname == iname) + if (this->iname == iname) return this; foreach (TreeItem *child, children()) { auto witem = static_cast<WatchItem *>(child); - if (witem->d.iname == iname) + if (witem->iname == iname) return witem; - if (witem->d.isAncestorOf(iname)) + if (witem->isAncestorOf(iname)) return witem->findItem(iname); } return 0; } -void WatchModel::reinsertAllData() -{ - QList<WatchData> list; - foreach (TreeItem *child, rootItem()->children()) - reinsertAllDataHelper(static_cast<WatchItem *>(child), &list); - reinitialize(true); - for (int i = 0, n = list.size(); i != n; ++i) - insertDataItem(list.at(i)); -} - void WatchModel::reinsertAllDataHelper(WatchItem *item, QList<WatchData> *data) { - data->append(item->d); + data->append(*item); // Slices intentionally. data->back().setAllUnneeded(); foreach (TreeItem *child, item->children()) reinsertAllDataHelper(static_cast<WatchItem *>(child), data); @@ -498,64 +479,63 @@ static QString translate(const QString &str) QString WatchItem::formattedValue() const { - if (d.type == "bool") { - if (d.value == QLatin1String("0")) + if (type == "bool") { + if (value == QLatin1String("0")) return QLatin1String("false"); - if (d.value == QLatin1String("1")) + if (value == QLatin1String("1")) return QLatin1String("true"); - return d.value; + return value; } const int format = itemFormat(); // Append quoted, printable character also for decimal. - if (d.type.endsWith("char") || d.type.endsWith("QChar")) { + if (type.endsWith("char") || type.endsWith("QChar")) { bool ok; - const int code = d.value.toInt(&ok); - return ok ? reformatCharacter(code, format) : d.value; + const int code = value.toInt(&ok); + return ok ? reformatCharacter(code, format) : value; } if (format == HexadecimalIntegerFormat || format == DecimalIntegerFormat || format == OctalIntegerFormat || format == BinaryIntegerFormat) { - bool isSigned = d.value.startsWith(QLatin1Char('-')); - quint64 raw = isSigned ? quint64(d.value.toLongLong()) : d.value.toULongLong(); - return reformatInteger(raw, format, d.size, isSigned); + bool isSigned = value.startsWith(QLatin1Char('-')); + quint64 raw = isSigned ? quint64(value.toLongLong()) : value.toULongLong(); + return reformatInteger(raw, format, size, isSigned); } if (format == ScientificFloatFormat) { - double dd = d.value.toDouble(); + double dd = value.toDouble(); return QString::number(dd, 'e'); } if (format == CompactFloatFormat) { - double dd = d.value.toDouble(); + double dd = value.toDouble(); return QString::number(dd, 'g'); } - if (d.type == "va_list") - return d.value; + if (type == "va_list") + return value; - if (!isPointerType(d.type) && !d.isVTablePointer()) { + if (!isPointerType(type) && !isVTablePointer()) { bool ok = false; - qulonglong integer = d.value.toULongLong(&ok, 0); + qulonglong integer = value.toULongLong(&ok, 0); if (ok) { const int format = itemFormat(); - return reformatInteger(integer, format, d.size, false); + return reformatInteger(integer, format, size, false); } } - if (d.elided) { - QString v = d.value; + if (elided) { + QString v = value; v.chop(1); v = translate(v); - QString len = d.elided > 0 ? QString::number(d.elided) - : QLatin1String("unknown length"); + QString len = elided > 0 ? QString::number(elided) : QLatin1String("unknown length"); return v + QLatin1String("\"... (") + len + QLatin1Char(')'); } - return translate(d.value); + return translate(value); } // Get a pointer address from pointer values reported by the debugger. @@ -573,14 +553,14 @@ static inline quint64 pointerValue(QString data) // Return the type used for editing int WatchItem::editType() const { - if (d.type == "bool") + if (type == "bool") return QVariant::Bool; - if (isIntType(d.type)) - return d.type.contains('u') ? QVariant::ULongLong : QVariant::LongLong; - if (isFloatType(d.type)) + if (isIntType(type)) + return type.contains('u') ? QVariant::ULongLong : QVariant::LongLong; + if (isFloatType(type)) return QVariant::Double; // Check for pointers using hex values (0xAD00 "Hallo") - if (isPointerType(d.type) && d.value.startsWith(QLatin1String("0x"))) + if (isPointerType(type) && value.startsWith(QLatin1String("0x"))) return QVariant::ULongLong; return QVariant::String; } @@ -590,21 +570,21 @@ QVariant WatchItem::editValue() const { switch (editType()) { case QVariant::Bool: - return d.value != QLatin1String("0") && d.value != QLatin1String("false"); + return value != QLatin1String("0") && value != QLatin1String("false"); case QVariant::ULongLong: - if (isPointerType(d.type)) // Fix pointer values (0xAD00 "Hallo" -> 0xAD00) - return QVariant(pointerValue(d.value)); - return QVariant(d.value.toULongLong()); + if (isPointerType(type)) // Fix pointer values (0xAD00 "Hallo" -> 0xAD00) + return QVariant(pointerValue(value)); + return QVariant(value.toULongLong()); case QVariant::LongLong: - return QVariant(d.value.toLongLong()); + return QVariant(value.toLongLong()); case QVariant::Double: - return QVariant(d.value.toDouble()); + return QVariant(value.toDouble()); default: break; } // Some string value: '0x434 "Hallo"': // Remove quotes and replace newlines, which will cause line edit troubles. - QString stringValue = d.value; + QString stringValue = value; if (stringValue.endsWith(QLatin1Char('"'))) { const int leadingDoubleQuote = stringValue.indexOf(QLatin1Char('"')); if (leadingDoubleQuote != stringValue.size() - 1) { @@ -618,11 +598,11 @@ QVariant WatchItem::editValue() const bool WatchItem::canFetchMore() const { - if (!d.hasChildren) + if (!wantsChildren) return false; if (!watchModel()) return false; - if (!watchModel()->contentIsValid() && !d.isInspect()) + if (!watchModel()->contentIsValid() && !isInspect()) return false; return !fetchTriggered; } @@ -632,11 +612,11 @@ void WatchItem::fetchMore() if (fetchTriggered) return; - watchModel()->m_expandedINames.insert(d.iname); + watchModel()->m_expandedINames.insert(iname); fetchTriggered = true; if (children().isEmpty()) { - d.setChildrenNeeded(); - watchModel()->engine()->updateWatchData(d); + setChildrenNeeded(); + watchModel()->engine()->updateWatchItem(this); } } @@ -654,10 +634,10 @@ static QString truncateValue(QString v) int WatchItem::itemFormat() const { - const int individualFormat = theIndividualFormats.value(d.iname, AutomaticFormat); + const int individualFormat = theIndividualFormats.value(iname, AutomaticFormat); if (individualFormat != AutomaticFormat) return individualFormat; - return theTypeFormats.value(stripForFormat(d.type), AutomaticFormat); + return theTypeFormats.value(stripForFormat(type), AutomaticFormat); } bool WatchModel::contentIsValid() const @@ -671,17 +651,17 @@ bool WatchModel::contentIsValid() const QString WatchItem::expression() const { - if (!d.exp.isEmpty()) - return QString::fromLatin1(d.exp); - if (d.address && !d.type.isEmpty()) { + if (!exp.isEmpty()) + return QString::fromLatin1(exp); + if (address && !type.isEmpty()) { return QString::fromLatin1("*(%1*)%2"). - arg(QLatin1String(d.type), QLatin1String(d.hexAddress())); + arg(QLatin1String(type), QLatin1String(hexAddress())); } if (const WatchItem *p = parentItem()) { - if (!p->d.exp.isEmpty()) - return QString::fromLatin1("(%1).%2").arg(QString::fromLatin1(p->d.exp), d.name); + if (!p->exp.isEmpty()) + return QString::fromLatin1("(%1).%2").arg(QString::fromLatin1(p->exp), name); } - return d.name; + return name; } QString WatchItem::displayName() const @@ -689,12 +669,12 @@ QString WatchItem::displayName() const QString result; if (!parentItem()) return result; - if (d.iname.startsWith("return")) + if (iname.startsWith("return")) result = WatchModel::tr("returned value"); - else if (d.name == QLatin1String("*")) - result = QLatin1Char('*') + parentItem()->d.name; + else if (name == QLatin1String("*")) + result = QLatin1Char('*') + parentItem()->name; else - result = watchModel()->removeNamespaces(d.name); + result = watchModel()->removeNamespaces(name); // Simplyfy names that refer to base classes. if (result.startsWith(QLatin1Char('['))) { @@ -709,20 +689,20 @@ QString WatchItem::displayName() const QString WatchItem::displayValue() const { QString result = watchModel()->removeNamespaces(truncateValue(formattedValue())); - if (result.isEmpty() && d.address) - result += QString::fromLatin1("@0x" + QByteArray::number(d.address, 16)); -// if (d.origaddr) -// result += QString::fromLatin1(" (0x" + QByteArray::number(d.origaddr, 16) + ')'); + if (result.isEmpty() && address) + result += QString::fromLatin1("@0x" + QByteArray::number(address, 16)); +// if (origaddr) +// result += QString::fromLatin1(" (0x" + QByteArray::number(origaddr, 16) + ')'); return result; } QString WatchItem::displayType() const { - QString result = d.displayedType.isEmpty() - ? niceTypeHelper(d.type) - : d.displayedType; - if (d.bitsize) - result += QString::fromLatin1(":%1").arg(d.bitsize); + QString result = displayedType.isEmpty() + ? niceTypeHelper(type) + : displayedType; + if (bitsize) + result += QString::fromLatin1(":%1").arg(bitsize); result.remove(QLatin1Char('\'')); result = watchModel()->removeNamespaces(result); return result; @@ -733,13 +713,13 @@ QColor WatchItem::valueColor() const static const QColor red(200, 0, 0); static const QColor gray(140, 140, 140); if (watchModel()) { - if (!d.valueEnabled) + if (!valueEnabled) return gray; - if (!watchModel()->contentIsValid() && !d.isInspect()) + if (!watchModel()->contentIsValid() && !isInspect()) return gray; - if (d.value.isEmpty()) // This might still show 0x... + if (value.isEmpty()) // This might still show 0x... return gray; - if (d.value != watchModel()->m_valueCache.value(d.iname)) + if (value != watchModel()->m_valueCache.value(iname)) return red; } return QColor(); @@ -752,10 +732,10 @@ QVariant WatchItem::data(int column, int role) const return QVariant(editType()); case LocalsNameRole: - return QVariant(d.name); + return QVariant(name); case LocalsIntegerBaseRole: - if (isPointerType(d.type)) // Pointers using 0x-convention + if (isPointerType(type)) // Pointers using 0x-convention return QVariant(16); return QVariant(formatToIntegerBase(itemFormat())); @@ -767,9 +747,9 @@ QVariant WatchItem::data(int column, int role) const return editValue(); case 2: // FIXME:: To be tested: Can debuggers handle those? - if (!d.displayedType.isEmpty()) - return d.displayedType; - return QString::fromUtf8(d.type); + if (!displayedType.isEmpty()) + return displayedType; + return QString::fromUtf8(type); } } @@ -786,7 +766,7 @@ QVariant WatchItem::data(int column, int role) const case Qt::ToolTipRole: return boolSetting(UseToolTipsInLocalsView) - ? d.toToolTip() : QVariant(); + ? toToolTip() : QVariant(); case Qt::ForegroundRole: if (column == 1) @@ -796,51 +776,51 @@ QVariant WatchItem::data(int column, int role) const return expression(); case LocalsRawExpressionRole: - return d.exp; + return exp; case LocalsINameRole: - return d.iname; + return iname; case LocalsExpandedRole: - return watchModel()->m_expandedINames.contains(d.iname); + return watchModel()->m_expandedINames.contains(iname); case LocalsTypeFormatListRole: - return QVariant::fromValue(watchModel()->typeFormatList(d)); + return QVariant::fromValue(typeFormatList()); case LocalsTypeRole: return watchModel()->removeNamespaces(displayType()); case LocalsRawTypeRole: - return QString::fromLatin1(d.type); + return QString::fromLatin1(type); case LocalsTypeFormatRole: - return theTypeFormats.value(stripForFormat(d.type), AutomaticFormat); + return theTypeFormats.value(stripForFormat(type), AutomaticFormat); case LocalsIndividualFormatRole: - return theIndividualFormats.value(d.iname, AutomaticFormat); + return theIndividualFormats.value(iname, AutomaticFormat); case LocalsRawValueRole: - return d.value; + return value; case LocalsObjectAddressRole: - return d.address; + return address; case LocalsPointerAddressRole: - return d.origaddr; + return origaddr; case LocalsIsWatchpointAtObjectAddressRole: { BreakpointParameters bp(WatchpointAtAddress); - bp.address = d.address; + bp.address = address; return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0; } case LocalsSizeRole: - return QVariant(d.size); + return QVariant(size); case LocalsIsWatchpointAtPointerAddressRole: - if (isPointerType(d.type)) { + if (isPointerType(type)) { BreakpointParameters bp(WatchpointAtAddress); - bp.address = pointerValue(d.value); + bp.address = pointerValue(value); return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0; } return false; @@ -871,7 +851,6 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role WatchItem *item = static_cast<WatchItem *>(itemFromIndex(idx)); QTC_ASSERT(item, return false); - const WatchData &data = item->d; switch (role) { case Qt::EditRole: @@ -881,35 +860,35 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role break; } case 1: // Change value - engine()->assignValueInDebugger(&data, item->expression(), value); + engine()->assignValueInDebugger(item, item->expression(), value); break; case 2: // TODO: Implement change type. - engine()->assignValueInDebugger(&data, item->expression(), value); + engine()->assignValueInDebugger(item, item->expression(), value); break; } case LocalsExpandedRole: if (value.toBool()) { // Should already have been triggered by fetchMore() - //QTC_CHECK(m_expandedINames.contains(data.iname)); - m_expandedINames.insert(data.iname); + //QTC_CHECK(m_expandedINames.contains(item->iname)); + m_expandedINames.insert(item->iname); } else { - m_expandedINames.remove(data.iname); + m_expandedINames.remove(item->iname); } emit columnAdjustmentRequested(); break; case LocalsTypeFormatRole: - m_handler->setFormat(data.type, value.toInt()); - engine()->updateWatchData(data); + m_handler->setFormat(item->type, value.toInt()); + engine()->updateWatchItem(item); break; case LocalsIndividualFormatRole: { const int format = value.toInt(); if (format == AutomaticFormat) - theIndividualFormats.remove(data.iname); + theIndividualFormats.remove(item->iname); else - theIndividualFormats[data.iname] = format; - engine()->updateWatchData(data); + theIndividualFormats[item->iname] = format; + engine()->updateWatchItem(item); break; } } @@ -931,29 +910,29 @@ Qt::ItemFlags WatchItem::flags(int column) const const Qt::ItemFlags notEditable = Qt::ItemIsSelectable | Qt::ItemIsEnabled; const Qt::ItemFlags editable = notEditable | Qt::ItemIsEditable; - if (d.isWatcher()) { + if (isWatcher()) { if (state != InferiorStopOk && state != DebuggerNotReady && state != DebuggerFinished && !engine->hasCapability(AddWatcherWhileRunningCapability)) return Qt::ItemFlags(); - if (column == 0 && d.iname.count('.') == 1) + if (column == 0 && iname.count('.') == 1) return editable; // Watcher names are editable. - if (!d.name.isEmpty()) { + if (!name.isEmpty()) { // FIXME: Forcing types is not implemented yet. //if (idx.column() == 2) // return editable; // Watcher types can be set by force. - if (column == 1 && d.valueEditable) + if (column == 1 && valueEditable) return editable; // Watcher values are sometimes editable. } - } else if (d.isLocal()) { + } else if (isLocal()) { if (state != InferiorStopOk && !engine->hasCapability(AddWatcherWhileRunningCapability)) return Qt::ItemFlags(); - if (column == 1 && d.valueEditable) + if (column == 1 && valueEditable) return editable; // Locals values are sometimes editable. - } else if (d.isInspect()) { - if (column == 1 && d.valueEditable) + } else if (isInspect()) { + if (column == 1 && valueEditable) return editable; // Inspector values are sometimes editable. } return notEditable; @@ -991,26 +970,26 @@ QString WatchModel::nameForFormat(int format) return QString(); } -TypeFormatList WatchModel::typeFormatList(const WatchData &data) const +TypeFormatList WatchItem::typeFormatList() const { TypeFormatList formats; // Types supported by dumpers: // Hack: Compensate for namespaces. - QString type = QLatin1String(stripForFormat(data.type)); - int pos = type.indexOf(QLatin1String("::Q")); - if (pos >= 0 && type.count(QLatin1Char(':')) == 2) - type.remove(0, pos + 2); - pos = type.indexOf(QLatin1Char('<')); + QString t = QLatin1String(stripForFormat(type)); + int pos = t.indexOf(QLatin1String("::Q")); + if (pos >= 0 && t.count(QLatin1Char(':')) == 2) + t.remove(0, pos + 2); + pos = t.indexOf(QLatin1Char('<')); if (pos >= 0) - type.truncate(pos); - type.replace(QLatin1Char(':'), QLatin1Char('_')); - QStringList reported = m_reportedTypeFormats.value(type); + t.truncate(pos); + t.replace(QLatin1Char(':'), QLatin1Char('_')); + QStringList reported = watchModel()->m_reportedTypeFormats.value(t); for (int i = 0, n = reported.size(); i != n; ++i) formats.append(TypeFormatItem(reported.at(i), i)); // Fixed artificial string and pointer types. - if (data.origaddr || isPointerType(data.type)) { + if (origaddr || isPointerType(type)) { formats.append(RawFormat); formats.append(Latin1StringFormat); formats.append(SeparateLatin1StringFormat); @@ -1023,7 +1002,7 @@ TypeFormatList WatchModel::typeFormatList(const WatchData &data) const formats.append(Array100Format); formats.append(Array1000Format); formats.append(Array10000Format); - } else if (data.type.contains("char[") || data.type.contains("char [")) { + } else if (type.contains("char[") || type.contains("char [")) { formats.append(RawFormat); formats.append(Latin1StringFormat); formats.append(SeparateLatin1StringFormat); @@ -1036,14 +1015,14 @@ TypeFormatList WatchModel::typeFormatList(const WatchData &data) const // Fixed artificial floating point types. bool ok = false; - data.value.toDouble(&ok); + value.toDouble(&ok); if (ok) { formats.append(CompactFloatFormat); formats.append(ScientificFloatFormat); } // Fixed artificial integral types. - QString v = data.value; + QString v = value; if (v.startsWith(QLatin1Char('-'))) v = v.mid(1); v.toULongLong(&ok, 10); @@ -1093,25 +1072,11 @@ static bool watchDataLessThan(const QByteArray &iname1, int sortId1, return qstrcmp(iname1.constData() + cmpPos1, iname2.constData() + cmpPos2) < 0; } -// Sort key for watch data consisting of iname and numerical sort id. -struct WatchDataSortKey -{ - explicit WatchDataSortKey(const WatchData &wd) - : iname(wd.iname), sortId(wd.sortId) {} - QByteArray iname; - int sortId; -}; - -inline bool operator<(const WatchDataSortKey &k1, const WatchDataSortKey &k2) -{ - return watchDataLessThan(k1.iname, k1.sortId, k2.iname, k2.sortId); -} - bool watchItemSorter(const TreeItem *item1, const TreeItem *item2) { const WatchItem *it1 = static_cast<const WatchItem *>(item1); const WatchItem *it2 = static_cast<const WatchItem *>(item2); - return watchDataLessThan(it1->d.iname, it1->d.sortId, it2->d.iname, it2->d.sortId); + return watchDataLessThan(it1->iname, it1->sortId, it2->iname, it2->sortId); } static int findInsertPosition(const QVector<TreeItem *> &list, const WatchItem *item) @@ -1121,27 +1086,38 @@ static int findInsertPosition(const QVector<TreeItem *> &list, const WatchItem * return it - list.begin(); } -int WatchItem::requestedFormat() const +void WatchModel::reinsertAllData() { - int format = theIndividualFormats.value(d.iname, AutomaticFormat); - if (format == AutomaticFormat) - format = theTypeFormats.value(stripForFormat(d.type), AutomaticFormat); - return format; + QList<WatchData> list; + foreach (TreeItem *child, rootItem()->children()) + reinsertAllDataHelper(static_cast<WatchItem *>(child), &list); + + reinitialize(true); + + for (int i = 0, n = list.size(); i != n; ++i) { + const WatchData &data = list.at(i); + QTC_ASSERT(!data.iname.isEmpty(), qDebug() << data.toString(); return); + // Add new entry. + WatchItem *parent = findItem(parentName(data.iname)); + QTC_ASSERT(parent, return); + WatchItem *newItem = new WatchItem(data); + newItem->sortChildren(&watchItemSorter); + const int row = findInsertPosition(parent->children(), newItem); + parent->insertChild(row, newItem); + if (m_expandedINames.contains(parent->iname)) { + emit inameIsExpanded(parent->iname); + emit itemIsExpanded(indexFromItem(parent)); + } + showEditValue(data); + } } -void WatchItem::showInEditorHelper(QString *contents, int depth) const +int WatchItem::requestedFormat() const { - const QChar tab = QLatin1Char('\t'); - const QChar nl = QLatin1Char('\n'); - contents->append(QString(depth, tab)); - contents->append(d.name); - contents->append(tab); - contents->append(d.value); - contents->append(tab); - contents->append(QString::fromLatin1(d.type)); - contents->append(nl); - foreach (const TreeItem *child, children()) - static_cast<const WatchItem *>(child)->showInEditorHelper(contents, depth + 1); + int format = theIndividualFormats.value(iname, AutomaticFormat); + if (format == AutomaticFormat) + format = theTypeFormats.value(stripForFormat(type), AutomaticFormat); + return format; } void WatchModel::setCurrentItem(const QByteArray &iname) @@ -1165,15 +1141,13 @@ WatchHandler::WatchHandler(DebuggerEngine *engine) m_contentsValid = false; m_contentsValid = true; // FIXME m_resetLocationScheduled = false; - m_separatedView = new SeparatedView; } WatchHandler::~WatchHandler() { - delete m_separatedView; - m_separatedView = 0; // Do it manually to prevent calling back in model destructors // after m_cache is destroyed. + m_model->disconnect(); delete m_model; m_model = 0; } @@ -1185,7 +1159,7 @@ void WatchHandler::cleanup() saveWatchers(); m_model->reinitialize(); emit m_model->updateFinished(); - m_separatedView->hide(); + m_model->m_separatedView.hide(); } void WatchHandler::insertItem(WatchItem *item) @@ -1195,44 +1169,19 @@ void WatchHandler::insertItem(WatchItem *item) void WatchModel::insertItem(WatchItem *item) { - WatchItem *existing = findItem(item->d.iname); + WatchItem *existing = findItem(item->iname); if (existing) removeItem(existing); - WatchItem *parent = findItem(parentName(item->d.iname)); + //item->walkTree([item](TreeItem *sub) { sub->sortChildren(&watchItemSorter); }); + item->sortChildren(&watchItemSorter); + + WatchItem *parent = findItem(parentName(item->iname)); QTC_ASSERT(parent, return); const int row = findInsertPosition(parent->children(), item); parent->insertChild(row, item); } -void WatchModel::insertDataItem(const WatchData &data) -{ - QTC_ASSERT(!data.iname.isEmpty(), qDebug() << data.toString(); return); - - if (WatchItem *item = findItem(data.iname)) { - // Remove old children. - item->fetchTriggered = false; - item->removeChildren(); - - // Overwrite old entry. - item->d = data; - item->update(); - } else { - // Add new entry. - WatchItem *parent = findItem(parentName(data.iname)); - QTC_ASSERT(parent, return); - WatchItem *newItem = new WatchItem; - newItem->d = data; - const int row = findInsertPosition(parent->children(), newItem); - parent->insertChild(row, newItem); - if (m_expandedINames.contains(parent->d.iname)) { - emit inameIsExpanded(parent->d.iname); - emit itemIsExpanded(indexFromItem(parent)); - } - } - m_handler->showEditValue(data); -} - void WatchModel::reexpandItems() { foreach (const QByteArray &iname, m_expandedINames) { @@ -1248,11 +1197,6 @@ void WatchModel::reexpandItems() } } -void WatchHandler::insertData(const WatchData &data) -{ - m_model->insertDataItem(data); -} - void WatchHandler::removeAllData(bool includeInspectData) { m_model->reinitialize(includeInspectData); @@ -1265,7 +1209,7 @@ void WatchHandler::resetValueCache() TreeItem *root = m_model->rootItem(); root->walkTree([this, root](TreeItem *item) { auto watchItem = static_cast<WatchItem *>(item); - m_model->m_valueCache[watchItem->d.iname] = watchItem->d.value; + m_model->m_valueCache[watchItem->iname] = watchItem->value; }); } @@ -1307,8 +1251,8 @@ void WatchHandler::removeItemByIName(const QByteArray &iname) WatchItem *item = m_model->findItem(iname); if (!item) return; - if (item->d.isWatcher()) { - theWatcherNames.remove(item->d.exp); + if (item->isWatcher()) { + theWatcherNames.remove(item->exp); saveWatchers(); } m_model->removeItem(item); @@ -1330,19 +1274,18 @@ void WatchHandler::watchExpression(const QString &exp0, const QString &name) theWatcherNames[exp] = theWatcherCount++; - WatchData data; - data.exp = exp; - data.name = name.isEmpty() ? exp0 : name; - data.iname = watcherName(exp); + auto item = new WatchItem; + item->exp = exp; + item->name = name.isEmpty() ? exp0 : name; + item->iname = watcherName(exp); saveWatchers(); if (m_engine->state() == DebuggerNotReady) { - data.setAllUnneeded(); - data.setValue(QString(QLatin1Char(' '))); - data.setHasChildren(false); - m_model->insertDataItem(data); + item->setAllUnneeded(); + item->setValue(QString(QLatin1Char(' '))); + m_model->insertItem(item); } else { - m_engine->updateWatchData(data); + m_engine->updateWatchItem(item); } updateWatchersWindow(); } @@ -1371,12 +1314,12 @@ static void swapEndian(char *d, int nchar) } } -void WatchHandler::showEditValue(const WatchData &data) +void WatchModel::showEditValue(const WatchData &data) { const QByteArray key = data.address ? data.hexAddress() : data.iname; switch (data.editformat) { case StopDisplay: - m_separatedView->removeObject(data.iname); + m_separatedView.removeObject(data.iname); break; case DisplayImageData: case DisplayImageFile: { // QImage @@ -1414,7 +1357,7 @@ void WatchHandler::showEditValue(const WatchData &data) tr("%1 Object at %2").arg(QLatin1String(data.type), QLatin1String(data.hexAddress())) : tr("%1 Object at Unknown Address").arg(QLatin1String(data.type)); - ImageViewer *v = m_separatedView->prepareObject<ImageViewer>(key, title); + ImageViewer *v = m_separatedView.prepareObject<ImageViewer>(key, title); v->setProperty(INameProperty, data.iname); v->setImage(im); break; @@ -1430,7 +1373,7 @@ void WatchHandler::showEditValue(const WatchData &data) str = QString::fromLatin1(ba.constData(), ba.size()); else if (data.editformat == DisplayUtf8String) str = QString::fromUtf8(ba.constData(), ba.size()); - QTextEdit *t = m_separatedView->prepareObject<QTextEdit>(key, data.name); + QTextEdit *t = m_separatedView.prepareObject<QTextEdit>(key, data.name); t->setProperty(INameProperty, data.iname); t->setText(str); break; @@ -1557,37 +1500,29 @@ WatchModelBase *WatchHandler::model() const return m_model; } -const WatchData *WatchHandler::watchData(const QModelIndex &idx) const +const WatchItem *WatchHandler::watchItem(const QModelIndex &idx) const { - TreeItem *item = m_model->itemFromIndex(idx); - return item ? &static_cast<WatchItem *>(item)->d : 0; + return static_cast<WatchItem *>(m_model->itemFromIndex(idx)); } void WatchHandler::fetchMore(const QByteArray &iname) const { - WatchItem *item = m_model->findItem(iname); - if (item) + if (WatchItem *item = m_model->findItem(iname)) item->fetchMore(); } -const WatchData *WatchHandler::findData(const QByteArray &iname) const -{ - const WatchItem *item = m_model->findItem(iname); - return item ? &item->d : 0; -} - WatchItem *WatchHandler::findItem(const QByteArray &iname) const { return m_model->findItem(iname); } -const WatchData *WatchHandler::findCppLocalVariable(const QString &name) const +const WatchItem *WatchHandler::findCppLocalVariable(const QString &name) const { // Can this be found as a local variable? const QByteArray localsPrefix("local."); QByteArray iname = localsPrefix + name.toLatin1(); - if (const WatchData *wd = findData(iname)) - return wd; + if (const WatchItem *item = findItem(iname)) + return item; // // Nope, try a 'local.this.m_foo'. // iname.insert(localsPrefix.size(), "this."); // if (const WatchData *wd = findData(iname)) @@ -1615,9 +1550,9 @@ int WatchHandler::format(const QByteArray &iname) const { int result = AutomaticFormat; if (const WatchItem *item = m_model->findItem(iname)) { - result = theIndividualFormats.value(item->d.iname, AutomaticFormat); + result = theIndividualFormats.value(item->iname, AutomaticFormat); if (result == AutomaticFormat) - result = theTypeFormats.value(stripForFormat(item->d.type), AutomaticFormat); + result = theTypeFormats.value(stripForFormat(item->type), AutomaticFormat); } return result; } @@ -1716,10 +1651,21 @@ void WatchHandler::addTypeFormats(const QByteArray &type, const QStringList &for m_model->m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats); } +static void showInEditorHelper(const WatchItem *item, QTextStream &ts, int depth) +{ + const QChar tab = QLatin1Char('\t'); + const QChar nl = QLatin1Char('\n'); + ts << QString(depth, tab) << item->name << tab << item->value << tab + << item->type << nl; + foreach (const TreeItem *child, item->children()) + showInEditorHelper(static_cast<const WatchItem *>(child), ts, depth + 1); +} + QString WatchHandler::editorContents() { QString contents; - m_model->root()->showInEditorHelper(&contents, 0); + QTextStream ts(&contents); + showInEditorHelper(m_model->root(), ts, 0); return contents; } @@ -1733,22 +1679,6 @@ DumperTypeFormats WatchHandler::typeFormats() const return m_model->m_reportedTypeFormats; } -void WatchHandler::editTypeFormats(bool includeLocals, const QByteArray &iname) -{ - Q_UNUSED(includeLocals); - TypeFormatsDialog dlg(0); - - //QHashIterator<QString, QStringList> it(m_reportedTypeFormats); - QList<QString> l = m_model->m_reportedTypeFormats.keys(); - Utils::sort(l); - foreach (const QString &ba, l) { - int f = iname.isEmpty() ? AutomaticFormat : format(iname); - dlg.addTypeFormats(ba, m_model->m_reportedTypeFormats.value(ba), f); - } - if (dlg.exec()) - setTypeFormats(dlg.typeFormats()); -} - void WatchHandler::scheduleResetLocation() { m_contentsValid = false; @@ -1828,30 +1758,30 @@ WatchItem::WatchItem() WatchItem::WatchItem(const QByteArray &i, const QString &n) { fetchTriggered = false; - d.iname = i; - d.name = n; + iname = i; + name = n; } WatchItem::WatchItem(const WatchData &data) - : d(data), fetchTriggered(false) + : WatchData(data), fetchTriggered(false) { } WatchItem::WatchItem(const GdbMi &data) : fetchTriggered(false) { - d.iname = data["iname"].data(); + iname = data["iname"].data(); GdbMi wname = data["wname"]; if (wname.isValid()) // Happens (only) for watched expressions. - d.name = QString::fromUtf8(QByteArray::fromHex(wname.data())); + name = QString::fromUtf8(QByteArray::fromHex(wname.data())); else - d.name = QString::fromLatin1(data["name"].data()); + name = QString::fromLatin1(data["name"].data()); parseWatchData(data); if (wname.isValid()) - d.exp = d.name.toUtf8(); + exp = name.toUtf8(); } WatchItem *WatchItem::parentItem() const @@ -1872,8 +1802,9 @@ WatchModel *WatchItem::watchModel() void WatchItem::parseWatchData(const GdbMi &input) { auto itemHandler = [this](const WatchData &data) { - d = data; + WatchData::operator=(data); }; + auto childHandler = [this](const WatchData &innerData, const GdbMi &innerInput) { WatchItem *item = new WatchItem(innerData); item->parseWatchData(innerInput); @@ -1889,10 +1820,8 @@ void WatchItem::parseWatchData(const GdbMi &input) decodeArrayData(itemAdder, childTemplate, encodedData, encoding); }; - parseChildrenData(d, input, itemHandler, childHandler, arrayDecoder); + parseChildrenData(*this, input, itemHandler, childHandler, arrayDecoder); } } // namespace Internal } // namespace Debugger - -#include "watchhandler.moc" diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index c9d4dc6418..318c9bc6a2 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -35,17 +35,34 @@ #include <utils/treemodel.h> -#include <QPointer> #include <QVector> namespace Debugger { namespace Internal { class DebuggerCommand; -class SeparatedView; +class DebuggerEngine; class WatchModel; -class WatchItem : public Utils::TreeItem +class TypeFormatItem +{ +public: + TypeFormatItem() : format(-1) {} + TypeFormatItem(const QString &display, int format); + + QString display; + int format; +}; + +class TypeFormatList : public QVector<TypeFormatItem> +{ +public: + using QVector::append; + void append(int format); + TypeFormatItem find(int format) const; +}; + +class WatchItem : public Utils::TreeItem, public WatchData { public: WatchItem(); @@ -53,14 +70,6 @@ public: explicit WatchItem(const WatchData &data); explicit WatchItem(const GdbMi &data); - WatchItem *parentItem() const; - const WatchModel *watchModel() const; - WatchModel *watchModel(); - - QVariant data(int column, int role) const; - Qt::ItemFlags flags(int column) const; - - bool canFetchMore() const; void fetchMore(); QString displayName() const; @@ -76,12 +85,19 @@ public: QColor valueColor() const; int requestedFormat() const; - void showInEditorHelper(QString *contents, int depth) const; WatchItem *findItem(const QByteArray &iname); - void parseWatchData(const GdbMi &input); -public: - WatchData d; +private: + WatchItem *parentItem() const; + const WatchModel *watchModel() const; + WatchModel *watchModel(); + TypeFormatList typeFormatList() const; + + bool canFetchMore() const; + QVariant data(int column, int role) const; + Qt::ItemFlags flags(int column) const; + + void parseWatchData(const GdbMi &input); bool fetchTriggered; }; @@ -125,35 +141,6 @@ enum DisplayFormat ScientificFloatFormat, }; - -class TypeFormatItem -{ -public: - TypeFormatItem() : format(-1) {} - TypeFormatItem(const QString &display, int format); - - QString display; - int format; -}; - -class TypeFormatList : public QVector<TypeFormatItem> -{ -public: - using QVector::append; - void append(int format); - TypeFormatItem find(int format) const; -}; - -} // namespace Internal -} // namespace Debugger - -Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList) - -namespace Debugger { -namespace Internal { - -class DebuggerEngine; - class UpdateParameters { public: @@ -196,13 +183,10 @@ public: void watchVariable(const QString &exp); Q_SLOT void clearWatches(); - void showEditValue(const WatchData &data); - - const WatchData *watchData(const QModelIndex &) const; + const WatchItem *watchItem(const QModelIndex &) const; void fetchMore(const QByteArray &iname) const; - const WatchData *findData(const QByteArray &iname) const; WatchItem *findItem(const QByteArray &iname) const; - const WatchData *findCppLocalVariable(const QString &name) const; + const WatchItem *findCppLocalVariable(const QString &name) const; bool hasItem(const QByteArray &iname) const; void loadSessionData(); @@ -229,7 +213,6 @@ public: QByteArray watcherName(const QByteArray &exp); QString editorContents(); - void editTypeFormats(bool includeLocals, const QByteArray &iname); void scheduleResetLocation(); void resetLocation(); @@ -238,7 +221,6 @@ public: void updateWatchersWindow(); void appendFormatRequests(DebuggerCommand *cmd); - void insertData(const WatchData &data); // DEPRECATED void insertItem(WatchItem *item); // Takes ownership. void removeItemByIName(const QByteArray &iname); void removeAllData(bool includeInspectData = false); @@ -259,7 +241,6 @@ private: WatchModel *m_model; // Owned. DebuggerEngine *m_engine; // Not owned. - SeparatedView *m_separatedView; // Owned. bool m_contentsValid; bool m_resetLocationScheduled; @@ -269,5 +250,6 @@ private: } // namespace Debugger Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters) +Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList) #endif // DEBUGGER_WATCHHANDLER_H |