summaryrefslogtreecommitdiff
path: root/src/plugins/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/debugger')
-rw-r--r--src/plugins/debugger/breakhandler.cpp1645
-rw-r--r--src/plugins/debugger/breakhandler.h272
-rw-r--r--src/plugins/debugger/breakpoint.cpp12
-rw-r--r--src/plugins/debugger/breakpoint.h5
-rw-r--r--src/plugins/debugger/breakpointmarker.cpp88
-rw-r--r--src/plugins/debugger/breakwindow.cpp188
-rw-r--r--src/plugins/debugger/breakwindow.h12
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp172
-rw-r--r--src/plugins/debugger/cdb/cdbengine.h7
-rw-r--r--src/plugins/debugger/cdb/cdbparsehelpers.cpp3
-rw-r--r--src/plugins/debugger/commonoptionspage.cpp4
-rw-r--r--src/plugins/debugger/debugger.pro6
-rw-r--r--src/plugins/debugger/debugger.qbs3
-rw-r--r--src/plugins/debugger/debuggeractions.cpp13
-rw-r--r--src/plugins/debugger/debuggeractions.h1
-rw-r--r--src/plugins/debugger/debuggerconstants.h4
-rw-r--r--src/plugins/debugger/debuggercore.h7
-rw-r--r--src/plugins/debugger/debuggerdialogs.cpp87
-rw-r--r--src/plugins/debugger/debuggerengine.cpp195
-rw-r--r--src/plugins/debugger/debuggerengine.h58
-rw-r--r--src/plugins/debugger/debuggeritem.cpp15
-rw-r--r--src/plugins/debugger/debuggeritem.h1
-rw-r--r--src/plugins/debugger/debuggeritemmanager.cpp159
-rw-r--r--src/plugins/debugger/debuggeritemmanager.h31
-rw-r--r--src/plugins/debugger/debuggeritemmodel.cpp311
-rw-r--r--src/plugins/debugger/debuggeritemmodel.h93
-rw-r--r--src/plugins/debugger/debuggerkitconfigwidget.cpp36
-rw-r--r--src/plugins/debugger/debuggerkitconfigwidget.h8
-rw-r--r--src/plugins/debugger/debuggerkitinformation.cpp25
-rw-r--r--src/plugins/debugger/debuggermainwindow.cpp86
-rw-r--r--src/plugins/debugger/debuggermainwindow.h9
-rw-r--r--src/plugins/debugger/debuggeroptionspage.cpp459
-rw-r--r--src/plugins/debugger/debuggeroptionspage.h78
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp415
-rw-r--r--src/plugins/debugger/debuggerprotocol.cpp140
-rw-r--r--src/plugins/debugger/debuggerprotocol.h65
-rw-r--r--src/plugins/debugger/debuggerrunconfigurationaspect.cpp30
-rw-r--r--src/plugins/debugger/debuggerruncontrol.cpp134
-rw-r--r--src/plugins/debugger/debuggerruncontrol.h30
-rw-r--r--src/plugins/debugger/debuggersourcepathmappingwidget.cpp35
-rw-r--r--src/plugins/debugger/debuggerstartparameters.h7
-rw-r--r--src/plugins/debugger/debuggertooltipmanager.cpp897
-rw-r--r--src/plugins/debugger/debuggertooltipmanager.h9
-rw-r--r--src/plugins/debugger/disassembleragent.cpp13
-rw-r--r--src/plugins/debugger/disassembleragent.h5
-rw-r--r--src/plugins/debugger/gdb/attachgdbadapter.cpp16
-rw-r--r--src/plugins/debugger/gdb/attachgdbadapter.h2
-rw-r--r--src/plugins/debugger/gdb/coregdbadapter.cpp37
-rw-r--r--src/plugins/debugger/gdb/coregdbadapter.h7
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp1463
-rw-r--r--src/plugins/debugger/gdb/gdbengine.h183
-rw-r--r--src/plugins/debugger/gdb/gdboptionspage.cpp4
-rw-r--r--src/plugins/debugger/gdb/gdbplainengine.cpp19
-rw-r--r--src/plugins/debugger/gdb/gdbplainengine.h4
-rw-r--r--src/plugins/debugger/gdb/gdbprocess.cpp6
-rw-r--r--src/plugins/debugger/gdb/remotegdbserveradapter.cpp116
-rw-r--r--src/plugins/debugger/gdb/remotegdbserveradapter.h22
-rw-r--r--src/plugins/debugger/gdb/startgdbserverdialog.cpp31
-rw-r--r--src/plugins/debugger/gdb/termgdbadapter.cpp36
-rw-r--r--src/plugins/debugger/gdb/termgdbadapter.h2
-rw-r--r--src/plugins/debugger/imageviewer.cpp4
-rw-r--r--src/plugins/debugger/lldb/lldbengine.cpp606
-rw-r--r--src/plugins/debugger/lldb/lldbengine.h44
-rw-r--r--src/plugins/debugger/loadcoredialog.cpp49
-rw-r--r--src/plugins/debugger/logwindow.cpp46
-rw-r--r--src/plugins/debugger/memoryagent.cpp48
-rw-r--r--src/plugins/debugger/memoryagent.h29
-rw-r--r--src/plugins/debugger/memoryview.cpp39
-rw-r--r--src/plugins/debugger/memoryview.h16
-rw-r--r--src/plugins/debugger/moduleshandler.cpp365
-rw-r--r--src/plugins/debugger/moduleshandler.h15
-rw-r--r--src/plugins/debugger/moduleswindow.cpp4
-rw-r--r--src/plugins/debugger/pdb/pdbengine.cpp99
-rw-r--r--src/plugins/debugger/pdb/pdbengine.h16
-rw-r--r--src/plugins/debugger/qml/baseqmldebuggerclient.cpp3
-rw-r--r--src/plugins/debugger/qml/baseqmldebuggerclient.h8
-rw-r--r--src/plugins/debugger/qml/qmladapter.cpp50
-rw-r--r--src/plugins/debugger/qml/qmladapter.h5
-rw-r--r--src/plugins/debugger/qml/qmlcppengine.cpp41
-rw-r--r--src/plugins/debugger/qml/qmlcppengine.h10
-rw-r--r--src/plugins/debugger/qml/qmlengine.cpp111
-rw-r--r--src/plugins/debugger/qml/qmlengine.h12
-rw-r--r--src/plugins/debugger/qml/qmlinspectoradapter.cpp10
-rw-r--r--src/plugins/debugger/qml/qmlinspectoradapter.h4
-rw-r--r--src/plugins/debugger/qml/qmlinspectoragent.cpp23
-rw-r--r--src/plugins/debugger/qml/qmlinspectoragent.h4
-rw-r--r--src/plugins/debugger/qml/qmllivetextpreview.cpp28
-rw-r--r--src/plugins/debugger/qml/qmlv8debuggerclient.cpp80
-rw-r--r--src/plugins/debugger/qml/qmlv8debuggerclient.h8
-rw-r--r--src/plugins/debugger/qml/qscriptdebuggerclient.cpp68
-rw-r--r--src/plugins/debugger/qml/qscriptdebuggerclient.h6
-rw-r--r--src/plugins/debugger/registerhandler.cpp865
-rw-r--r--src/plugins/debugger/registerhandler.h99
-rw-r--r--src/plugins/debugger/registerwindow.cpp98
-rw-r--r--src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp13
-rw-r--r--src/plugins/debugger/snapshothandler.h4
-rw-r--r--src/plugins/debugger/sourceagent.cpp22
-rw-r--r--src/plugins/debugger/sourceagent.h7
-rw-r--r--src/plugins/debugger/sourceutils.cpp13
-rw-r--r--src/plugins/debugger/stackhandler.cpp28
-rw-r--r--src/plugins/debugger/stackhandler.h22
-rw-r--r--src/plugins/debugger/stackwindow.cpp21
-rw-r--r--src/plugins/debugger/terminal.cpp169
-rw-r--r--src/plugins/debugger/terminal.h (renamed from src/plugins/debugger/breakpointmarker.h)47
-rw-r--r--src/plugins/debugger/unstartedappwatcherdialog.cpp23
-rw-r--r--src/plugins/debugger/unstartedappwatcherdialog.h11
-rw-r--r--src/plugins/debugger/watchdata.cpp71
-rw-r--r--src/plugins/debugger/watchdata.h20
-rw-r--r--src/plugins/debugger/watchhandler.cpp1164
-rw-r--r--src/plugins/debugger/watchhandler.h61
-rw-r--r--src/plugins/debugger/watchwindow.cpp225
-rw-r--r--src/plugins/debugger/watchwindow.h13
112 files changed, 5829 insertions, 6839 deletions
diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index 75534a428a..a13f54326c 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -29,7 +29,6 @@
****************************************************************************/
#include "breakhandler.h"
-#include "breakpointmarker.h"
#include "debuggeractions.h"
#include "debuggercore.h"
@@ -38,6 +37,7 @@
#include "simplifytype.h"
#include <extensionsystem/invoker.h>
+#include <texteditor/textmark.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
@@ -49,17 +49,125 @@
#include <QDir>
#include <QDebug>
-#define BREAK_ASSERT(cond, action) if (cond) {} else { action; }
-//#define BREAK_ASSERT(cond, action) QTC_ASSERT(cond, action)
+using namespace Utils;
+
+namespace Debugger {
+namespace Internal {
+
+struct LocationItem : public TreeItem
+{
+ QVariant data(int column, int role) const
+ {
+ if (role == Qt::DisplayRole) {
+ switch (column) {
+ case 0:
+ return params.id.toString();
+ case 1:
+ return params.functionName;
+ case 4:
+ if (params.address)
+ return QString::fromLatin1("0x%1").arg(params.address, 0, 16);
+ }
+ }
+ return QVariant();
+ }
+
+ BreakpointResponse params;
+};
+
+class BreakpointMarker;
+
+class BreakpointItem : public QObject, public TreeItem
+{
+ Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::BreakHandler)
+
+public:
+ ~BreakpointItem();
+
+ QVariant data(int column, int role) const;
+
+ QIcon icon() const;
+
+ void removeBreakpoint();
+ void updateLineNumberFromMarker(int lineNumber);
+ void updateFileNameFromMarker(const QString &fileName);
+ void changeLineNumberFromMarker(int lineNumber);
+ bool isLocatedAt(const QString &fileName, int lineNumber, bool useMarkerPosition) const;
+
+ bool needsChildren() const;
+
+ void setMarkerFileAndLine(const QString &fileName, int lineNumber);
+
+ void insertSubBreakpoint(const BreakpointResponse &params);
+ QString markerFileName() const;
+ int markerLineNumber() const;
+
+ bool needsChange() const;
+private:
+ friend class BreakHandler;
+ friend class Breakpoint;
+ BreakpointItem(BreakHandler *handler);
+
+ void destroyMarker();
+ void updateMarker();
+ void updateMarkerIcon();
+ void scheduleSynchronization();
+
+ QString toToolTip() const;
+ void setState(BreakpointState state);
+ void deleteThis();
+ bool isEngineRunning() const;
+
+ BreakHandler * const m_handler;
+ const BreakpointModelId m_id;
+ BreakpointParameters m_params;
+ BreakpointState m_state; // Current state of breakpoint.
+ DebuggerEngine *m_engine; // Engine currently handling the breakpoint.
+ BreakpointResponse m_response;
+ BreakpointMarker *m_marker;
+};
-//////////////////////////////////////////////////////////////////
//
-// BreakHandler
+// BreakpointMarker
//
-//////////////////////////////////////////////////////////////////
-namespace Debugger {
-namespace Internal {
+// The red blob on the left side in the cpp editor.
+class BreakpointMarker : public TextEditor::TextMark
+{
+public:
+ BreakpointMarker(BreakpointItem *b, const QString &fileName, int lineNumber)
+ : TextMark(fileName, lineNumber), m_bp(b)
+ {
+ setIcon(b->icon());
+ setPriority(TextEditor::TextMark::NormalPriority);
+ }
+
+ void removedFromEditor()
+ {
+ if (m_bp)
+ m_bp->removeBreakpoint();
+ }
+
+ void updateLineNumber(int lineNumber)
+ {
+ TextMark::updateLineNumber(lineNumber);
+ m_bp->updateLineNumberFromMarker(lineNumber);
+ }
+
+ void updateFileName(const QString &fileName)
+ {
+ TextMark::updateFileName(fileName);
+ m_bp->updateFileNameFromMarker(fileName);
+ }
+
+ bool isDraggable() const { return true; }
+ void dragToLine(int line) { m_bp->changeLineNumberFromMarker(line); }
+ bool isClickable() const { return true; }
+ void clicked() { m_bp->removeBreakpoint(); }
+
+public:
+ BreakpointItem *m_bp;
+};
static QString stateToString(BreakpointState state)
{
@@ -135,14 +243,16 @@ static QString typeToString(BreakpointType type)
BreakHandler::BreakHandler()
: m_syncTimerId(-1)
{
+ qRegisterMetaType<BreakpointModelId>();
+
#if USE_BREAK_MODEL_TEST
new ModelTest(this, 0);
#endif
+ setHeader(QStringList()
+ << tr("Number") << tr("Function") << tr("File") << tr("Line")
+ << tr("Address") << tr("Condition") << tr("Ignore") << tr("Threads"));
}
-BreakHandler::~BreakHandler()
-{}
-
QIcon BreakHandler::breakpointIcon()
{
static QIcon icon(_(":/debugger/images/breakpoint_16.png"));
@@ -183,276 +293,260 @@ QIcon BreakHandler::emptyIcon()
static inline bool fileNameMatch(const QString &f1, const QString &f2)
{
- if (Utils::HostOsInfo::fileNameCaseSensitivity() == Qt::CaseInsensitive)
+ if (HostOsInfo::fileNameCaseSensitivity() == Qt::CaseInsensitive)
return f1.compare(f2, Qt::CaseInsensitive) == 0;
return f1 == f2;
}
-static bool isSimilarTo(const BreakpointParameters &data, const BreakpointResponse &needle)
+static bool isSimilarTo(const BreakpointParameters &params, const BreakpointResponse &needle)
{
// Clear miss.
- if (needle.type != UnknownBreakpointType && data.type != UnknownBreakpointType
- && data.type != needle.type)
+ if (needle.type != UnknownBreakpointType && params.type != UnknownBreakpointType
+ && params.type != needle.type)
return false;
// Clear hit.
- if (data.address && data.address == needle.address)
+ if (params.address && params.address == needle.address)
return true;
// Clear hit.
- if (data == needle)
+ if (params == needle)
return true;
// At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location
- if (!data.fileName.isEmpty()
- && fileNameMatch(data.fileName, needle.fileName)
- && data.lineNumber == needle.lineNumber)
+ if (!params.fileName.isEmpty()
+ && fileNameMatch(params.fileName, needle.fileName)
+ && params.lineNumber == needle.lineNumber)
return true;
// At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location
- if (!data.fileName.isEmpty()
- && fileNameMatch(data.fileName, needle.fileName)
- && data.lineNumber == needle.lineNumber)
+ if (!params.fileName.isEmpty()
+ && fileNameMatch(params.fileName, needle.fileName)
+ && params.lineNumber == needle.lineNumber)
return true;
return false;
}
-BreakpointModelId BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needle) const
+Breakpoint BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needle) const
{
// Search a breakpoint we might refer to.
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it) {
- const BreakpointModelId id = it.key();
- const BreakpointParameters &data = it->data;
- const BreakpointResponse &response = it->response;
- //qDebug() << "COMPARING " << data.toString() << " WITH " << needle.toString();
- if (response.id.isValid() && response.id.majorPart() == needle.id.majorPart())
- return id;
-
- if (isSimilarTo(data, needle))
- return id;
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ //qDebug() << "COMPARING " << params.toString() << " WITH " << needle.toString();
+ if (b->m_response.id.isValid() && b->m_response.id.majorPart() == needle.id.majorPart())
+ return Breakpoint(b);
+
+ if (isSimilarTo(b->m_params, needle))
+ return Breakpoint(b);
}
- return BreakpointModelId();
+ return Breakpoint();
}
-BreakpointModelId BreakHandler::findBreakpointByResponseId(const BreakpointResponseId &id) const
+Breakpoint BreakHandler::findBreakpointByResponseId(const BreakpointResponseId &id) const
{
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it)
- if (it->response.id.majorPart() == id.majorPart())
- return it.key();
- return BreakpointModelId();
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ if (b->m_response.id.majorPart() == id.majorPart())
+ return Breakpoint(b);
+ }
+ return Breakpoint();
}
-BreakpointModelId BreakHandler::findBreakpointByFunction(const QString &functionName) const
+Breakpoint BreakHandler::findBreakpointByFunction(const QString &functionName) const
{
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it)
- if (it->data.functionName == functionName)
- return it.key();
- return BreakpointModelId();
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ if (b->m_params.functionName == functionName)
+ return Breakpoint(b);
+ }
+ return Breakpoint();
}
-BreakpointModelId BreakHandler::findBreakpointByAddress(quint64 address) const
+Breakpoint BreakHandler::findBreakpointByAddress(quint64 address) const
{
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it)
- if (it->data.address == address || it->response.address == address)
- return it.key();
- return BreakpointModelId();
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ if (b->m_params.address == address || b->m_params.address == address)
+ return Breakpoint(b);
+ }
+ return Breakpoint();
}
-BreakpointModelId BreakHandler::findBreakpointByFileAndLine(const QString &fileName,
+Breakpoint BreakHandler::findBreakpointByFileAndLine(const QString &fileName,
int lineNumber, bool useMarkerPosition)
{
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it)
- if (it->isLocatedAt(fileName, lineNumber, useMarkerPosition))
- return it.key();
- return BreakpointModelId();
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ if (b->isLocatedAt(fileName, lineNumber, useMarkerPosition))
+ return Breakpoint(b);
+ }
+ return Breakpoint();
}
-const BreakpointParameters &BreakHandler::breakpointData(BreakpointModelId id) const
+Breakpoint BreakHandler::breakpointById(BreakpointModelId id) const
{
- static BreakpointParameters dummy;
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return dummy);
- return it->data;
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ if (b->m_id == id)
+ return Breakpoint(b);
+ }
+ return Breakpoint();
}
-BreakpointModelId BreakHandler::findWatchpoint(const BreakpointParameters &data) const
+void BreakHandler::deletionHelper(BreakpointModelId id)
{
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it)
- if (it->data.isWatchpoint()
- && it->data.address == data.address
- && it->data.size == data.size
- && it->data.expression == data.expression
- && it->data.bitpos == data.bitpos)
- return it.key();
- return BreakpointModelId();
+ Breakpoint b = breakpointById(id);
+ QTC_ASSERT(b, return);
+ removeItem(b.b);
+ delete b.b;
+}
+
+Breakpoint BreakHandler::findWatchpoint(const BreakpointParameters &params) const
+{
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ if (b->m_params.isWatchpoint()
+ && b->m_params.address == params.address
+ && b->m_params.size == params.size
+ && b->m_params.expression == params.expression
+ && b->m_params.bitpos == params.bitpos)
+ return Breakpoint(b);
+ }
+ return Breakpoint();
}
void BreakHandler::saveBreakpoints()
{
const QString one = _("1");
- //qDebug() << "SAVING BREAKPOINTS...";
QList<QVariant> list;
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it) {
- const BreakpointParameters &data = it->data;
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ const BreakpointParameters &params = b->m_params;
QMap<QString, QVariant> map;
- if (data.type != BreakpointByFileAndLine)
- map.insert(_("type"), data.type);
- if (!data.fileName.isEmpty())
- map.insert(_("filename"), data.fileName);
- if (data.lineNumber)
- map.insert(_("linenumber"), data.lineNumber);
- if (!data.functionName.isEmpty())
- map.insert(_("funcname"), data.functionName);
- if (data.address)
- map.insert(_("address"), data.address);
- if (!data.condition.isEmpty())
- map.insert(_("condition"), data.condition);
- if (data.ignoreCount)
- map.insert(_("ignorecount"), data.ignoreCount);
- if (data.threadSpec >= 0)
- map.insert(_("threadspec"), data.threadSpec);
- if (!data.enabled)
+ if (params.type != BreakpointByFileAndLine)
+ map.insert(_("type"), params.type);
+ if (!params.fileName.isEmpty())
+ map.insert(_("filename"), params.fileName);
+ if (params.lineNumber)
+ map.insert(_("linenumber"), params.lineNumber);
+ if (!params.functionName.isEmpty())
+ map.insert(_("funcname"), params.functionName);
+ if (params.address)
+ map.insert(_("address"), params.address);
+ if (!params.condition.isEmpty())
+ map.insert(_("condition"), params.condition);
+ if (params.ignoreCount)
+ map.insert(_("ignorecount"), params.ignoreCount);
+ if (params.threadSpec >= 0)
+ map.insert(_("threadspec"), params.threadSpec);
+ if (!params.enabled)
map.insert(_("disabled"), one);
- if (data.oneShot)
+ if (params.oneShot)
map.insert(_("oneshot"), one);
- if (data.pathUsage != BreakpointPathUsageEngineDefault)
- map.insert(_("usefullpath"), QString::number(data.pathUsage));
- if (data.tracepoint)
+ if (params.pathUsage != BreakpointPathUsageEngineDefault)
+ map.insert(_("usefullpath"), QString::number(params.pathUsage));
+ if (params.tracepoint)
map.insert(_("tracepoint"), one);
- if (!data.module.isEmpty())
- map.insert(_("module"), data.module);
- if (!data.command.isEmpty())
- map.insert(_("command"), data.command);
- if (!data.expression.isEmpty())
- map.insert(_("expression"), data.expression);
- if (!data.message.isEmpty())
- map.insert(_("message"), data.message);
+ if (!params.module.isEmpty())
+ map.insert(_("module"), params.module);
+ if (!params.command.isEmpty())
+ map.insert(_("command"), params.command);
+ if (!params.expression.isEmpty())
+ map.insert(_("expression"), params.expression);
+ if (!params.message.isEmpty())
+ map.insert(_("message"), params.message);
list.append(map);
}
setSessionValue("Breakpoints", list);
- //qDebug() << "SAVED BREAKPOINTS" << this << list.size();
}
void BreakHandler::loadBreakpoints()
{
- //qDebug() << "LOADING BREAKPOINTS...";
QVariant value = sessionValue("Breakpoints");
QList<QVariant> list = value.toList();
- //clear();
foreach (const QVariant &var, list) {
const QMap<QString, QVariant> map = var.toMap();
- BreakpointParameters data(BreakpointByFileAndLine);
+ BreakpointParameters params(BreakpointByFileAndLine);
QVariant v = map.value(_("filename"));
if (v.isValid())
- data.fileName = v.toString();
+ params.fileName = v.toString();
v = map.value(_("linenumber"));
if (v.isValid())
- data.lineNumber = v.toString().toInt();
+ params.lineNumber = v.toString().toInt();
v = map.value(_("condition"));
if (v.isValid())
- data.condition = v.toString().toLatin1();
+ params.condition = v.toString().toLatin1();
v = map.value(_("address"));
if (v.isValid())
- data.address = v.toString().toULongLong();
+ params.address = v.toString().toULongLong();
v = map.value(_("ignorecount"));
if (v.isValid())
- data.ignoreCount = v.toString().toInt();
+ params.ignoreCount = v.toString().toInt();
v = map.value(_("threadspec"));
if (v.isValid())
- data.threadSpec = v.toString().toInt();
+ params.threadSpec = v.toString().toInt();
v = map.value(_("funcname"));
if (v.isValid())
- data.functionName = v.toString();
+ params.functionName = v.toString();
v = map.value(_("disabled"));
if (v.isValid())
- data.enabled = !v.toInt();
+ params.enabled = !v.toInt();
v = map.value(_("oneshot"));
if (v.isValid())
- data.oneShot = v.toInt();
+ params.oneShot = v.toInt();
v = map.value(_("usefullpath"));
if (v.isValid())
- data.pathUsage = static_cast<BreakpointPathUsage>(v.toInt());
+ params.pathUsage = static_cast<BreakpointPathUsage>(v.toInt());
v = map.value(_("tracepoint"));
if (v.isValid())
- data.tracepoint = bool(v.toInt());
+ params.tracepoint = bool(v.toInt());
v = map.value(_("type"));
if (v.isValid() && v.toInt() != UnknownBreakpointType)
- data.type = BreakpointType(v.toInt());
+ params.type = BreakpointType(v.toInt());
v = map.value(_("module"));
if (v.isValid())
- data.module = v.toString();
+ params.module = v.toString();
v = map.value(_("command"));
if (v.isValid())
- data.command = v.toString();
+ params.command = v.toString();
v = map.value(_("expression"));
if (v.isValid())
- data.expression = v.toString();
+ params.expression = v.toString();
v = map.value(_("message"));
if (v.isValid())
- data.message = v.toString();
- if (data.isValid())
- appendBreakpoint(data);
+ params.message = v.toString();
+ if (params.isValid())
+ appendBreakpointInternal(params);
else
- qWarning("Not restoring invalid breakpoint: %s", qPrintable(data.toString()));
+ qWarning("Not restoring invalid breakpoint: %s", qPrintable(params.toString()));
}
- //qDebug() << "LOADED BREAKPOINTS" << this << list.size();
}
void BreakHandler::updateMarkers()
{
- Iterator it = m_storage.begin(), et = m_storage.end();
- for ( ; it != et; ++it)
- it->updateMarker(it.key());
-}
-
-QVariant BreakHandler::headerData(int section,
- Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
- static QString headers[] = {
- tr("Number"), tr("Function"), tr("File"), tr("Line"),
- tr("Address"), tr("Condition"), tr("Ignore"), tr("Threads")
- };
- return headers[section];
- }
- return QVariant();
+ foreach (TreeItem *n, rootItem()->children())
+ static_cast<BreakpointItem *>(n)->updateMarker();
}
-BreakpointModelId BreakHandler::findBreakpointByIndex(const QModelIndex &index) const
+Breakpoint BreakHandler::findBreakpointByIndex(const QModelIndex &index) const
{
- //qDebug() << "FIND: " << index <<
- // BreakpointId::fromInternalId(index.internalId());
- return BreakpointModelId::fromInternalId(index.internalId());
+ TreeItem *item = itemFromIndex(index);
+ return Breakpoint(item && item->parent() == rootItem() ? static_cast<BreakpointItem *>(item) : 0);
}
-BreakpointModelIds BreakHandler::findBreakpointsByIndex(const QList<QModelIndex> &list) const
+Breakpoints BreakHandler::findBreakpointsByIndex(const QList<QModelIndex> &list) const
{
- QSet<BreakpointModelId> ids;
- foreach (const QModelIndex &index, list)
- ids.insert(findBreakpointByIndex(index));
+ QSet<Breakpoint> ids;
+ foreach (const QModelIndex &index, list) {
+ if (Breakpoint b = findBreakpointByIndex(index))
+ ids.insert(Breakpoint(b));
+ }
return ids.toList();
}
-Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const
-{
-// switch (index.column()) {
-// //case 0:
-// // return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
-// default:
- return QAbstractItemModel::flags(index);
-// }
-}
-
QString BreakHandler::displayFromThreadSpec(int spec)
{
return spec == -1 ? BreakHandler::tr("(all)") : QString::number(spec);
@@ -465,95 +559,12 @@ int BreakHandler::threadSpecFromDisplay(const QString &str)
return ok ? result : -1;
}
-QModelIndex BreakHandler::createIndex(int row, int column, quint32 id) const
-{
- return QAbstractItemModel::createIndex(row, column, id);
-}
-
-QModelIndex BreakHandler::createIndex(int row, int column, void *ptr) const
-{
- QTC_CHECK(false); // This function is not used.
- return QAbstractItemModel::createIndex(row, column, ptr);
-}
+const QString empty(QLatin1Char('-'));
-int BreakHandler::columnCount(const QModelIndex &idx) const
+QVariant BreakpointItem::data(int column, int role) const
{
- if (idx.column() > 0)
- return 0;
- const BreakpointModelId id = findBreakpointByIndex(idx);
- return id.isMinor() ? 0 : 8;
-}
-
-int BreakHandler::rowCount(const QModelIndex &idx) const
-{
- if (idx.column() > 0)
- return 0;
- if (!idx.isValid())
- return m_storage.size();
- const BreakpointModelId id = findBreakpointByIndex(idx);
- if (id.isMajor())
- return m_storage.value(id).subItems.size();
- return 0;
-}
-
-QModelIndex BreakHandler::index(int row, int col, const QModelIndex &parent) const
-{
- if (row < 0 || col < 0)
- return QModelIndex();
- if (parent.column() > 0)
- return QModelIndex();
- BreakpointModelId id = findBreakpointByIndex(parent);
- if (id.isMajor()) {
- ConstIterator it = m_storage.find(id);
- if (row >= it->subItems.size())
- return QModelIndex();
- BreakpointModelId sub = id.child(row);
- return createIndex(row, col, sub.toInternalId());
- }
- if (id.isMinor())
- return QModelIndex();
- QTC_ASSERT(!id.isValid(), return QModelIndex());
- if (row >= m_storage.size())
- return QModelIndex();
- id = at(row);
- return createIndex(row, col, id.toInternalId());
-}
-
-QModelIndex BreakHandler::parent(const QModelIndex &idx) const
-{
- if (!idx.isValid())
- return QModelIndex();
- BreakpointModelId id = findBreakpointByIndex(idx);
- if (id.isMajor())
- return QModelIndex();
- if (id.isMinor()) {
- BreakpointModelId pid = id.parent();
- int row = indexOf(pid);
- return createIndex(row, 0, pid.toInternalId());
- }
- return QModelIndex();
-}
-
-QVariant BreakHandler::data(const QModelIndex &mi, int role) const
-{
- static const QString empty = QString(QLatin1Char('-'));
-
- if (!mi.isValid())
- return QVariant();
-
- BreakpointModelId id = findBreakpointByIndex(mi);
-
- BreakpointModelId pid = id;
- if (id.isMinor())
- pid = id.parent();
-
- ConstIterator it = m_storage.find(pid);
- QTC_ASSERT(it != m_storage.end(), return QVariant());
- const BreakpointParameters &data = it->data;
- const BreakpointResponse &response = it->response;
-
bool orig = false;
- switch (it->state) {
+ switch (m_state) {
case BreakpointInsertRequested:
case BreakpointInsertProceeding:
case BreakpointChangeRequested:
@@ -568,53 +579,52 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
break;
};
- if (id.isMinor()) {
- QTC_ASSERT(id.minorPart() <= it->subItems.size(), return QVariant());
- const BreakpointResponse &res = it->subItems.at(id.minorPart() - 1);
- switch (mi.column()) {
- case 0:
- if (role == Qt::DisplayRole)
- return id.toString();
- case 1:
- if (role == Qt::DisplayRole)
- return res.functionName;
- case 4:
- if (role == Qt::DisplayRole)
- if (res.address)
- return QString::fromLatin1("0x%1").arg(res.address, 0, 16);
- }
- return QVariant();
+ if (role == Qt::ForegroundRole) {
+ static const QVariant gray(QColor(140, 140, 140));
+ switch (m_state) {
+ case BreakpointInsertRequested:
+ case BreakpointInsertProceeding:
+ case BreakpointChangeRequested:
+ case BreakpointChangeProceeding:
+ case BreakpointRemoveRequested:
+ case BreakpointRemoveProceeding:
+ return gray;
+ case BreakpointInserted:
+ case BreakpointNew:
+ case BreakpointDead:
+ break;
+ };
}
- switch (mi.column()) {
+ switch (column) {
case 0:
if (role == Qt::DisplayRole)
- return id.toString();
+ return m_id.toString();
if (role == Qt::DecorationRole)
- return it->icon();
+ return icon();
break;
case 1:
if (role == Qt::DisplayRole) {
- if (!response.functionName.isEmpty())
- return simplifyType(response.functionName);
- if (!data.functionName.isEmpty())
- return data.functionName;
- if (data.type == BreakpointAtMain
- || data.type == BreakpointAtThrow
- || data.type == BreakpointAtCatch
- || data.type == BreakpointAtFork
- || data.type == BreakpointAtExec
- //|| data.type == BreakpointAtVFork
- || data.type == BreakpointAtSysCall)
- return typeToString(data.type);
- if (data.type == WatchpointAtAddress) {
- quint64 address = response.address ? response.address : data.address;
- return tr("Data at 0x%1").arg(address, 0, 16);
+ if (!m_response.functionName.isEmpty())
+ return simplifyType(m_response.functionName);
+ if (!m_params.functionName.isEmpty())
+ return m_params.functionName;
+ if (m_params.type == BreakpointAtMain
+ || m_params.type == BreakpointAtThrow
+ || m_params.type == BreakpointAtCatch
+ || m_params.type == BreakpointAtFork
+ || m_params.type == BreakpointAtExec
+ //|| m_params.type == BreakpointAtVFork
+ || m_params.type == BreakpointAtSysCall)
+ return typeToString(m_params.type);
+ if (m_params.type == WatchpointAtAddress) {
+ quint64 address = m_response.address ? m_response.address : m_params.address;
+ return BreakHandler::tr("Data at 0x%1").arg(address, 0, 16);
}
- if (data.type == WatchpointAtExpression) {
- QString expression = !response.expression.isEmpty()
- ? response.expression : data.expression;
- return tr("Data at %1").arg(expression);
+ if (m_params.type == WatchpointAtExpression) {
+ QString expression = !m_response.expression.isEmpty()
+ ? m_response.expression : m_params.expression;
+ return BreakHandler::tr("Data at %1").arg(expression);
}
return empty;
}
@@ -622,17 +632,17 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
case 2:
if (role == Qt::DisplayRole) {
QString str;
- if (!response.fileName.isEmpty())
- str = response.fileName;
- if (str.isEmpty() && !data.fileName.isEmpty())
- str = data.fileName;
+ if (!m_response.fileName.isEmpty())
+ str = m_response.fileName;
+ if (str.isEmpty() && !m_params.fileName.isEmpty())
+ str = m_params.fileName;
if (str.isEmpty()) {
- QString s = QFileInfo(str).fileName();
+ QString s = FileName::fromString(str).fileName();
if (!s.isEmpty())
str = s;
}
// FIXME: better?
- //if (data.multiple && str.isEmpty() && !response.fileName.isEmpty())
+ //if (params.multiple && str.isEmpty() && !response.fileName.isEmpty())
// str = response.fileName;
if (!str.isEmpty())
return QDir::toNativeSeparators(str);
@@ -641,18 +651,18 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
break;
case 3:
if (role == Qt::DisplayRole) {
- if (response.lineNumber > 0)
- return response.lineNumber;
- if (data.lineNumber > 0)
- return data.lineNumber;
+ if (m_response.lineNumber > 0)
+ return m_response.lineNumber;
+ if (m_params.lineNumber > 0)
+ return m_params.lineNumber;
return empty;
}
if (role == Qt::UserRole + 1)
- return data.lineNumber;
+ return m_params.lineNumber;
break;
case 4:
if (role == Qt::DisplayRole) {
- const quint64 address = orig ? data.address : response.address;
+ const quint64 address = orig ? m_params.address : m_response.address;
if (address)
return QString::fromLatin1("0x%1").arg(address, 0, 16);
return QVariant();
@@ -660,196 +670,204 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
break;
case 5:
if (role == Qt::DisplayRole)
- return orig ? data.condition : response.condition;
+ return orig ? m_params.condition : m_response.condition;
if (role == Qt::ToolTipRole)
- return tr("Breakpoint will only be hit if this condition is met.");
+ return BreakHandler::tr("Breakpoint will only be hit if this condition is met.");
if (role == Qt::UserRole + 1)
- return data.condition;
+ return m_params.condition;
break;
case 6:
if (role == Qt::DisplayRole) {
const int ignoreCount =
- orig ? data.ignoreCount : response.ignoreCount;
+ orig ? m_params.ignoreCount : m_response.ignoreCount;
return ignoreCount ? QVariant(ignoreCount) : QVariant(QString());
}
if (role == Qt::ToolTipRole)
- return tr("Breakpoint will only be hit after being ignored so many times.");
+ return BreakHandler::tr("Breakpoint will only be hit after being ignored so many times.");
if (role == Qt::UserRole + 1)
- return data.ignoreCount;
+ return m_params.ignoreCount;
break;
case 7:
if (role == Qt::DisplayRole)
- return displayFromThreadSpec(orig ? data.threadSpec : response.threadSpec);
+ return BreakHandler::displayFromThreadSpec(orig ? m_params.threadSpec : m_response.threadSpec);
if (role == Qt::ToolTipRole)
- return tr("Breakpoint will only be hit in the specified thread(s).");
+ return BreakHandler::tr("Breakpoint will only be hit in the specified thread(s).");
if (role == Qt::UserRole + 1)
- return displayFromThreadSpec(data.threadSpec);
+ return BreakHandler::displayFromThreadSpec(m_params.threadSpec);
break;
}
- switch (role) {
- case Qt::ToolTipRole:
- if (boolSetting(UseToolTipsInBreakpointsView))
- return QVariant(it->toToolTip());
- break;
- }
+
+ if (role == Qt::ToolTipRole && boolSetting(UseToolTipsInBreakpointsView))
+ return toToolTip();
+
return QVariant();
}
-#define GETTER(type, getter) \
-type BreakHandler::getter(BreakpointModelId id) const \
+#define PROPERTY(type, getter, setter) \
+\
+type Breakpoint::getter() const \
{ \
- ConstIterator it = m_storage.find(id); \
- BREAK_ASSERT(it != m_storage.end(), \
- qDebug() << "ID" << id << "NOT KNOWN"; \
- return type()); \
- return it->data.getter; \
-}
-
-#define SETTER(type, getter, setter) \
-void BreakHandler::setter(BreakpointModelId id, const type &value) \
+ return parameters().getter; \
+} \
+\
+void Breakpoint::setter(const type &value) \
{ \
- Iterator it = m_storage.find(id); \
- BREAK_ASSERT(it != m_storage.end(), \
- qDebug() << "ID" << id << "NOT KNOWN"; return); \
- if (it->data.getter == value) \
+ QTC_ASSERT(b, return); \
+ if (b->m_params.getter == value) \
return; \
- it->data.getter = value; \
- if (it->state != BreakpointNew) { \
- it->state = BreakpointChangeRequested; \
- scheduleSynchronization(); \
+ b->m_params.getter = value; \
+ if (b->m_state != BreakpointNew) { \
+ b->m_state = BreakpointChangeRequested; \
+ b->scheduleSynchronization(); \
} \
}
-#define PROPERTY(type, getter, setter) \
- GETTER(type, getter) \
- SETTER(type, getter, setter)
-
-
PROPERTY(BreakpointPathUsage, pathUsage, setPathUsage)
PROPERTY(QString, fileName, setFileName)
PROPERTY(QString, functionName, setFunctionName)
PROPERTY(BreakpointType, type, setType)
PROPERTY(int, threadSpec, setThreadSpec)
PROPERTY(QByteArray, condition, setCondition)
-GETTER(int, lineNumber)
PROPERTY(quint64, address, setAddress)
PROPERTY(QString, expression, setExpression)
PROPERTY(QString, message, setMessage)
PROPERTY(int, ignoreCount, setIgnoreCount)
-bool BreakHandler::isEnabled(BreakpointModelId id) const
+void BreakpointItem::scheduleSynchronization()
{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return false);
- return it->data.enabled;
+ m_handler->scheduleSynchronization();
}
-void BreakHandler::setEnabled(BreakpointModelId id, bool on)
+const BreakpointParameters &Breakpoint::parameters() const
{
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- //qDebug() << "SET ENABLED: " << id << it->data.isEnabled() << on;
- if (it->data.enabled == on)
- return;
- it->data.enabled = on;
- it->updateMarkerIcon();
- if (it->engine) {
- it->state = BreakpointChangeRequested;
- scheduleSynchronization();
- }
+ static BreakpointParameters p;
+ QTC_ASSERT(b, return p);
+ return b->m_params;
+}
+
+void Breakpoint::addToCommand(DebuggerCommand *cmd) const
+{
+ cmd->arg("modelid", id().toByteArray());
+ cmd->arg("type", type());
+ cmd->arg("ignorecount", ignoreCount());
+ cmd->arg("condition", condition().toHex());
+ cmd->arg("function", functionName().toUtf8());
+ cmd->arg("oneshot", isOneShot());
+ cmd->arg("enabled", isEnabled());
+ cmd->arg("fileName", fileName().toUtf8());
+ cmd->arg("lineNumber", lineNumber());
+ cmd->arg("address", address());
+ cmd->arg("expression", expression());
+}
+
+BreakpointState Breakpoint::state() const
+{
+ QTC_ASSERT(b, return BreakpointState());
+ return b->m_state;
}
-bool BreakHandler::isWatchpoint(BreakpointModelId id) const
+int Breakpoint::lineNumber() const { return parameters().lineNumber; }
+
+bool Breakpoint::isEnabled() const { return parameters().enabled; }
+
+bool Breakpoint::isWatchpoint() const { return parameters().isWatchpoint(); }
+
+bool Breakpoint::isTracepoint() const { return parameters().isTracepoint(); }
+
+QIcon Breakpoint::icon() const { return b ? b->icon() : QIcon(); }
+
+DebuggerEngine *Breakpoint::engine() const
{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return false);
- return it->data.isWatchpoint();
+ return b ? b->m_engine : 0;
}
-bool BreakHandler::isTracepoint(BreakpointModelId id) const
+const BreakpointResponse &Breakpoint::response() const
{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return false);
- return it->data.tracepoint;
+ static BreakpointResponse r;
+ return b ? b->m_response : r;
}
-bool BreakHandler::isOneShot(BreakpointModelId id) const
+bool Breakpoint::isOneShot() const { return parameters().oneShot; }
+
+void Breakpoint::removeAlienBreakpoint()
{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return false);
- return it->data.oneShot;
+ b->deleteThis();
}
-bool BreakHandler::needsChildren(BreakpointModelId id) const
+void Breakpoint::removeBreakpoint() const
{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return false);
- return it->response.multiple && it->subItems.isEmpty();
+ b->removeBreakpoint();
}
-void BreakHandler::setTracepoint(BreakpointModelId id, bool on)
+Breakpoint::Breakpoint(BreakpointItem *b)
+ : b(b)
+{}
+
+void Breakpoint::setEnabled(bool on) const
{
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- if (it->data.tracepoint == on)
+ QTC_ASSERT(b, return);
+ if (b->m_params.enabled == on)
return;
- it->data.tracepoint = on;
- it->updateMarkerIcon();
-
- if (it->engine) {
- it->state = BreakpointChangeRequested;
- scheduleSynchronization();
+ b->m_params.enabled = on;
+ b->updateMarkerIcon();
+ if (b->m_engine) {
+ b->m_state = BreakpointChangeRequested;
+ b->scheduleSynchronization();
}
}
-void BreakHandler::setMarkerFileAndLine(BreakpointModelId id,
- const QString &fileName, int lineNumber)
+void Breakpoint::setMarkerFileAndLine(const QString &fileName, int lineNumber)
{
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(),
- qDebug() << "MARKER_FILE_AND_LINE: " << id; return);
- if (it->response.fileName == fileName && it->response.lineNumber == lineNumber)
- return;
- it->response.fileName = fileName;
- it->response.lineNumber = lineNumber;
- it->destroyMarker();
- it->updateMarker(id);
- emit layoutChanged();
+ if (b)
+ b->setMarkerFileAndLine(fileName, lineNumber);
}
-BreakpointState BreakHandler::state(BreakpointModelId id) const
+bool BreakpointItem::needsChildren() const
{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(),
- qDebug() << "STATE: " << id; return BreakpointDead);
- return it->state;
+ return m_response.multiple && rowCount() == 0;
}
-DebuggerEngine *BreakHandler::engine(BreakpointModelId id) const
+void Breakpoint::setTracepoint(bool on)
{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), qDebug() << id; return 0);
- return it->engine;
+ if (b->m_params.tracepoint == on)
+ return;
+ b->m_params.tracepoint = on;
+ b->updateMarkerIcon();
+
+ if (b->m_engine) {
+ b->m_state = BreakpointChangeRequested;
+ b->scheduleSynchronization();
+ }
}
-void BreakHandler::setEngine(BreakpointModelId id, DebuggerEngine *value)
+void BreakpointItem::setMarkerFileAndLine(const QString &fileName, int lineNumber)
{
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), qDebug() << "SET ENGINE" << id; return);
- QTC_ASSERT(it->state == BreakpointNew, qDebug() << "STATE: " << it->state <<id);
- QTC_ASSERT(!it->engine, qDebug() << "NO ENGINE" << id; return);
- it->engine = value;
- it->state = BreakpointInsertRequested;
- it->response = BreakpointResponse();
- it->updateMarker(id);
- scheduleSynchronization();
+ if (m_response.fileName == fileName && m_response.lineNumber == lineNumber)
+ return;
+ m_response.fileName = fileName;
+ m_response.lineNumber = lineNumber;
+ destroyMarker();
+ updateMarker();
+ update();
+}
+
+void Breakpoint::setEngine(DebuggerEngine *value)
+{
+ QTC_ASSERT(b->m_state == BreakpointNew, qDebug() << "STATE: " << b->m_state << b->m_id);
+ QTC_ASSERT(!b->m_engine, qDebug() << "NO ENGINE" << b->m_id; return);
+ b->m_engine = value;
+ b->m_state = BreakpointInsertRequested;
+ b->m_response = BreakpointResponse();
+ b->updateMarker();
+ //b->scheduleSynchronization();
}
static bool isAllowedTransition(BreakpointState from, BreakpointState to)
{
switch (from) {
case BreakpointNew:
- return to == BreakpointInsertRequested;
+ return to == BreakpointInsertRequested
+ || to == BreakpointDead;
case BreakpointInsertRequested:
return to == BreakpointInsertProceeding;
case BreakpointInsertProceeding:
@@ -876,287 +894,234 @@ static bool isAllowedTransition(BreakpointState from, BreakpointState to)
return false;
}
-bool BreakHandler::isEngineRunning(BreakpointModelId id) const
+bool BreakpointItem::isEngineRunning() const
{
- if (const DebuggerEngine *e = engine(id)) {
- const DebuggerState state = e->state();
- return state != DebuggerFinished && state != DebuggerNotReady;
- }
- return false;
+ if (!m_engine)
+ return false;
+ const DebuggerState state = m_engine->state();
+ return state != DebuggerFinished && state != DebuggerNotReady;
}
-void BreakHandler::setState(BreakpointModelId id, BreakpointState state)
+void BreakpointItem::setState(BreakpointState state)
{
- Iterator it = m_storage.find(id);
- //qDebug() << "BREAKPOINT STATE TRANSITION, ID: " << id
- // << " FROM: " << it->state << " TO: " << state;
- BREAK_ASSERT(it != m_storage.end(), qDebug() << id; return);
- QTC_ASSERT(isAllowedTransition(it->state, state),
- qDebug() << "UNEXPECTED BREAKPOINT STATE TRANSITION"
- << it->state << state);
+ //qDebug() << "BREAKPOINT STATE TRANSITION, ID: " << m_id
+ // << " FROM: " << state << " TO: " << state;
+ if (!isAllowedTransition(m_state, state)) {
+ qDebug() << "UNEXPECTED BREAKPOINT STATE TRANSITION" << m_state << state;
+ QTC_CHECK(false);
+ }
- if (it->state == state) {
- qDebug() << "STATE UNCHANGED: " << id << state;
+ if (m_state == state) {
+ qDebug() << "STATE UNCHANGED: " << m_id << m_state;
return;
}
- it->state = state;
+ m_state = state;
// FIXME: updateMarker() should recognize the need for icon changes.
if (state == BreakpointInserted) {
- it->destroyMarker();
- it->updateMarker(id);
+ destroyMarker();
+ updateMarker();
}
- layoutChanged();
+ update();
+}
+
+void BreakpointItem::deleteThis()
+{
+ setState(BreakpointDead);
+ destroyMarker();
+
+ // This is called from b directly. So delay deletion of b.
+ ExtensionSystem::InvokerBase invoker;
+ invoker.addArgument(m_id);
+ invoker.setConnectionType(Qt::QueuedConnection);
+ invoker.invoke(m_handler, "deletionHelper");
+ QTC_CHECK(invoker.wasSuccessful());
}
-void BreakHandler::notifyBreakpointChangeAfterInsertNeeded(BreakpointModelId id)
+void Breakpoint::gotoState(BreakpointState target, BreakpointState assumedCurrent)
{
- QTC_ASSERT(state(id) == BreakpointInsertProceeding, qDebug() << state(id));
- setState(id, BreakpointChangeRequested);
+ QTC_ASSERT(b, return);
+ QTC_ASSERT(b->m_state == assumedCurrent, qDebug() << b->m_state);
+ b->setState(target);
}
-void BreakHandler::notifyBreakpointInsertProceeding(BreakpointModelId id)
+void Breakpoint::notifyBreakpointChangeAfterInsertNeeded()
{
- QTC_ASSERT(state(id) == BreakpointInsertRequested, qDebug() << state(id));
- setState(id, BreakpointInsertProceeding);
+ gotoState(BreakpointChangeRequested, BreakpointInsertProceeding);
}
-void BreakHandler::notifyBreakpointInsertOk(BreakpointModelId id)
+void Breakpoint::notifyBreakpointInsertProceeding()
{
- QTC_ASSERT(state(id) == BreakpointInsertProceeding, qDebug() << state(id));
- setState(id, BreakpointInserted);
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
+ gotoState(BreakpointInsertProceeding, BreakpointInsertRequested);
}
-void BreakHandler::notifyBreakpointInsertFailed(BreakpointModelId id)
+void Breakpoint::notifyBreakpointInsertOk()
{
- QTC_ASSERT(state(id) == BreakpointInsertProceeding, qDebug() << state(id));
- setState(id, BreakpointDead);
+ gotoState(BreakpointInserted, BreakpointInsertProceeding);
}
-void BreakHandler::notifyBreakpointRemoveProceeding(BreakpointModelId id)
+void Breakpoint::notifyBreakpointInsertFailed()
{
- QTC_ASSERT(state(id) == BreakpointRemoveRequested, qDebug() << state(id));
- setState(id, BreakpointRemoveProceeding);
+ gotoState(BreakpointDead, BreakpointInsertProceeding);
}
-void BreakHandler::notifyBreakpointRemoveOk(BreakpointModelId id)
+void Breakpoint::notifyBreakpointRemoveProceeding()
{
- QTC_ASSERT(state(id) == BreakpointRemoveProceeding, qDebug() << state(id));
- setState(id, BreakpointDead);
- cleanupBreakpoint(id);
+ gotoState(BreakpointRemoveProceeding, BreakpointRemoveRequested);
}
-void BreakHandler::notifyBreakpointRemoveFailed(BreakpointModelId id)
+void Breakpoint::notifyBreakpointRemoveOk()
{
- QTC_ASSERT(state(id) == BreakpointRemoveProceeding, qDebug() << state(id));
- setState(id, BreakpointDead);
- cleanupBreakpoint(id);
+ QTC_ASSERT(b, return);
+ QTC_ASSERT(b->m_state == BreakpointRemoveProceeding, qDebug() << b->m_state);
+ b->deleteThis();
}
-void BreakHandler::notifyBreakpointChangeProceeding(BreakpointModelId id)
+void Breakpoint::notifyBreakpointRemoveFailed()
{
- QTC_ASSERT(state(id) == BreakpointChangeRequested, qDebug() << state(id));
- setState(id, BreakpointChangeProceeding);
+ QTC_ASSERT(b, return);
+ QTC_ASSERT(b->m_state == BreakpointRemoveProceeding, qDebug() << b->m_state);
+ b->deleteThis();
}
-void BreakHandler::notifyBreakpointChangeOk(BreakpointModelId id)
+void Breakpoint::notifyBreakpointChangeProceeding()
{
- QTC_ASSERT(state(id) == BreakpointChangeProceeding, qDebug() << state(id));
- setState(id, BreakpointInserted);
+ gotoState(BreakpointChangeProceeding, BreakpointChangeRequested);
}
-void BreakHandler::notifyBreakpointChangeFailed(BreakpointModelId id)
+void Breakpoint::notifyBreakpointChangeOk()
{
- QTC_ASSERT(state(id) == BreakpointChangeProceeding, qDebug() << state(id));
- setState(id, BreakpointDead);
+ gotoState(BreakpointInserted, BreakpointChangeProceeding);
}
-void BreakHandler::notifyBreakpointReleased(BreakpointModelId id)
+void Breakpoint::notifyBreakpointChangeFailed()
{
- //QTC_ASSERT(state(id) == BreakpointChangeProceeding, qDebug() << state(id));
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- it->state = BreakpointNew;
- it->engine = 0;
- it->response = BreakpointResponse();
- it->subItems.clear();
- it->destroyMarker();
- it->updateMarker(id);
- if (it->data.type == WatchpointAtAddress
- || it->data.type == WatchpointAtExpression
- || it->data.type == BreakpointByAddress)
- it->data.enabled = false;
- else
- it->data.address = 0;
- layoutChanged();
+ gotoState(BreakpointDead, BreakpointChangeProceeding);
}
-void BreakHandler::notifyBreakpointAdjusted(BreakpointModelId id,
- const BreakpointParameters &data)
+void Breakpoint::notifyBreakpointReleased()
{
- QTC_ASSERT(state(id) == BreakpointInserted, qDebug() << state(id));
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- it->data = data;
- //if (it->needsChange())
- // setState(id, BreakpointChangeRequested);
+ QTC_ASSERT(b, return);
+ b->removeChildren();
+ //QTC_ASSERT(b->m_state == BreakpointChangeProceeding, qDebug() << b->m_state);
+ b->m_state = BreakpointNew;
+ b->m_engine = 0;
+ b->m_response = BreakpointResponse();
+ b->destroyMarker();
+ b->updateMarker();
+ if (b->m_params.type == WatchpointAtAddress
+ || b->m_params.type == WatchpointAtExpression
+ || b->m_params.type == BreakpointByAddress)
+ b->m_params.enabled = false;
+ else
+ b->m_params.address = 0;
+ b->update();
}
-void BreakHandler::notifyBreakpointNeedsReinsertion(BreakpointModelId id)
+void Breakpoint::notifyBreakpointAdjusted(const BreakpointParameters &params)
{
- QTC_ASSERT(state(id) == BreakpointChangeProceeding, qDebug() << state(id));
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- it->state = BreakpointInsertRequested;
+ QTC_ASSERT(b, return);
+ QTC_ASSERT(b->m_state == BreakpointInserted, qDebug() << b->m_state);
+ b->m_params = params;
+ //if (b->needsChange())
+ // b->setState(BreakpointChangeRequested);
}
-void BreakHandler::removeAlienBreakpoint(BreakpointModelId id)
+void Breakpoint::notifyBreakpointNeedsReinsertion()
{
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- it->state = BreakpointDead;
- cleanupBreakpoint(id);
+ QTC_ASSERT(b, return);
+ QTC_ASSERT(b->m_state == BreakpointChangeProceeding, qDebug() << b->m_state);
+ b->m_state = BreakpointInsertRequested;
}
-void BreakHandler::removeBreakpoint(BreakpointModelId id)
+void BreakpointItem::removeBreakpoint()
{
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- switch (it->state) {
+ switch (m_state) {
case BreakpointRemoveRequested:
break;
case BreakpointInserted:
case BreakpointInsertProceeding:
- setState(id, BreakpointRemoveRequested);
+ setState(BreakpointRemoveRequested);
scheduleSynchronization();
break;
case BreakpointNew:
- it->state = BreakpointDead;
- cleanupBreakpoint(id);
+ deleteThis();
break;
default:
qWarning("Warning: Cannot remove breakpoint %s in state '%s'.",
- qPrintable(id.toString()), qPrintable(stateToString(it->state)));
- it->state = BreakpointRemoveRequested;
+ qPrintable(m_id.toString()), qPrintable(stateToString(m_state)));
+ m_state = BreakpointRemoveRequested;
break;
}
}
-// Ok to be not thread-safe. The order does not matter and only the gui
-// produces authoritative ids.
-static int currentId = 0;
+void BreakHandler::appendBreakpoint(const BreakpointParameters &params)
+{
+ appendBreakpointInternal(params);
+ scheduleSynchronization();
+}
-void BreakHandler::appendBreakpoint(const BreakpointParameters &data)
+void BreakHandler::appendBreakpointInternal(const BreakpointParameters &params)
{
- if (!data.isValid()) {
- qWarning("Not adding invalid breakpoint: %s", qPrintable(data.toString()));
+ if (!params.isValid()) {
+ qWarning("Not adding invalid breakpoint: %s", qPrintable(params.toString()));
return;
}
- BreakpointModelId id(++currentId);
- const int row = m_storage.size();
- beginInsertRows(QModelIndex(), row, row);
- Iterator it = m_storage.insert(id, BreakpointItem());
- endInsertRows();
-
- // Create marker after copy is inserted into hash.
- it->data = data;
- it->updateMarker(id);
-
- scheduleSynchronization();
+ BreakpointItem *b = new BreakpointItem(this);
+ b->m_params = params;
+ b->updateMarker();
+ rootItem()->appendChild(b);
}
void BreakHandler::handleAlienBreakpoint(const BreakpointResponse &response, DebuggerEngine *engine)
{
- BreakpointModelId id = findSimilarBreakpoint(response);
- if (id.isValid()) {
+ Breakpoint b = findSimilarBreakpoint(response);
+ if (b) {
if (response.id.isMinor())
- insertSubBreakpoint(id, response);
+ b.insertSubBreakpoint(response);
else
- setResponse(id, response);
+ b.setResponse(response);
} else {
- id = BreakpointModelId(++currentId);
- const int row = m_storage.size();
-
- beginInsertRows(QModelIndex(), row, row);
- Iterator it = m_storage.insert(id, BreakpointItem());
- endInsertRows();
-
- it->data = response;
- it->response = response;
- it->state = BreakpointInserted;
- it->engine = engine;
- it->updateMarker(id);
-
- layoutChanged();
- scheduleSynchronization();
+ auto b = new BreakpointItem(this);
+ b->m_params = response;
+ b->m_response = response;
+ b->m_state = BreakpointInserted;
+ b->m_engine = engine;
+ b->updateMarker();
+ rootItem()->appendChild(b);
}
}
-BreakpointModelId BreakHandler::at(int n) const
+void Breakpoint::insertSubBreakpoint(const BreakpointResponse &params)
{
- if (n < 0 || n >= m_storage.size())
- return BreakpointModelId();
- ConstIterator it = m_storage.constBegin();
- for ( ; --n >= 0; ++it)
- ;
- return it.key();
+ QTC_ASSERT(b, return);
+ b->insertSubBreakpoint(params);
}
-int BreakHandler::indexOf(BreakpointModelId id) const
+void BreakpointItem::insertSubBreakpoint(const BreakpointResponse &params)
{
- int row = 0;
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it, ++row)
- if (it.key() == id)
- return row;
- return -1;
-}
+ QTC_ASSERT(params.id.isMinor(), return);
-void BreakHandler::insertSubBreakpoint(BreakpointModelId id,
- const BreakpointResponse &data)
-{
- QTC_ASSERT(data.id.isMinor(), return);
- QTC_ASSERT(id.isMajor(), return);
- Iterator it = m_storage.find(id);
+ int minorPart = params.id.minorPart();
- if (it == m_storage.end()) {
- qDebug() << "FAILED: " << id.toString();
- for (ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- it != et; ++it) {
- qDebug() << " ID: " << it->response.id.toString();
- qDebug() << " DATA: " << it->data.toString();
- qDebug() << " RESP: " << it->response.toString();
+ const QVector<TreeItem *> &children = TreeItem::children();
+ foreach (TreeItem *n, children) {
+ LocationItem *l = static_cast<LocationItem *>(n);
+ if (l->params.id.minorPart() == minorPart) {
+ // This modifies an existing sub-breakpoint.
+ l->params = params;
+ l->update();
+ return;
}
}
- QTC_ASSERT(it != m_storage.end(), return);
- int minorPart = data.id.minorPart();
- int pos = -1;
- for (int i = 0; i != it->subItems.size(); ++i) {
- if (it->subItems.at(i).id.minorPart() == minorPart) {
- pos = i;
- break;
- }
- }
- if (pos == -1) {
- // This is a new sub-breakpoint.
- //qDebug() << "NEW ID" << id;
- int row = indexOf(id);
- QTC_ASSERT(row != -1, return);
- QModelIndex idx = createIndex(row, 0, id.toInternalId());
- beginInsertRows(idx, it->subItems.size(), it->subItems.size());
- it->subItems.append(data);
- endInsertRows();
- } else {
- // This modifies an existing sub-breakpoint.
- //qDebug() << "EXISTING ID" << id;
- it->subItems[pos] = data;
- layoutChanged();
- }
+ // This is a new sub-breakpoint.
+ LocationItem *l = new LocationItem;
+ l->params = params;
+ appendChild(l);
+ expand();
}
void BreakHandler::saveSessionData()
@@ -1166,12 +1131,7 @@ void BreakHandler::saveSessionData()
void BreakHandler::loadSessionData()
{
- beginResetModel();
- Iterator it = m_storage.begin(), et = m_storage.end();
- for ( ; it != et; ++it)
- it->destroyMarker();
- m_storage.clear();
- endResetModel();
+ removeItems();
loadBreakpoints();
}
@@ -1179,25 +1139,17 @@ void BreakHandler::breakByFunction(const QString &functionName)
{
// One breakpoint per function is enough for now. This does not handle
// combinations of multiple conditions and ignore counts, though.
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it) {
- const BreakpointParameters &data = it->data;
- if (data.functionName == functionName
- && data.condition.isEmpty()
- && data.ignoreCount == 0)
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ const BreakpointParameters &params = b->m_params;
+ if (params.functionName == functionName
+ && params.condition.isEmpty()
+ && params.ignoreCount == 0)
return;
}
- BreakpointParameters data(BreakpointByFunction);
- data.functionName = functionName;
- appendBreakpoint(data);
-}
-
-QIcon BreakHandler::icon(BreakpointModelId id) const
-{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), qDebug() << "NO ICON FOR ID" << id;
- return pendingBreakpointIcon());
- return it->icon();
+ BreakpointParameters params(BreakpointByFunction);
+ params.functionName = functionName;
+ appendBreakpoint(params);
}
void BreakHandler::scheduleSynchronization()
@@ -1215,158 +1167,127 @@ void BreakHandler::timerEvent(QTimerEvent *event)
Internal::synchronizeBreakpoints();
}
-void BreakHandler::gotoLocation(BreakpointModelId id) const
+void Breakpoint::gotoLocation() const
{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- DebuggerEngine *engine = currentEngine();
- if (it->data.type == BreakpointByAddress) {
- if (engine)
- engine->gotoLocation(it->data.address);
- } else {
- if (engine)
- engine->gotoLocation(
- Location(it->markerFileName(), it->markerLineNumber(), false));
+ if (DebuggerEngine *engine = currentEngine()) {
+ if (b->m_params.type == BreakpointByAddress)
+ engine->gotoLocation(b->m_params.address);
+ else
+ engine->gotoLocation(Location(b->markerFileName(), b->markerLineNumber(), false));
}
}
-void BreakHandler::updateFileNameFromMarker(BreakpointModelId id, const QString &fileName)
+void BreakpointItem::updateFileNameFromMarker(const QString &fileName)
{
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- it->data.fileName = fileName;
- emit layoutChanged();
+ m_params.fileName = fileName;
+ update();
}
-void BreakHandler::updateLineNumberFromMarker(BreakpointModelId id, int lineNumber)
+void BreakpointItem::updateLineNumberFromMarker(int lineNumber)
{
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
// Ignore updates to the "real" line number while the debugger is
// running, as this can be triggered by moving the breakpoint to
// the next line that generated code.
- if (it->data.lineNumber == lineNumber)
+ if (m_params.lineNumber == lineNumber)
; // Nothing
- else if (isEngineRunning(id))
- it->data.lineNumber += lineNumber - it->response.lineNumber;
+ else if (isEngineRunning())
+ m_params.lineNumber += lineNumber - m_response.lineNumber;
else
- it->data.lineNumber = lineNumber;
- it->updateMarker(id);
- emit layoutChanged();
+ m_params.lineNumber = lineNumber;
+ updateMarker();
+ update();
}
-void BreakHandler::changeLineNumberFromMarker(BreakpointModelId id, int lineNumber)
+void BreakpointItem::changeLineNumberFromMarker(int lineNumber)
{
+ m_params.lineNumber = lineNumber;
+
// We need to delay this as it is called from a marker which will be destroyed.
ExtensionSystem::InvokerBase invoker;
- invoker.addArgument(id);
- invoker.addArgument(lineNumber);
+ invoker.addArgument(m_id);
invoker.setConnectionType(Qt::QueuedConnection);
- invoker.invoke(this, "changeLineNumberFromMarkerHelper");
+ invoker.invoke(m_handler, "changeLineNumberFromMarkerHelper");
QTC_CHECK(invoker.wasSuccessful());
}
-void BreakHandler::changeLineNumberFromMarkerHelper(BreakpointModelId id, int lineNumber)
+void BreakHandler::changeLineNumberFromMarkerHelper(BreakpointModelId id)
{
- BreakpointParameters data = breakpointData(id);
- data.lineNumber = lineNumber;
- removeBreakpoint(id);
- appendBreakpoint(data);
+ Breakpoint b = breakpointById(id);
+ QTC_ASSERT(b, return);
+ BreakpointParameters params = b.parameters();
+ removeItem(b.b);
+ delete b.b;
+ appendBreakpoint(params);
}
-BreakpointModelIds BreakHandler::allBreakpointIds() const
+Breakpoints BreakHandler::allBreakpoints() const
{
- BreakpointModelIds ids;
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it)
- ids.append(it.key());
- return ids;
+ Breakpoints items;
+ foreach (TreeItem *n, rootItem()->children())
+ items.append(Breakpoint(static_cast<BreakpointItem *>(n)));
+ return items;
}
-BreakpointModelIds BreakHandler::unclaimedBreakpointIds() const
+Breakpoints BreakHandler::unclaimedBreakpoints() const
{
- return engineBreakpointIds(0);
+ return engineBreakpoints(0);
}
-BreakpointModelIds BreakHandler::engineBreakpointIds(DebuggerEngine *engine) const
+Breakpoints BreakHandler::engineBreakpoints(DebuggerEngine *engine) const
{
- BreakpointModelIds ids;
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it)
- if (it->engine == engine)
- ids.append(it.key());
- return ids;
+ Breakpoints items;
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ if (b->m_engine == engine)
+ items.append(Breakpoint(b));
+ }
+ return items;
}
QStringList BreakHandler::engineBreakpointPaths(DebuggerEngine *engine) const
{
QSet<QString> set;
- ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
- for ( ; it != et; ++it) {
- if (it->engine == engine) {
- if (it->data.type == BreakpointByFileAndLine)
- set.insert(QFileInfo(it->data.fileName).dir().path());
+ foreach (TreeItem *n, rootItem()->children()) {
+ BreakpointItem *b = static_cast<BreakpointItem *>(n);
+ if (b->m_engine == engine) {
+ if (b->m_params.type == BreakpointByFileAndLine)
+ set.insert(QFileInfo(b->m_params.fileName).dir().path());
}
}
return set.toList();
}
-void BreakHandler::cleanupBreakpoint(BreakpointModelId id)
+void Breakpoint::setResponse(const BreakpointResponse &response)
{
- QTC_ASSERT(state(id) == BreakpointDead, qDebug() << state(id));
- BreakpointItem item = m_storage.take(id);
- item.destroyMarker();
- layoutChanged();
-}
-
-const BreakpointResponse &BreakHandler::response(BreakpointModelId id) const
-{
- static BreakpointResponse dummy;
- ConstIterator it = m_storage.find(id);
- if (it == m_storage.end()) {
- qDebug() << "NO RESPONSE FOR " << id;
- return dummy;
- }
- return it->response;
-}
-
-bool BreakHandler::needsChange(BreakpointModelId id) const
-{
- ConstIterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return false);
- return it->needsChange();
+ QTC_ASSERT(b, return);
+ b->m_response = response;
+ b->destroyMarker();
+ b->updateMarker();
+ // Take over corrected values from response.
+ if ((b->m_params.type == BreakpointByFileAndLine
+ || b->m_params.type == BreakpointByFunction)
+ && !response.module.isEmpty())
+ b->m_params.module = response.module;
}
-void BreakHandler::setResponse(BreakpointModelId id,
- const BreakpointResponse &response)
+bool Internal::Breakpoint::needsChange() const
{
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- it->response = response;
- it->destroyMarker();
- it->updateMarker(id);
- // Take over corrected values from response.
- if ((it->data.type == BreakpointByFileAndLine
- || it->data.type == BreakpointByFunction)
- && !response.module.isEmpty())
- it->data.module = response.module;
+ return b && b->needsChange();
}
-void BreakHandler::changeBreakpointData(BreakpointModelId id,
- const BreakpointParameters &data, BreakpointParts parts)
+void Breakpoint::changeBreakpointData(const BreakpointParameters &params)
{
- Q_UNUSED(parts);
- Iterator it = m_storage.find(id);
- BREAK_ASSERT(it != m_storage.end(), return);
- if (data == it->data)
+ if (!b)
return;
- it->data = data;
- it->destroyMarker();
- it->updateMarker(id);
- layoutChanged();
- if (it->needsChange() && it->engine && it->state != BreakpointNew) {
- setState(id, BreakpointChangeRequested);
- scheduleSynchronization();
+ if (params == b->m_params)
+ return;
+ b->m_params = params;
+ b->destroyMarker();
+ b->updateMarker();
+ b->update();
+ if (b->needsChange() && b->m_engine && b->m_state != BreakpointNew) {
+ b->setState(BreakpointChangeRequested);
+ b->m_handler->scheduleSynchronization();
}
}
@@ -1376,42 +1297,52 @@ void BreakHandler::changeBreakpointData(BreakpointModelId id,
//
//////////////////////////////////////////////////////////////////
-BreakHandler::BreakpointItem::BreakpointItem()
- : state(BreakpointNew), engine(0), marker(0)
+// Ok to be not thread-safe. The order does not matter and only the gui
+// produces authoritative ids.
+static int currentId = 0;
+
+BreakpointItem::BreakpointItem(BreakHandler *handler)
+ : m_handler(handler), m_id(++currentId), m_state(BreakpointNew), m_engine(0), m_marker(0)
{}
-void BreakHandler::BreakpointItem::destroyMarker()
+BreakpointItem::~BreakpointItem()
+{
+ delete m_marker;
+}
+
+void BreakpointItem::destroyMarker()
{
- BreakpointMarker *m = marker;
- marker = 0;
+ BreakpointMarker *m = m_marker;
+ QTC_ASSERT(m, return);
+ m->m_bp = 0;
+ m_marker = 0;
delete m;
}
-QString BreakHandler::BreakpointItem::markerFileName() const
+QString BreakpointItem::markerFileName() const
{
// Some heuristics to find a "good" file name.
- if (!data.fileName.isEmpty()) {
- QFileInfo fi(data.fileName);
+ if (!m_params.fileName.isEmpty()) {
+ QFileInfo fi(m_params.fileName);
if (fi.exists())
return fi.absoluteFilePath();
}
- if (!response.fileName.isEmpty()) {
- QFileInfo fi(response.fileName);
+ if (!m_response.fileName.isEmpty()) {
+ QFileInfo fi(m_response.fileName);
if (fi.exists())
return fi.absoluteFilePath();
}
- if (response.fileName.endsWith(data.fileName))
- return response.fileName;
- if (data.fileName.endsWith(response.fileName))
- return data.fileName;
- return response.fileName.size() > data.fileName.size()
- ? response.fileName : data.fileName;
+ if (m_response.fileName.endsWith(m_params.fileName))
+ return m_response.fileName;
+ if (m_params.fileName.endsWith(m_response.fileName))
+ return m_params.fileName;
+ return m_response.fileName.size() > m_params.fileName.size()
+ ? m_response.fileName : m_params.fileName;
}
-
-int BreakHandler::BreakpointItem::markerLineNumber() const
+int BreakpointItem::markerLineNumber() const
{
- return response.lineNumber ? response.lineNumber : data.lineNumber;
+ return m_response.lineNumber ? m_response.lineNumber : m_params.lineNumber;
}
static void formatAddress(QTextStream &str, quint64 address)
@@ -1424,94 +1355,94 @@ static void formatAddress(QTextStream &str, quint64 address)
}
}
-bool BreakHandler::BreakpointItem::needsChange() const
+bool BreakpointItem::needsChange() const
{
- if (!data.conditionsMatch(response.condition))
+ if (!m_params.conditionsMatch(m_response.condition))
return true;
- if (data.ignoreCount != response.ignoreCount)
+ if (m_params.ignoreCount != m_response.ignoreCount)
return true;
- if (data.enabled != response.enabled)
+ if (m_params.enabled != m_response.enabled)
return true;
- if (data.threadSpec != response.threadSpec)
+ if (m_params.threadSpec != m_response.threadSpec)
return true;
- if (data.command != response.command)
+ if (m_params.command != m_response.command)
return true;
- if (data.type == BreakpointByFileAndLine && data.lineNumber != response.lineNumber)
+ if (m_params.type == BreakpointByFileAndLine && m_params.lineNumber != m_response.lineNumber)
return true;
// FIXME: Too strict, functions may have parameter lists, or not.
- // if (data.type == BreakpointByFunction && data.functionName != response.functionName)
+ // if (m_params.type == BreakpointByFunction && m_params.functionName != m_response.functionName)
// return true;
- // if (data.type == BreakpointByAddress && data.address != response.address)
+ // if (m_params.type == BreakpointByAddress && m_params.address != m_response.address)
// return true;
return false;
}
-bool BreakHandler::BreakpointItem::isLocatedAt
+bool BreakpointItem::isLocatedAt
(const QString &fileName, int lineNumber, bool useMarkerPosition) const
{
- int line = useMarkerPosition ? response.lineNumber : data.lineNumber;
+ int line = useMarkerPosition ? m_response.lineNumber : m_params.lineNumber;
return lineNumber == line
- && (fileNameMatch(fileName, response.fileName)
+ && (fileNameMatch(fileName, m_response.fileName)
|| fileNameMatch(fileName, markerFileName()));
}
-void BreakHandler::BreakpointItem::updateMarkerIcon()
+void BreakpointItem::updateMarkerIcon()
{
- if (marker) {
- marker->setIcon(icon());
- marker->updateMarker();
+ if (m_marker) {
+ m_marker->setIcon(icon());
+ m_marker->updateMarker();
}
}
-void BreakHandler::BreakpointItem::updateMarker(BreakpointModelId id)
+void BreakpointItem::updateMarker()
{
QString file = markerFileName();
int line = markerLineNumber();
- if (marker && (file != marker->fileName() || line != marker->lineNumber()))
+ if (m_marker && (file != m_marker->fileName() || line != m_marker->lineNumber()))
destroyMarker();
- if (!marker && !file.isEmpty() && line > 0)
- marker = new BreakpointMarker(id, file, line);
+ if (!m_marker && !file.isEmpty() && line > 0)
+ m_marker = new BreakpointMarker(this, file, line);
}
-QIcon BreakHandler::BreakpointItem::icon() const
+QIcon BreakpointItem::icon() const
{
// FIXME: This seems to be called on each cursor blink as soon as the
// cursor is near a line with a breakpoint marker (+/- 2 lines or so).
- if (data.isTracepoint())
+ if (m_params.isTracepoint())
return BreakHandler::tracepointIcon();
- if (data.type == WatchpointAtAddress)
+ if (m_params.type == WatchpointAtAddress)
return BreakHandler::watchpointIcon();
- if (data.type == WatchpointAtExpression)
+ if (m_params.type == WatchpointAtExpression)
return BreakHandler::watchpointIcon();
- if (!data.enabled)
+ if (!m_params.enabled)
return BreakHandler::disabledBreakpointIcon();
- if (state == BreakpointInserted)
+ if (m_state == BreakpointInserted)
return BreakHandler::breakpointIcon();
return BreakHandler::pendingBreakpointIcon();
}
-QString BreakHandler::BreakpointItem::toToolTip() const
+QString BreakpointItem::toToolTip() const
{
QString rc;
QTextStream str(&rc);
str << "<html><body><table>"
//<< "<tr><td>" << tr("ID:") << "</td><td>" << m_id << "</td></tr>"
<< "<tr><td>" << tr("State:")
- << "</td><td>" << (data.enabled ? tr("Enabled") : tr("Disabled"));
- if (response.pending)
+ << "</td><td>" << (m_params.enabled ? tr("Enabled") : tr("Disabled"));
+ if (m_response.pending)
str << tr(", pending");
- str << ", " << state << " (" << stateToString(state) << ")</td></tr>";
- if (engine) {
+ str << ", " << m_state << " (" << stateToString(m_state) << ")</td></tr>";
+ if (m_engine) {
str << "<tr><td>" << tr("Engine:")
- << "</td><td>" << engine->objectName() << "</td></tr>";
+ << "</td><td>" << m_engine->objectName() << "</td></tr>";
}
- if (!response.pending) {
+ if (!m_response.pending) {
str << "<tr><td>" << tr("Breakpoint Number:")
- << "</td><td>" << response.id.toString() << "</td></tr>";
+ << "</td><td>" << m_response.id.toString() << "</td></tr>";
}
str << "<tr><td>" << tr("Breakpoint Type:")
- << "</td><td>" << typeToString(data.type) << "</td></tr>"
+ << "</td><td>" << typeToString(m_params.type) << "</td></tr>"
<< "<tr><td>" << tr("Marker File:")
<< "</td><td>" << QDir::toNativeSeparators(markerFileName()) << "</td></tr>"
<< "<tr><td>" << tr("Marker Line:")
@@ -1521,77 +1452,77 @@ QString BreakHandler::BreakpointItem::toToolTip() const
<< "</th><th>" << tr("Requested")
<< "</th><th>" << tr("Obtained") << "</th></tr>"
<< "<tr><td>" << tr("Internal Number:")
- << "</td><td>&mdash;</td><td>" << response.id.toString() << "</td></tr>";
- if (data.type == BreakpointByFunction) {
+ << "</td><td>&mdash;</td><td>" << m_response.id.toString() << "</td></tr>";
+ if (m_params.type == BreakpointByFunction) {
str << "<tr><td>" << tr("Function Name:")
- << "</td><td>" << data.functionName
- << "</td><td>" << response.functionName
+ << "</td><td>" << m_params.functionName
+ << "</td><td>" << m_response.functionName
<< "</td></tr>";
}
- if (data.type == BreakpointByFileAndLine) {
+ if (m_params.type == BreakpointByFileAndLine) {
str << "<tr><td>" << tr("File Name:")
- << "</td><td>" << QDir::toNativeSeparators(data.fileName)
- << "</td><td>" << QDir::toNativeSeparators(response.fileName)
+ << "</td><td>" << QDir::toNativeSeparators(m_params.fileName)
+ << "</td><td>" << QDir::toNativeSeparators(m_response.fileName)
<< "</td></tr>"
<< "<tr><td>" << tr("Line Number:")
- << "</td><td>" << data.lineNumber
- << "</td><td>" << response.lineNumber << "</td></tr>"
+ << "</td><td>" << m_params.lineNumber
+ << "</td><td>" << m_response.lineNumber << "</td></tr>"
<< "<tr><td>" << tr("Corrected Line Number:")
<< "</td><td>-"
- << "</td><td>" << response.correctedLineNumber << "</td></tr>";
+ << "</td><td>" << m_response.correctedLineNumber << "</td></tr>";
}
- if (data.type == BreakpointByFunction || data.type == BreakpointByFileAndLine) {
+ if (m_params.type == BreakpointByFunction || m_params.type == BreakpointByFileAndLine) {
str << "<tr><td>" << tr("Module:")
- << "</td><td>" << data.module
- << "</td><td>" << response.module
+ << "</td><td>" << m_params.module
+ << "</td><td>" << m_response.module
<< "</td></tr>";
}
str << "<tr><td>" << tr("Breakpoint Address:")
<< "</td><td>";
- formatAddress(str, data.address);
+ formatAddress(str, m_params.address);
str << "</td><td>";
- formatAddress(str, response.address);
+ formatAddress(str, m_response.address);
str << "</td></tr>";
- if (response.multiple) {
+ if (m_response.multiple) {
str << "<tr><td>" << tr("Multiple Addresses:")
<< "</td><td>"
<< "</td></tr>";
}
- if (!data.command.isEmpty() || !response.command.isEmpty()) {
+ if (!m_params.command.isEmpty() || !m_response.command.isEmpty()) {
str << "<tr><td>" << tr("Command:")
- << "</td><td>" << data.command
- << "</td><td>" << response.command
+ << "</td><td>" << m_params.command
+ << "</td><td>" << m_response.command
<< "</td></tr>";
}
- if (!data.message.isEmpty() || !response.message.isEmpty()) {
+ if (!m_params.message.isEmpty() || !m_response.message.isEmpty()) {
str << "<tr><td>" << tr("Message:")
- << "</td><td>" << data.message
- << "</td><td>" << response.message
+ << "</td><td>" << m_params.message
+ << "</td><td>" << m_response.message
<< "</td></tr>";
}
- if (!data.condition.isEmpty() || !response.condition.isEmpty()) {
+ if (!m_params.condition.isEmpty() || !m_response.condition.isEmpty()) {
str << "<tr><td>" << tr("Condition:")
- << "</td><td>" << data.condition
- << "</td><td>" << response.condition
+ << "</td><td>" << m_params.condition
+ << "</td><td>" << m_response.condition
<< "</td></tr>";
}
- if (data.ignoreCount || response.ignoreCount) {
+ if (m_params.ignoreCount || m_response.ignoreCount) {
str << "<tr><td>" << tr("Ignore Count:") << "</td><td>";
- if (data.ignoreCount)
- str << data.ignoreCount;
+ if (m_params.ignoreCount)
+ str << m_params.ignoreCount;
str << "</td><td>";
- if (response.ignoreCount)
- str << response.ignoreCount;
+ if (m_response.ignoreCount)
+ str << m_response.ignoreCount;
str << "</td></tr>";
}
- if (data.threadSpec >= 0 || response.threadSpec >= 0) {
+ if (m_params.threadSpec >= 0 || m_response.threadSpec >= 0) {
str << "<tr><td>" << tr("Thread Specification:")
<< "</td><td>";
- if (data.threadSpec >= 0)
- str << data.threadSpec;
+ if (m_params.threadSpec >= 0)
+ str << m_params.threadSpec;
str << "</td><td>";
- if (response.threadSpec >= 0)
- str << response.threadSpec;
+ if (m_response.threadSpec >= 0)
+ str << m_response.threadSpec;
str << "</td></tr>";
}
str << "</table></body></html>";
@@ -1600,29 +1531,89 @@ QString BreakHandler::BreakpointItem::toToolTip() const
void BreakHandler::setWatchpointAtAddress(quint64 address, unsigned size)
{
- BreakpointParameters data(WatchpointAtAddress);
- data.address = address;
- data.size = size;
- BreakpointModelId id = findWatchpoint(data);
- if (id) {
+ BreakpointParameters params(WatchpointAtAddress);
+ params.address = address;
+ params.size = size;
+ if (findWatchpoint(params)) {
qDebug() << "WATCHPOINT EXISTS";
// removeBreakpoint(index);
return;
}
- appendBreakpoint(data);
+ appendBreakpoint(params);
}
void BreakHandler::setWatchpointAtExpression(const QString &exp)
{
- BreakpointParameters data(WatchpointAtExpression);
- data.expression = exp;
- BreakpointModelId id = findWatchpoint(data);
- if (id) {
+ BreakpointParameters params(WatchpointAtExpression);
+ params.expression = exp;
+ if (findWatchpoint(params)) {
qDebug() << "WATCHPOINT EXISTS";
// removeBreakpoint(index);
return;
}
- appendBreakpoint(data);
+ appendBreakpoint(params);
+}
+
+bool Breakpoint::isValid() const
+{
+ return b && b->m_id.isValid();
+}
+
+uint Breakpoint::hash() const
+{
+ return b ? 0 : qHash(b->m_id);
+}
+
+BreakpointModelId Breakpoint::id() const
+{
+ return b ? b->m_id : BreakpointModelId();
+}
+
+QString Breakpoint::msgWatchpointByExpressionTriggered(const int number, const QString &expr) const
+{
+ return id()
+ ? tr("Data breakpoint %1 (%2) at %3 triggered.")
+ .arg(id().toString()).arg(number).arg(expr)
+ : tr("Internal data breakpoint %1 at %2 triggered.")
+ .arg(number).arg(expr);
+}
+
+QString Breakpoint::msgWatchpointByExpressionTriggered(const int number, const QString &expr,
+ const QString &threadId) const
+{
+ return id()
+ ? tr("Data breakpoint %1 (%2) at %3 in thread %4 triggered.")
+ .arg(id().toString()).arg(number).arg(expr).arg(threadId)
+ : tr("Internal data breakpoint %1 at %2 in thread %3 triggered.")
+ .arg(number).arg(expr).arg(threadId);
+}
+
+QString Breakpoint::msgWatchpointByAddressTriggered(const int number, quint64 address) const
+{
+ return id()
+ ? tr("Data breakpoint %1 (%2) at 0x%3 triggered.")
+ .arg(id().toString()).arg(number).arg(address, 0, 16)
+ : tr("Internal data breakpoint %1 at 0x%2 triggered.")
+ .arg(number).arg(address, 0, 16);
+}
+
+QString Breakpoint::msgWatchpointByAddressTriggered(
+ const int number, quint64 address, const QString &threadId) const
+{
+ return id()
+ ? tr("Data breakpoint %1 (%2) at 0x%3 in thread %4 triggered.")
+ .arg(id().toString()).arg(number).arg(address, 0, 16).arg(threadId)
+ : tr("Internal data breakpoint %1 at 0x%2 in thread %3 triggered.")
+ .arg(id().toString()).arg(number).arg(address, 0, 16).arg(threadId);
+}
+
+QString Breakpoint::msgBreakpointTriggered(const int number, const QString &threadId) const
+{
+ return id()
+ ? tr("Stopped at breakpoint %1 (%2) in thread %3.")
+ .arg(id().toString()).arg(number).arg(threadId)
+ : tr("Stopped at internal breakpoint %1 in thread %2.")
+ .arg(number).arg(threadId);
}
} // namespace Internal
diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h
index 7281d88faa..430f93c698 100644
--- a/src/plugins/debugger/breakhandler.h
+++ b/src/plugins/debugger/breakhandler.h
@@ -33,7 +33,10 @@
#include "breakpoint.h"
-#include <QAbstractTableModel>
+#include <utils/treemodel.h>
+
+#include <QCoreApplication>
+#include <QPointer>
//////////////////////////////////////////////////////////////////
//
@@ -42,20 +45,132 @@
//////////////////////////////////////////////////////////////////
namespace Debugger {
+namespace Internal {
+class BreakpointItem;
+class BreakHandler;
+class DebuggerCommand;
class DebuggerEngine;
-namespace Internal {
+// Non-owning "deletion-safe" wrapper around a BreakpointItem *
+class Breakpoint
+{
+ Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::BreakHandler)
+
+public:
+ Breakpoint() {}
+
+ bool isValid() const;
+ operator const void *() const { return isValid() ? this : 0; }
+ bool operator!() const { return !isValid(); }
+
+ uint hash() const;
+
+ const BreakpointParameters &parameters() const;
+ void addToCommand(DebuggerCommand *cmd) const;
-class BreakpointMarker;
+ BreakpointModelId id() const;
+ bool isLocatedAt(const QString &fileName, int lineNumber,
+ bool useMarkerPosition) const;
+
+ QIcon icon() const;
+ BreakpointState state() const;
+ void setEngine(DebuggerEngine *engine);
+
+ // State transitions.
+ void notifyBreakpointChangeAfterInsertNeeded();
+ void notifyBreakpointInsertProceeding();
+ void notifyBreakpointInsertOk();
+ void notifyBreakpointInsertFailed();
+ void notifyBreakpointChangeOk();
+ void notifyBreakpointChangeProceeding();
+ void notifyBreakpointChangeFailed();
+ void notifyBreakpointPending();
+ void notifyBreakpointRemoveProceeding();
+ void notifyBreakpointRemoveOk();
+ void notifyBreakpointRemoveFailed();
+ void notifyBreakpointReleased();
+ void notifyBreakpointNeedsReinsertion();
+ void notifyBreakpointAdjusted(const BreakpointParameters &params);
+
+ void update();
+
+ void gotoLocation() const;
+
+ // Getter retrieves property value.
+ // Setter sets property value and triggers update if changed.
+ // Only use setters when it is safe to assume that the breakpoint still
+ // exist. That's not the case if the event loop could run after you
+ // obtained the BreakpointItem pointer.
+ BreakpointPathUsage pathUsage() const;
+ void setPathUsage(const BreakpointPathUsage &u);
+ QByteArray condition() const;
+ void setCondition(const QByteArray &condition);
+ int ignoreCount() const;
+ void setIgnoreCount(const int &count);
+ int threadSpec() const;
+ void setThreadSpec(const int &spec);
+ QString fileName() const;
+ void setFileName(const QString &fileName);
+ QString functionName() const;
+ void setFunctionName(const QString &functionName);
+ QString expression() const;
+ void setExpression(const QString &expression);
+ QString message() const;
+ void setMessage(const QString &m);
+ BreakpointType type() const;
+ void setType(const BreakpointType &type);
+ quint64 address() const;
+ void setAddress(const quint64 &address);
+ int lineNumber() const;
+ void changeBreakpointData(const BreakpointParameters &data);
+ bool isEnabled() const;
+ void setEnabled(bool on) const;
+ void updateFileNameFromMarker(const QString &fileName);
+ void updateLineNumberFromMarker(int lineNumber);
+ void changeLineNumberFromMarker(int lineNumber);
+ void setMarkerFileAndLine(const QString &fileName, int lineNumber);
+ bool isWatchpoint() const;
+ bool isTracepoint() const;
+ void setTracepoint(bool on);
+ DebuggerEngine *engine() const;
+ const BreakpointResponse &response() const;
+ void setResponse(const BreakpointResponse &data);
+ bool needsChange() const;
+ bool needsChildren() const;
+
+ bool isOneShot() const;
+ void insertSubBreakpoint(const BreakpointResponse &data);
+ void removeAlienBreakpoint();
+ void removeBreakpoint() const;
+
+ QString msgWatchpointByAddressTriggered(int number, quint64 address) const;
+ QString msgWatchpointByAddressTriggered(
+ int number, quint64 address, const QString &threadId) const;
+ QString msgWatchpointByExpressionTriggered(int number, const QString &expr) const;
+ QString msgWatchpointByExpressionTriggered(
+ int number, const QString &expr, const QString &threadId) const;
+ QString msgBreakpointTriggered(int number, const QString &threadId) const;
+
+private:
+ void gotoState(BreakpointState target, BreakpointState assumedCurrent);
-class BreakHandler : public QAbstractItemModel
+ friend class BreakHandler;
+ explicit Breakpoint(BreakpointItem *b);
+
+ QPointer<BreakpointItem> b;
+};
+
+inline uint qHash(const Debugger::Internal::Breakpoint &b) { return b.hash(); }
+
+typedef QList<Breakpoint> Breakpoints;
+
+class BreakHandler : public Utils::TreeModel
{
Q_OBJECT
public:
BreakHandler();
- ~BreakHandler();
void loadSessionData();
void saveSessionData();
@@ -65,22 +180,19 @@ public:
// The only way to add a new breakpoint.
void appendBreakpoint(const BreakpointParameters &data);
void handleAlienBreakpoint(const BreakpointResponse &response, DebuggerEngine *engine);
- void insertSubBreakpoint(BreakpointModelId id, const BreakpointResponse &data);
- void removeAlienBreakpoint(BreakpointModelId id);
- BreakpointModelIds allBreakpointIds() const;
- BreakpointModelIds engineBreakpointIds(DebuggerEngine *engine) const;
- BreakpointModelIds unclaimedBreakpointIds() const;
- int size() const { return m_storage.size(); }
+ Breakpoints allBreakpoints() const;
+ Breakpoints engineBreakpoints(DebuggerEngine *engine) const;
+ Breakpoints unclaimedBreakpoints() const;
QStringList engineBreakpointPaths(DebuggerEngine *engine) const;
// Find a breakpoint matching approximately the data in needle.
- BreakpointModelId findSimilarBreakpoint(const BreakpointResponse &needle) const;
- BreakpointModelId findBreakpointByResponseId(const BreakpointResponseId &resultId) const;
- BreakpointModelId findWatchpoint(const BreakpointParameters &data) const;
- BreakpointModelId findBreakpointByFunction(const QString &functionName) const;
- BreakpointModelId findBreakpointByIndex(const QModelIndex &index) const;
- BreakpointModelIds findBreakpointsByIndex(const QList<QModelIndex> &list) const;
+ Breakpoint findSimilarBreakpoint(const BreakpointResponse &needle) const;
+ Breakpoint findBreakpointByResponseId(const BreakpointResponseId &resultId) const;
+ Breakpoint findWatchpoint(const BreakpointParameters &data) const;
+ Breakpoint findBreakpointByFunction(const QString &functionName) const;
+ Breakpoint findBreakpointByIndex(const QModelIndex &index) const;
+ Breakpoints findBreakpointsByIndex(const QList<QModelIndex> &list) const;
void updateMarkers();
static QIcon breakpointIcon();
@@ -90,77 +202,11 @@ public:
static QIcon watchpointIcon();
static QIcon tracepointIcon();
- BreakpointModelId findBreakpointByFileAndLine(const QString &fileName,
+ Breakpoint findBreakpointByFileAndLine(const QString &fileName,
int lineNumber, bool useMarkerPosition = true);
- BreakpointModelId findBreakpointByAddress(quint64 address) const;
+ Breakpoint findBreakpointByAddress(quint64 address) const;
void breakByFunction(const QString &functionName);
- void removeBreakpoint(BreakpointModelId id);
- QIcon icon(BreakpointModelId id) const;
- void gotoLocation(BreakpointModelId id) const;
-
- // Getter retrieves property value.
- // Setter sets property value and triggers update if changed.
- BreakpointPathUsage pathUsage(BreakpointModelId id) const;
- void setPathUsage(BreakpointModelId, const BreakpointPathUsage &u);
- QByteArray condition(BreakpointModelId id) const;
- void setCondition(BreakpointModelId, const QByteArray &condition);
- int ignoreCount(BreakpointModelId id) const;
- void setIgnoreCount(BreakpointModelId, const int &count);
- int threadSpec(BreakpointModelId id) const;
- void setThreadSpec(BreakpointModelId, const int &spec);
- QString fileName(BreakpointModelId id) const;
- void setFileName(BreakpointModelId, const QString &fileName);
- QString functionName(BreakpointModelId id) const;
- void setFunctionName(BreakpointModelId, const QString &functionName);
- QString expression(BreakpointModelId id) const;
- void setExpression(BreakpointModelId, const QString &expression);
- QString message(BreakpointModelId id) const;
- void setMessage(BreakpointModelId, const QString &m);
- BreakpointType type(BreakpointModelId id) const;
- void setType(BreakpointModelId id, const BreakpointType &type);
- quint64 address(BreakpointModelId id) const;
- void setAddress(BreakpointModelId id, const quint64 &address);
- int lineNumber(BreakpointModelId id) const;
- void changeBreakpointData(BreakpointModelId id, const BreakpointParameters &data,
- BreakpointParts parts);
- const BreakpointParameters &breakpointData(BreakpointModelId id) const;
- BreakpointState state(BreakpointModelId id) const;
- bool isEnabled(BreakpointModelId id) const;
- void setEnabled(BreakpointModelId id, bool on);
- void updateFileNameFromMarker(BreakpointModelId id, const QString &fileName);
- void updateLineNumberFromMarker(BreakpointModelId id, int lineNumber);
- void changeLineNumberFromMarker(BreakpointModelId id, int lineNumber);
- void setMarkerFileAndLine(BreakpointModelId id,
- const QString &fileName, int lineNumber);
- bool isOneShot(BreakpointModelId id) const;
- bool isWatchpoint(BreakpointModelId id) const;
- bool isTracepoint(BreakpointModelId id) const;
- void setTracepoint(BreakpointModelId, bool on);
- DebuggerEngine *engine(BreakpointModelId id) const;
- void setEngine(BreakpointModelId id, DebuggerEngine *engine);
- const BreakpointResponse &response(BreakpointModelId id) const;
- void setResponse(BreakpointModelId id, const BreakpointResponse &data);
- bool needsChange(BreakpointModelId id) const;
- bool needsChildren(BreakpointModelId id) const;
-
- // State transitions.
- void notifyBreakpointChangeAfterInsertNeeded(BreakpointModelId id);
- void notifyBreakpointInsertProceeding(BreakpointModelId id);
- void notifyBreakpointInsertOk(BreakpointModelId id);
- void notifyBreakpointInsertFailed(BreakpointModelId id);
- void notifyBreakpointChangeOk(BreakpointModelId id);
- void notifyBreakpointChangeProceeding(BreakpointModelId id);
- void notifyBreakpointChangeFailed(BreakpointModelId id);
- void notifyBreakpointPending(BreakpointModelId id);
- void notifyBreakpointRemoveProceeding(BreakpointModelId id);
- void notifyBreakpointRemoveOk(BreakpointModelId id);
- void notifyBreakpointRemoveFailed(BreakpointModelId id);
- void notifyBreakpointReleased(BreakpointModelId id);
- void notifyBreakpointNeedsReinsertion(BreakpointModelId id);
- void notifyBreakpointAdjusted(BreakpointModelId id,
- const BreakpointParameters &data);
-
static QString displayFromThreadSpec(int spec);
static int threadSpecFromDisplay(const QString &str);
@@ -168,53 +214,19 @@ public:
void setWatchpointAtAddress(quint64 address, unsigned size);
void setWatchpointAtExpression(const QString &exp);
+ Breakpoint breakpointById(BreakpointModelId id) const;
+
private:
- // QAbstractItemModel implementation.
- int columnCount(const QModelIndex &parent) const;
- int rowCount(const QModelIndex &parent) const;
- QVariant data(const QModelIndex &index, int role) const;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
- QModelIndex index(int row, int col, const QModelIndex &parent) const;
- QModelIndex parent(const QModelIndex &parent) const;
- QModelIndex createIndex(int row, int column, quint32 id) const;
- QModelIndex createIndex(int row, int column, void *ptr) const;
-
- int indexOf(BreakpointModelId id) const;
- BreakpointModelId at(int index) const;
- bool isEngineRunning(BreakpointModelId id) const;
- void setState(BreakpointModelId id, BreakpointState state);
+ friend class BreakpointItem;
+ friend class Breakpoint;
+
void loadBreakpoints();
void saveBreakpoints();
- void cleanupBreakpoint(BreakpointModelId id);
- Q_SLOT void changeLineNumberFromMarkerHelper(Debugger::Internal::BreakpointModelId id, int lineNumber);
-
- struct BreakpointItem
- {
- BreakpointItem();
-
- void destroyMarker();
- bool needsChange() const;
- bool isLocatedAt(const QString &fileName, int lineNumber,
- bool useMarkerPosition) const;
- void updateMarker(BreakpointModelId id);
- void updateMarkerIcon();
- QString toToolTip() const;
- QString markerFileName() const;
- int markerLineNumber() const;
- QIcon icon() const;
-
- BreakpointParameters data;
- BreakpointState state; // Current state of breakpoint.
- DebuggerEngine *engine; // Engine currently handling the breakpoint.
- BreakpointResponse response;
- BreakpointMarker *marker;
- QList<BreakpointResponse> subItems;
- };
- typedef QHash<BreakpointModelId, BreakpointItem> BreakpointStorage;
- typedef BreakpointStorage::ConstIterator ConstIterator;
- typedef BreakpointStorage::Iterator Iterator;
- BreakpointStorage m_storage;
+
+ void appendBreakpointInternal(const BreakpointParameters &data);
+
+ Q_SLOT void changeLineNumberFromMarkerHelper(Debugger::Internal::BreakpointModelId id);
+ Q_SLOT void deletionHelper(Debugger::Internal::BreakpointModelId id);
void scheduleSynchronization();
void timerEvent(QTimerEvent *event);
@@ -224,4 +236,6 @@ private:
} // namespace Internal
} // namespace Debugger
+Q_DECLARE_METATYPE(Debugger::Internal::Breakpoint)
+
#endif // DEBUGGER_BREAKHANDLER_H
diff --git a/src/plugins/debugger/breakpoint.cpp b/src/plugins/debugger/breakpoint.cpp
index 859ed4956e..76a722c66b 100644
--- a/src/plugins/debugger/breakpoint.cpp
+++ b/src/plugins/debugger/breakpoint.cpp
@@ -94,18 +94,6 @@ QString BreakpointModelId::toString() const
return QString::number(m_majorPart);
}
-BreakpointModelId BreakpointModelId::parent() const
-{
- QTC_ASSERT(isMinor(), return BreakpointModelId());
- return BreakpointModelId(m_majorPart, 0);
-}
-
-BreakpointModelId BreakpointModelId::child(int row) const
-{
- QTC_ASSERT(isMajor(), return BreakpointModelId());
- return BreakpointModelId(m_majorPart, row + 1);
-}
-
//////////////////////////////////////////////////////////////////
//
diff --git a/src/plugins/debugger/breakpoint.h b/src/plugins/debugger/breakpoint.h
index d53a292970..989c3528c8 100644
--- a/src/plugins/debugger/breakpoint.h
+++ b/src/plugins/debugger/breakpoint.h
@@ -63,8 +63,6 @@ public:
{ return m_majorPart == id.m_majorPart && m_minorPart == id.m_minorPart; }
quint16 majorPart() const { return m_majorPart; }
quint16 minorPart() const { return m_minorPart; }
- BreakpointModelId parent() const;
- BreakpointModelId child(int row) const;
static BreakpointModelId fromInternalId(quint32 id)
{ return BreakpointModelId(id & 0xff, id >> 16); }
@@ -199,7 +197,6 @@ inline void operator|=(BreakpointParts &p, BreakpointParts r)
p = BreakpointParts(int(p) | int(r));
}
-
class BreakpointParameters
{
public:
@@ -257,8 +254,6 @@ public:
int correctedLineNumber; //!< Line number as seen by gdb.
};
-typedef QList<BreakpointModelId> BreakpointModelIds;
-
inline uint qHash(const Debugger::Internal::BreakpointModelId &id)
{
return id.toInternalId();
diff --git a/src/plugins/debugger/breakpointmarker.cpp b/src/plugins/debugger/breakpointmarker.cpp
deleted file mode 100644
index 5867d64bf9..0000000000
--- a/src/plugins/debugger/breakpointmarker.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms and
-** conditions see http://www.qt.io/terms-conditions. For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "breakpointmarker.h"
-#include "breakhandler.h"
-#include "debuggercore.h"
-
-//////////////////////////////////////////////////////////////////
-//
-// BreakpointMarker
-//
-//////////////////////////////////////////////////////////////////
-
-
-namespace Debugger {
-namespace Internal {
-
-BreakpointMarker::BreakpointMarker(BreakpointModelId id,
- const QString &fileName, int lineNumber)
- : TextMark(fileName, lineNumber), m_id(id)
-{
- setIcon(breakHandler()->icon(m_id));
- setPriority(TextEditor::TextMark::NormalPriority);
- //qDebug() << "CREATE MARKER " << fileName << lineNumber;
-}
-
-BreakpointMarker::~BreakpointMarker()
-{
- //qDebug() << "REMOVE MARKER ";
-}
-
-void BreakpointMarker::removedFromEditor()
-{
- breakHandler()->removeBreakpoint(m_id);
-}
-
-void BreakpointMarker::updateLineNumber(int lineNumber)
-{
- TextMark::updateLineNumber(lineNumber);
- breakHandler()->updateLineNumberFromMarker(m_id, lineNumber);
-}
-
-void BreakpointMarker::dragToLine(int lineNumber)
-{
- breakHandler()->changeLineNumberFromMarker(m_id, lineNumber);
-}
-
-void BreakpointMarker::clicked()
-{
- breakHandler()->removeBreakpoint(m_id);
-}
-
-void BreakpointMarker::updateFileName(const QString &fileName)
-{
- TextMark::updateFileName(fileName);
- breakHandler()->updateFileNameFromMarker(m_id, fileName);
-}
-
-} // namespace Internal
-} // namespace Debugger
-
diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp
index fdc2364992..ff5434e298 100644
--- a/src/plugins/debugger/breakwindow.cpp
+++ b/src/plugins/debugger/breakwindow.cpp
@@ -49,7 +49,6 @@
#include <QKeyEvent>
#include <QLabel>
#include <QLineEdit>
-#include <QMessageBox>
#include <QMenu>
#include <QSpinBox>
#include <QTextEdit>
@@ -81,7 +80,7 @@ class BreakpointDialog : public QDialog
{
Q_OBJECT
public:
- explicit BreakpointDialog(BreakpointModelId id, QWidget *parent = 0);
+ explicit BreakpointDialog(Breakpoint b, QWidget *parent = 0);
bool showDialog(BreakpointParameters *data, BreakpointParts *parts);
void setParameters(const BreakpointParameters &data);
@@ -139,13 +138,13 @@ private:
QDialogButtonBox *m_buttonBox;
};
-BreakpointDialog::BreakpointDialog(BreakpointModelId id, QWidget *parent)
+BreakpointDialog::BreakpointDialog(Breakpoint b, QWidget *parent)
: QDialog(parent), m_enabledParts(~0), m_previousType(UnknownBreakpointType),
m_firstTypeChange(true)
{
setWindowTitle(tr("Edit Breakpoint Properties"));
- QGroupBox *groupBoxBasic = new QGroupBox(tr("Basic"), this);
+ auto groupBoxBasic = new QGroupBox(tr("Basic"), this);
// Match BreakpointType (omitting unknown type).
QStringList types;
@@ -196,7 +195,7 @@ BreakpointDialog::BreakpointDialog(BreakpointModelId id, QWidget *parent)
m_labelFunction = new QLabel(tr("Fun&ction:"), groupBoxBasic);
m_labelFunction->setBuddy(m_lineEditFunction);
- QGroupBox *groupBoxAdvanced = new QGroupBox(tr("Advanced"), this);
+ auto groupBoxAdvanced = new QGroupBox(tr("Advanced"), this);
m_checkBoxTracepoint = new QCheckBox(groupBoxAdvanced);
m_labelTracepoint = new QLabel(tr("T&racepoint only:"), groupBoxAdvanced);
@@ -269,8 +268,8 @@ BreakpointDialog::BreakpointDialog(BreakpointModelId id, QWidget *parent)
m_buttonBox = new QDialogButtonBox(this);
m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
- if (id.isValid()) {
- if (DebuggerEngine *engine = breakHandler()->engine(id)) {
+ if (b) {
+ if (DebuggerEngine *engine = b.engine()) {
if (!engine->hasCapability(BreakConditionCapability))
m_enabledParts &= ~ConditionPart;
if (!engine->hasCapability(BreakModuleCapability))
@@ -280,7 +279,7 @@ BreakpointDialog::BreakpointDialog(BreakpointModelId id, QWidget *parent)
}
}
- QFormLayout *basicLayout = new QFormLayout(groupBoxBasic);
+ auto basicLayout = new QFormLayout(groupBoxBasic);
basicLayout->addRow(m_labelType, m_comboBoxType);
basicLayout->addRow(m_labelFileName, m_pathChooserFileName);
basicLayout->addRow(m_labelLineNumber, m_lineEditLineNumber);
@@ -290,7 +289,7 @@ BreakpointDialog::BreakpointDialog(BreakpointModelId id, QWidget *parent)
basicLayout->addRow(m_labelFunction, m_lineEditFunction);
basicLayout->addRow(m_labelOneShot, m_checkBoxOneShot);
- QFormLayout *advancedLeftLayout = new QFormLayout();
+ auto advancedLeftLayout = new QFormLayout();
advancedLeftLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
advancedLeftLayout->addRow(m_labelCondition, m_lineEditCondition);
advancedLeftLayout->addRow(m_labelIgnoreCount, m_spinBoxIgnoreCount);
@@ -298,18 +297,18 @@ BreakpointDialog::BreakpointDialog(BreakpointModelId id, QWidget *parent)
advancedLeftLayout->addRow(m_labelUseFullPath, m_comboBoxPathUsage);
advancedLeftLayout->addRow(m_labelModule, m_lineEditModule);
- QFormLayout *advancedRightLayout = new QFormLayout();
+ auto advancedRightLayout = new QFormLayout();
advancedRightLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
advancedRightLayout->addRow(m_labelCommands, m_textEditCommands);
advancedRightLayout->addRow(m_labelTracepoint, m_checkBoxTracepoint);
advancedRightLayout->addRow(m_labelMessage, m_lineEditMessage);
- QHBoxLayout *horizontalLayout = new QHBoxLayout(groupBoxAdvanced);
+ auto horizontalLayout = new QHBoxLayout(groupBoxAdvanced);
horizontalLayout->addLayout(advancedLeftLayout);
horizontalLayout->addSpacing(15);
horizontalLayout->addLayout(advancedRightLayout);
- QVBoxLayout *verticalLayout = new QVBoxLayout(this);
+ auto verticalLayout = new QVBoxLayout(this);
verticalLayout->addWidget(groupBoxBasic);
verticalLayout->addSpacing(10);
verticalLayout->addWidget(groupBoxAdvanced);
@@ -317,9 +316,10 @@ BreakpointDialog::BreakpointDialog(BreakpointModelId id, QWidget *parent)
verticalLayout->addWidget(m_buttonBox);
verticalLayout->setStretchFactor(groupBoxAdvanced, 10);
- connect(m_comboBoxType, SIGNAL(activated(int)), SLOT(typeChanged(int)));
- connect(m_buttonBox, SIGNAL(accepted()), SLOT(accept()));
- connect(m_buttonBox, SIGNAL(rejected()), SLOT(reject()));
+ connect(m_comboBoxType, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
+ this, &BreakpointDialog::typeChanged);
+ connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
void BreakpointDialog::setType(BreakpointType type)
@@ -655,18 +655,18 @@ MultiBreakPointsDialog::MultiBreakPointsDialog(QWidget *parent) :
m_buttonBox = new QDialogButtonBox(this);
m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
- QFormLayout *formLayout = new QFormLayout;
+ auto formLayout = new QFormLayout;
if (currentEngine()->hasCapability(BreakConditionCapability))
formLayout->addRow(tr("&Condition:"), m_lineEditCondition);
formLayout->addRow(tr("&Ignore count:"), m_spinBoxIgnoreCount);
formLayout->addRow(tr("&Thread specification:"), m_lineEditThreadSpec);
- QVBoxLayout *verticalLayout = new QVBoxLayout(this);
+ auto verticalLayout = new QVBoxLayout(this);
verticalLayout->addLayout(formLayout);
verticalLayout->addWidget(m_buttonBox);
- QObject::connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
- QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
///////////////////////////////////////////////////////////////////////
@@ -679,8 +679,8 @@ BreakTreeView::BreakTreeView()
{
setWindowIcon(QIcon(QLatin1String(":/debugger/images/debugger_breakpoints.png")));
setSelectionMode(QAbstractItemView::ExtendedSelection);
- connect(action(UseAddressInBreakpointsView),
- SIGNAL(toggled(bool)), SLOT(showAddressColumn(bool)));
+ connect(action(UseAddressInBreakpointsView), &QAction::toggled,
+ this, &BreakTreeView::showAddressColumn);
}
void BreakTreeView::showAddressColumn(bool on)
@@ -693,22 +693,21 @@ void BreakTreeView::keyPressEvent(QKeyEvent *ev)
if (ev->key() == Qt::Key_Delete) {
QItemSelectionModel *sm = selectionModel();
QTC_ASSERT(sm, return);
- QModelIndexList si = sm->selectedIndexes();
+ QModelIndexList si = sm->selectedRows();
if (si.isEmpty())
si.append(currentIndex());
- const BreakpointModelIds ids = breakHandler()->findBreakpointsByIndex(si);
+ const Breakpoints ids = breakHandler()->findBreakpointsByIndex(si);
int row = qMin(model()->rowCount() - ids.size() - 1, currentIndex().row());
deleteBreakpoints(ids);
- setCurrentIndex(si.at(0).sibling(row, 0));
+ setCurrentIndex(model()->index(row, 0));
} else if (ev->key() == Qt::Key_Space) {
QItemSelectionModel *sm = selectionModel();
QTC_ASSERT(sm, return);
- const QModelIndexList selectedIds = sm->selectedIndexes();
+ const QModelIndexList selectedIds = sm->selectedRows();
if (!selectedIds.isEmpty()) {
- BreakHandler *handler = breakHandler();
- const BreakpointModelIds validIds = handler->findBreakpointsByIndex(selectedIds);
- const bool isEnabled = validIds.isEmpty() || handler->isEnabled(validIds.at(0));
- setBreakpointsEnabled(validIds, !isEnabled);
+ const Breakpoints items = breakHandler()->findBreakpointsByIndex(selectedIds);
+ const bool isEnabled = items.isEmpty() || items.at(0).isEnabled();
+ setBreakpointsEnabled(items, !isEnabled);
foreach (const QModelIndex &id, selectedIds)
update(id);
}
@@ -721,8 +720,9 @@ void BreakTreeView::mouseDoubleClickEvent(QMouseEvent *ev)
QModelIndex indexUnderMouse = indexAt(ev->pos());
if (indexUnderMouse.isValid()) {
if (indexUnderMouse.column() >= 4) {
- BreakpointModelId id = breakHandler()->findBreakpointByIndex(indexUnderMouse);
- editBreakpoints(BreakpointModelIds() << id);
+ Breakpoint b = breakHandler()->findBreakpointByIndex(indexUnderMouse);
+ QTC_ASSERT(b, return);
+ editBreakpoints(Breakpoints() << b);
}
} else {
addBreakpoint();
@@ -735,27 +735,24 @@ void BreakTreeView::contextMenuEvent(QContextMenuEvent *ev)
QMenu menu;
QItemSelectionModel *sm = selectionModel();
QTC_ASSERT(sm, return);
- QModelIndexList selectedIndices = sm->selectedIndexes();
+ QModelIndexList selectedIndices = sm->selectedRows();
QModelIndex indexUnderMouse = indexAt(ev->pos());
if (selectedIndices.isEmpty() && indexUnderMouse.isValid())
selectedIndices.append(indexUnderMouse);
BreakHandler *handler = breakHandler();
- BreakpointModelIds selectedIds;
- foreach (BreakpointModelId id, handler->findBreakpointsByIndex(selectedIndices))
- if (id.isMajor())
- selectedIds.append(id);
+ Breakpoints selectedItems = handler->findBreakpointsByIndex(selectedIndices);
const int rowCount = model()->rowCount();
- QAction *deleteAction = new QAction(tr("Delete Breakpoint"), &menu);
- deleteAction->setEnabled(!selectedIds.empty());
+ auto deleteAction = new QAction(tr("Delete Selected Breakpoints"), &menu);
+ deleteAction->setEnabled(!selectedItems.empty());
- QAction *deleteAllAction = new QAction(tr("Delete All Breakpoints"), &menu);
+ auto deleteAllAction = new QAction(tr("Delete All Breakpoints"), &menu);
deleteAllAction->setEnabled(model()->rowCount() > 0);
// Delete by file: Find indices of breakpoints of the same file.
QAction *deleteByFileAction = 0;
- BreakpointModelIds breakpointsInFile;
+ Breakpoints breakpointsInFile;
if (indexUnderMouse.isValid()) {
const QModelIndex index = indexUnderMouse.sibling(indexUnderMouse.row(), 2);
const QString file = index.data().toString();
@@ -775,36 +772,33 @@ void BreakTreeView::contextMenuEvent(QContextMenuEvent *ev)
deleteByFileAction->setEnabled(false);
}
- QAction *editBreakpointAction =
- new QAction(tr("Edit Breakpoint..."), &menu);
- editBreakpointAction->setEnabled(!selectedIds.isEmpty());
+ auto editBreakpointAction = new QAction(tr("Edit Breakpoint..."), &menu);
+ editBreakpointAction->setEnabled(!selectedItems.isEmpty());
int threadId = 0;
// FIXME BP: m_engine->threadsHandler()->currentThreadId();
QString associateTitle = threadId == -1
? tr("Associate Breakpoint With All Threads")
: tr("Associate Breakpoint With Thread %1").arg(threadId);
- QAction *associateBreakpointAction = new QAction(associateTitle, &menu);
- associateBreakpointAction->setEnabled(!selectedIds.isEmpty());
+ auto associateBreakpointAction = new QAction(associateTitle, &menu);
+ associateBreakpointAction->setEnabled(!selectedItems.isEmpty());
- QAction *synchronizeAction =
- new QAction(tr("Synchronize Breakpoints"), &menu);
+ auto synchronizeAction = new QAction(tr("Synchronize Breakpoints"), &menu);
synchronizeAction->setEnabled(Internal::hasSnapshots());
- bool enabled = selectedIds.isEmpty() || handler->isEnabled(selectedIds.at(0));
+ bool enabled = selectedItems.isEmpty() || selectedItems.at(0).isEnabled();
- const QString str5 = selectedIds.size() > 1
+ const QString str5 = selectedItems.size() > 1
? enabled
? tr("Disable Selected Breakpoints")
: tr("Enable Selected Breakpoints")
: enabled
? tr("Disable Breakpoint")
: tr("Enable Breakpoint");
- QAction *toggleEnabledAction = new QAction(str5, &menu);
- toggleEnabledAction->setEnabled(!selectedIds.isEmpty());
+ auto toggleEnabledAction = new QAction(str5, &menu);
+ toggleEnabledAction->setEnabled(!selectedItems.isEmpty());
- QAction *addBreakpointAction =
- new QAction(tr("Add Breakpoint..."), this);
+ auto addBreakpointAction = new QAction(tr("Add Breakpoint..."), this);
menu.addAction(addBreakpointAction);
menu.addAction(deleteAction);
@@ -826,28 +820,27 @@ void BreakTreeView::contextMenuEvent(QContextMenuEvent *ev)
QAction *act = menu.exec(ev->globalPos());
if (act == deleteAction)
- deleteBreakpoints(selectedIds);
+ deleteBreakpoints(selectedItems);
else if (act == deleteAllAction)
deleteAllBreakpoints();
else if (act == deleteByFileAction)
deleteBreakpoints(breakpointsInFile);
else if (act == editBreakpointAction)
- editBreakpoints(selectedIds);
+ editBreakpoints(selectedItems);
else if (act == associateBreakpointAction)
- associateBreakpoint(selectedIds, threadId);
+ associateBreakpoint(selectedItems, threadId);
else if (act == synchronizeAction)
; //synchronizeBreakpoints();
else if (act == toggleEnabledAction)
- setBreakpointsEnabled(selectedIds, !enabled);
+ setBreakpointsEnabled(selectedItems, !enabled);
else if (act == addBreakpointAction)
addBreakpoint();
}
-void BreakTreeView::setBreakpointsEnabled(const BreakpointModelIds &ids, bool enabled)
+void BreakTreeView::setBreakpointsEnabled(const Breakpoints &bps, bool enabled)
{
- BreakHandler *handler = breakHandler();
- foreach (const BreakpointModelId id, ids)
- handler->setEnabled(id, enabled);
+ foreach (Breakpoint b, bps)
+ b.setEnabled(enabled);
}
void BreakTreeView::deleteAllBreakpoints()
@@ -858,55 +851,56 @@ void BreakTreeView::deleteAllBreakpoints()
"from all files in the current session?"),
Core::ICore::settings(),
QLatin1String("RemoveAllBreakpoints")) == QDialogButtonBox::Yes)
- deleteBreakpoints(breakHandler()->allBreakpointIds());
+ deleteBreakpoints(breakHandler()->allBreakpoints());
}
-void BreakTreeView::deleteBreakpoints(const BreakpointModelIds &ids)
+void BreakTreeView::deleteBreakpoints(const Breakpoints &bps)
{
- BreakHandler *handler = breakHandler();
- foreach (const BreakpointModelId id, ids)
- handler->removeBreakpoint(id);
+ foreach (Breakpoint bp, bps)
+ bp.removeBreakpoint();
}
-void BreakTreeView::editBreakpoint(BreakpointModelId id, QWidget *parent)
+void BreakTreeView::editBreakpoint(Breakpoint bp, QWidget *parent)
{
- BreakpointParameters data = breakHandler()->breakpointData(id);
+ BreakpointParameters data = bp.parameters();
BreakpointParts parts = NoParts;
- BreakpointDialog dialog(id, parent);
- if (dialog.showDialog(&data, &parts))
- breakHandler()->changeBreakpointData(id, data, parts);
+
+ BreakpointDialog dialog(bp, parent);
+ if (!dialog.showDialog(&data, &parts))
+ return;
+
+ bp.changeBreakpointData(data);
}
void BreakTreeView::addBreakpoint()
{
BreakpointParameters data(BreakpointByFileAndLine);
BreakpointParts parts = NoParts;
- BreakpointDialog dialog(BreakpointModelId(), this);
+ BreakpointDialog dialog(Breakpoint(), this);
dialog.setWindowTitle(tr("Add Breakpoint"));
if (dialog.showDialog(&data, &parts))
breakHandler()->appendBreakpoint(data);
}
-void BreakTreeView::editBreakpoints(const BreakpointModelIds &ids)
+void BreakTreeView::editBreakpoints(const Breakpoints &bps)
{
- QTC_ASSERT(!ids.isEmpty(), return);
+ QTC_ASSERT(!bps.isEmpty(), return);
- const BreakpointModelId id = ids.at(0);
+ const Breakpoint bp = bps.at(0);
- if (ids.size() == 1) {
- editBreakpoint(id, this);
+ if (bps.size() == 1) {
+ editBreakpoint(bp, this);
return;
}
// This allows to change properties of multiple breakpoints at a time.
- BreakHandler *handler = breakHandler();
+ if (!bp)
+ return;
+
MultiBreakPointsDialog dialog;
- const QString oldCondition = QString::fromLatin1(handler->condition(id));
- dialog.setCondition(oldCondition);
- const int oldIgnoreCount = handler->ignoreCount(id);
- dialog.setIgnoreCount(oldIgnoreCount);
- const int oldThreadSpec = handler->threadSpec(id);
- dialog.setThreadSpec(oldThreadSpec);
+ dialog.setCondition(QString::fromLatin1(bp.condition()));
+ dialog.setIgnoreCount(bp.ignoreCount());
+ dialog.setThreadSpec(bp.threadSpec());
if (dialog.exec() == QDialog::Rejected)
return;
@@ -915,27 +909,27 @@ void BreakTreeView::editBreakpoints(const BreakpointModelIds &ids)
const int newIgnoreCount = dialog.ignoreCount();
const int newThreadSpec = dialog.threadSpec();
- if (newCondition == oldCondition && newIgnoreCount == oldIgnoreCount
- && newThreadSpec == oldThreadSpec)
- return;
-
- foreach (const BreakpointModelId id, ids) {
- handler->setCondition(id, newCondition.toLatin1());
- handler->setIgnoreCount(id, newIgnoreCount);
- handler->setThreadSpec(id, newThreadSpec);
+ foreach (Breakpoint bp, bps) {
+ if (bp) {
+ bp.setCondition(newCondition.toLatin1());
+ bp.setIgnoreCount(newIgnoreCount);
+ bp.setThreadSpec(newThreadSpec);
+ }
}
}
-void BreakTreeView::associateBreakpoint(const BreakpointModelIds &ids, int threadId)
+void BreakTreeView::associateBreakpoint(const Breakpoints &bps, int threadId)
{
- BreakHandler *handler = breakHandler();
- foreach (const BreakpointModelId id, ids)
- handler->setThreadSpec(id, threadId);
+ foreach (Breakpoint bp, bps) {
+ if (bp)
+ bp.setThreadSpec(threadId);
+ }
}
void BreakTreeView::rowActivated(const QModelIndex &index)
{
- breakHandler()->gotoLocation(breakHandler()->findBreakpointByIndex(index));
+ if (Breakpoint bp = breakHandler()->findBreakpointByIndex(index))
+ bp.gotoLocation();
}
} // namespace Internal
diff --git a/src/plugins/debugger/breakwindow.h b/src/plugins/debugger/breakwindow.h
index 5c9154859d..f66d3e5eea 100644
--- a/src/plugins/debugger/breakwindow.h
+++ b/src/plugins/debugger/breakwindow.h
@@ -31,7 +31,7 @@
#ifndef DEBUGGER_BREAKWINDOW_H
#define DEBUGGER_BREAKWINDOW_H
-#include "breakpoint.h"
+#include "breakhandler.h"
#include <utils/basetreeview.h>
namespace Debugger {
@@ -44,7 +44,7 @@ class BreakTreeView : public Utils::BaseTreeView
public:
BreakTreeView();
- static void editBreakpoint(BreakpointModelId id, QWidget *parent);
+ static void editBreakpoint(Breakpoint bp, QWidget *parent);
private slots:
void showAddressColumn(bool on);
@@ -55,12 +55,12 @@ private:
void keyPressEvent(QKeyEvent *ev);
void mouseDoubleClickEvent(QMouseEvent *ev);
- void deleteBreakpoints(const BreakpointModelIds &ids);
+ void deleteBreakpoints(const Breakpoints &bps);
void deleteAllBreakpoints();
void addBreakpoint();
- void editBreakpoints(const BreakpointModelIds &ids);
- void associateBreakpoint(const BreakpointModelIds &ids, int thread);
- void setBreakpointsEnabled(const BreakpointModelIds &ids, bool enabled);
+ void editBreakpoints(const Breakpoints &bps);
+ void associateBreakpoint(const Breakpoints &bps, int thread);
+ void setBreakpointsEnabled(const Breakpoints &bps, bool enabled);
};
} // namespace Internal
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index cb210b8f8e..a23fc804d7 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -55,6 +55,7 @@
#include <debugger/shared/hostutils.h>
#include <coreplugin/icore.h>
+#include <coreplugin/messagebox.h>
#include <projectexplorer/taskhub.h>
#include <texteditor/texteditor.h>
@@ -72,7 +73,6 @@
#include <cpptools/cppworkingcopy.h>
#include <QDir>
-#include <QMessageBox>
#include <cctype>
@@ -340,17 +340,22 @@ CdbEngine::CdbEngine(const DebuggerStartParameters &sp) :
m_watchPointY(0),
m_ignoreCdbOutput(false)
{
- connect(action(OperateByInstruction), SIGNAL(triggered(bool)),
- this, SLOT(operateByInstructionTriggered(bool)));
- connect(action(VerboseLog), SIGNAL(triggered(bool)),
- this, SLOT(verboseLogTriggered(bool)));
- connect(action(CreateFullBacktrace), SIGNAL(triggered()),
- this, SLOT(createFullBacktrace()));
setObjectName(QLatin1String("CdbEngine"));
- connect(&m_process, SIGNAL(finished(int)), this, SLOT(processFinished()));
- connect(&m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError()));
- connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOut()));
- connect(&m_process, SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardOut()));
+
+ connect(action(OperateByInstruction), &QAction::triggered,
+ this, &CdbEngine::operateByInstructionTriggered);
+ connect(action(VerboseLog), &QAction::triggered,
+ this, &CdbEngine::verboseLogTriggered);
+ connect(action(CreateFullBacktrace), &QAction::triggered,
+ this, &CdbEngine::createFullBacktrace);
+ connect(&m_process, static_cast<void(QProcess::*)(int)>(&QProcess::finished),
+ this, &CdbEngine::processFinished);
+ connect(&m_process, static_cast<void(QProcess::*)(QProcess::ProcessError)>(&QProcess::error),
+ this, &CdbEngine::processError);
+ connect(&m_process, &QProcess::readyReadStandardOutput,
+ this, &CdbEngine::readyReadStandardOut);
+ connect(&m_process, &QProcess::readyReadStandardError,
+ this, &CdbEngine::readyReadStandardOut);
}
void CdbEngine::init()
@@ -534,7 +539,7 @@ void CdbEngine::consoleStubError(const QString &msg)
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineIll")
notifyEngineIll();
}
- showMessageBox(QMessageBox::Critical, tr("Debugger Error"), msg);
+ Core::AsynchronousMessageBox::critical(tr("Debugger Error"), msg);
}
void CdbEngine::consoleStubProcessStarted()
@@ -552,7 +557,7 @@ void CdbEngine::consoleStubProcessStarted()
QString errorMessage;
if (!launchCDB(attachParameters, &errorMessage)) {
showMessage(errorMessage, LogError);
- showMessageBox(QMessageBox::Critical, tr("Failed to Start the Debugger"), errorMessage);
+ Core::AsynchronousMessageBox::critical(tr("Failed to Start the Debugger"), errorMessage);
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupFailed")
notifyEngineSetupFailed();
}
@@ -599,7 +604,7 @@ void CdbEngine::setupEngine()
qDebug("<setupEngine ok=%d", ok);
if (!ok) {
showMessage(errorMessage, LogError);
- showMessageBox(QMessageBox::Critical, tr("Failed to Start the Debugger"), errorMessage);
+ Core::AsynchronousMessageBox::critical(tr("Failed to Start the Debugger"), errorMessage);
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupFailed")
notifyEngineSetupFailed();
}
@@ -1235,14 +1240,12 @@ void CdbEngine::executeRunToFunction(const QString &functionName)
continueInferior();
}
-void CdbEngine::setRegisterValue(int regnr, const QString &value)
+void CdbEngine::setRegisterValue(const QByteArray &name, const QString &value)
{
- const Registers registers = registerHandler()->registers();
- QTC_ASSERT(regnr < registers.size(), return);
// Value is decimal or 0x-hex-prefixed
QByteArray cmd;
ByteArrayInputStream str(cmd);
- str << "r " << registers.at(regnr).name << '=' << value;
+ str << "r " << name << '=' << value;
postCommand(cmd, 0);
reloadRegisters();
}
@@ -1854,29 +1857,14 @@ void CdbEngine::handlePid(const CdbExtensionCommandPtr &reply)
}
}
-// Parse CDB gdbmi register syntax.
-static Register parseRegister(const GdbMi &gdbmiReg)
-{
- Register reg;
- reg.name = gdbmiReg["name"].data();
- const GdbMi description = gdbmiReg["description"];
- if (description.type() != GdbMi::Invalid) {
- reg.name += " (";
- reg.name += description.data();
- reg.name += ')';
- }
- reg.value = gdbmiReg["value"].data();
- return reg;
-}
-
void CdbEngine::handleModules(const CdbExtensionCommandPtr &reply)
{
if (reply->success) {
GdbMi value;
value.fromString(reply->reply);
if (value.type() == GdbMi::List) {
- Modules modules;
- modules.reserve(value.childCount());
+ ModulesHandler *handler = modulesHandler();
+ handler->beginUpdateAll();
foreach (const GdbMi &gdbmiModule, value.children()) {
Module module;
module.moduleName = QString::fromLatin1(gdbmiModule["name"].data());
@@ -1885,9 +1873,9 @@ void CdbEngine::handleModules(const CdbExtensionCommandPtr &reply)
module.endAddress = gdbmiModule["end"].data().toULongLong(0, 0);
if (gdbmiModule["deferred"].type() == GdbMi::Invalid)
module.symbolsRead = Module::ReadOk;
- modules.push_back(module);
+ handler->updateModule(module);
}
- modulesHandler()->setModules(modules);
+ handler->endUpdateAll();
} else {
showMessage(QString::fromLatin1("Parse error in modules response."), LogError);
qWarning("Parse error in modules response:\n%s", reply->reply.constData());
@@ -1906,11 +1894,17 @@ void CdbEngine::handleRegisters(const CdbExtensionCommandPtr &reply)
GdbMi value;
value.fromString(reply->reply);
if (value.type() == GdbMi::List) {
- Registers registers;
- registers.reserve(value.childCount());
- foreach (const GdbMi &gdbmiReg, value.children())
- registers.push_back(parseRegister(gdbmiReg));
- registerHandler()->setAndMarkRegisters(registers);
+ RegisterHandler *handler = registerHandler();
+ foreach (const GdbMi &item, value.children()) {
+ Register reg;
+ reg.name = item["name"].data();
+ reg.description = item["description"].data();
+ reg.reportedType = item["type"].data();
+ reg.value = item["value"].data();
+ reg.size = item["size"].data().toInt();
+ handler->updateRegister(reg);
+ }
+ handler->commitUpdates();
} else {
showMessage(QString::fromLatin1("Parse error in registers response."), LogError);
qWarning("Parse error in registers response:\n%s", reply->reply.constData());
@@ -1944,7 +1938,7 @@ void CdbEngine::handleLocals(const CdbExtensionCommandPtr &reply)
WatchData dummy;
dummy.iname = child["iname"].data();
dummy.name = QLatin1String(child["name"].data());
- parseWatchData(handler->expandedINames(), dummy, child, &watchData);
+ parseWatchData(dummy, child, &watchData);
}
// Fix the names of watch data.
for (int i =0; i < watchData.size(); ++i) {
@@ -2084,9 +2078,10 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
// Step out creates temporary breakpoints with id 10000.
int number = 0;
BreakpointModelId id = cdbIdToBreakpointModelId(stopReason["breakpointId"]);
- if (id.isValid()) {
- if (breakHandler()->engineBreakpointIds(this).contains(id)) {
- const BreakpointResponse parameters = breakHandler()->response(id);
+ Breakpoint bp = breakHandler()->breakpointById(id);
+ if (bp) {
+ if (bp.engine() == this) {
+ const BreakpointResponse parameters = bp.response();
if (!parameters.message.isEmpty()) {
showMessage(parameters.message + QLatin1Char('\n'), AppOutput);
showMessage(parameters.message, LogMisc);
@@ -2107,16 +2102,16 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
return StopReportLog;
}
} else {
- id = BreakpointModelId();
+ bp = Breakpoint();
}
}
QString tid = QString::number(threadId);
- if (id && breakHandler()->type(id) == WatchpointAtAddress)
- *message = msgWatchpointByAddressTriggered(id, number, breakHandler()->address(id), tid);
- else if (id && breakHandler()->type(id) == WatchpointAtExpression)
- *message = msgWatchpointByExpressionTriggered(id, number, breakHandler()->expression(id), tid);
+ if (bp.type() == WatchpointAtAddress)
+ *message = bp.msgWatchpointByAddressTriggered(number, bp.address(), tid);
+ else if (bp.type() == WatchpointAtExpression)
+ *message = bp.msgWatchpointByExpressionTriggered(number, bp.expression(), tid);
else
- *message = msgBreakpointTriggered(id, number, tid);
+ *message = bp.msgBreakpointTriggered(number, tid);
rc |= StopReportStatusMessage|StopNotifyStop;
return rc;
}
@@ -2328,6 +2323,7 @@ void CdbEngine::handleBreakInsert(const CdbBuiltinCommandPtr &cmd)
if (!ok)
return;
const BreakpointModelId &originalId = cdbIdToBreakpointModelId(cdbBreakPointId);
+ Breakpoint bp = breakHandler()->breakpointById(originalId);
// add break point for every match
const QList<QByteArray>::const_iterator &end = reply.constEnd();
int subBreakPointID = 0;
@@ -2347,7 +2343,7 @@ void CdbEngine::handleBreakInsert(const CdbBuiltinCommandPtr &cmd)
continue;
BreakpointModelId id(originalId.majorPart(), ++subBreakPointID);
- BreakpointResponse res = breakHandler()->response(originalId);
+ BreakpointResponse res = bp.response();
res.type = BreakpointByAddress;
res.address = address;
m_insertSubBreakpointMap.insert(id, res);
@@ -2759,12 +2755,11 @@ bool CdbEngine::stateAcceptsBreakpointChanges() const
return false;
}
-bool CdbEngine::acceptsBreakpoint(BreakpointModelId id) const
+bool CdbEngine::acceptsBreakpoint(Breakpoint bp) const
{
- const BreakpointParameters &data = breakHandler()->breakpointData(id);
- if (!data.isCppBreakpoint())
+ if (!bp.parameters().isCppBreakpoint())
return false;
- switch (data.type) {
+ switch (bp.type()) {
case UnknownBreakpointType:
case LastBreakpointType:
case BreakpointAtFork:
@@ -2838,23 +2833,21 @@ unsigned BreakpointCorrectionContext::fixLineNumber(const QString &fileName,
void CdbEngine::attemptBreakpointSynchronization()
{
-
-
if (debug)
qDebug("attemptBreakpointSynchronization in %s", stateName(state()));
// Check if there is anything to be done at all.
BreakHandler *handler = breakHandler();
// Take ownership of the breakpoint. Requests insertion. TODO: Cpp only?
- foreach (BreakpointModelId id, handler->unclaimedBreakpointIds())
- if (acceptsBreakpoint(id))
- handler->setEngine(id, this);
+ foreach (Breakpoint bp, handler->unclaimedBreakpoints())
+ if (acceptsBreakpoint(bp))
+ bp.setEngine(this);
// Quick check: is there a need to change something? - Populate module cache
bool changed = !m_insertSubBreakpointMap.isEmpty();
- const BreakpointModelIds ids = handler->engineBreakpointIds(this);
+ const Breakpoints bps = handler->engineBreakpoints(this);
if (!changed) {
- foreach (BreakpointModelId id, ids) {
- switch (handler->state(id)) {
+ foreach (Breakpoint bp, bps) {
+ switch (bp.state()) {
case BreakpointInsertRequested:
case BreakpointRemoveRequested:
case BreakpointChangeRequested:
@@ -2863,7 +2856,7 @@ void CdbEngine::attemptBreakpointSynchronization()
case BreakpointInserted: {
// Collect the new modules matching the files.
// In the future, that information should be obtained from the build system.
- const BreakpointParameters &data = handler->breakpointData(id);
+ const BreakpointParameters &data = bp.parameters();
if (data.type == BreakpointByFileAndLine && !data.module.isEmpty())
m_fileNameModuleHash.insert(data.fileName, data.module);
}
@@ -2876,7 +2869,7 @@ void CdbEngine::attemptBreakpointSynchronization()
if (debugBreakpoints)
qDebug("attemptBreakpointSynchronizationI %dms accessible=%d, %s %d breakpoints, changed=%d",
- elapsedLogTime(), m_accessible, stateName(state()), ids.size(), changed);
+ elapsedLogTime(), m_accessible, stateName(state()), bps.size(), changed);
if (!changed)
return;
@@ -2891,8 +2884,9 @@ void CdbEngine::attemptBreakpointSynchronization()
// handleBreakPoints will the complete that information and set it on the break handler.
bool addedChanged = false;
QScopedPointer<BreakpointCorrectionContext> lineCorrection;
- foreach (BreakpointModelId id, ids) {
- BreakpointParameters parameters = handler->breakpointData(id);
+ foreach (Breakpoint bp, bps) {
+ BreakpointParameters parameters = bp.parameters();
+ BreakpointModelId id = bp.id();
BreakpointResponse response;
response.fromParameters(parameters);
response.id = BreakpointResponseId(id.majorPart(), id.minorPart());
@@ -2902,7 +2896,7 @@ void CdbEngine::attemptBreakpointSynchronization()
if (it != m_fileNameModuleHash.constEnd())
parameters.module = it.value();
}
- switch (handler->state(id)) {
+ switch (bp.state()) {
case BreakpointInsertRequested:
if (!m_autoBreakPointCorrection
&& parameters.type == BreakpointByFileAndLine
@@ -2921,29 +2915,29 @@ void CdbEngine::attemptBreakpointSynchronization()
}
if (!parameters.enabled)
postCommand("bd " + QByteArray::number(breakPointIdToCdbId(id)), 0);
- handler->notifyBreakpointInsertProceeding(id);
- handler->notifyBreakpointInsertOk(id);
+ bp.notifyBreakpointInsertProceeding();
+ bp.notifyBreakpointInsertOk();
m_pendingBreakpointMap.insert(id, response);
addedChanged = true;
// Ensure enabled/disabled is correct in handler and line number is there.
- handler->setResponse(id, response);
+ bp.setResponse(response);
if (debugBreakpoints)
qDebug("Adding %d %s\n", id.toInternalId(),
qPrintable(response.toString()));
break;
case BreakpointChangeRequested:
- handler->notifyBreakpointChangeProceeding(id);
+ bp.notifyBreakpointChangeProceeding();
if (debugBreakpoints)
qDebug("Changing %d:\n %s\nTo %s\n", id.toInternalId(),
- qPrintable(handler->response(id).toString()),
+ qPrintable(bp.response().toString()),
qPrintable(parameters.toString()));
- if (parameters.enabled != handler->response(id).enabled) {
+ if (parameters.enabled != bp.response().enabled) {
// Change enabled/disabled breakpoints without triggering update.
postCommand((parameters.enabled ? "be " : "bd ")
+ QByteArray::number(breakPointIdToCdbId(id)), 0);
response.pending = false;
response.enabled = parameters.enabled;
- handler->setResponse(id, response);
+ bp.setResponse(response);
} else {
// Delete and re-add, triggering update
addedChanged = true;
@@ -2953,12 +2947,12 @@ void CdbEngine::attemptBreakpointSynchronization()
&CdbEngine::handleBreakInsert);
m_pendingBreakpointMap.insert(id, response);
}
- handler->notifyBreakpointChangeOk(id);
+ bp.notifyBreakpointChangeOk();
break;
case BreakpointRemoveRequested:
postCommand(cdbClearBreakpointCommand(id), 0);
- handler->notifyBreakpointRemoveProceeding(id);
- handler->notifyBreakpointRemoveOk(id);
+ bp.notifyBreakpointRemoveProceeding();
+ bp.notifyBreakpointRemoveOk();
m_pendingBreakpointMap.remove(id);
break;
default:
@@ -2991,7 +2985,7 @@ CdbEngine::NormalizedSourceFileName CdbEngine::sourceMapNormalizeFileNameFromDeb
const QString fileName = cdbSourcePathMapping(QDir::toNativeSeparators(f), m_sourcePathMappings,
DebuggerToSource);
// Up/lower case normalization according to Windows.
- const QString normalized = Utils::FileUtils::normalizePathName(fileName);
+ const QString normalized = FileUtils::normalizePathName(fileName);
if (debugSourceMapping)
qDebug(" sourceMapNormalizeFileNameFromDebugger %s->%s", qPrintable(fileName), qPrintable(normalized));
// Check if it really exists, that is normalize worked and QFileInfo confirms it.
@@ -3301,12 +3295,12 @@ void CdbEngine::handleBreakPoints(const GdbMi &value)
reportedResponse.pending,
qPrintable(reportedResponse.toString()));
if (reportedResponse.id.isValid() && !reportedResponse.pending) {
- const BreakpointModelId mid = handler->findBreakpointByResponseId(reportedResponse.id);
- if (!mid.isValid() && reportedResponse.type == BreakpointByFunction)
+ Breakpoint bp = handler->findBreakpointByResponseId(reportedResponse.id);
+ if (!bp && reportedResponse.type == BreakpointByFunction)
continue; // Breakpoints from options, CrtDbgReport() and others.
- QTC_ASSERT(mid.isValid(), continue);
- const PendingBreakPointMap::iterator it = m_pendingBreakpointMap.find(mid);
- const PendingBreakPointMap::iterator subIt = m_pendingSubBreakpointMap.find(
+ QTC_ASSERT(bp, continue);
+ const auto it = m_pendingBreakpointMap.find(bp.id());
+ const auto subIt = m_pendingSubBreakpointMap.find(
BreakpointModelId(reportedResponse.id.majorPart(),
reportedResponse.id.minorPart()));
if (it != m_pendingBreakpointMap.end() || subIt != m_pendingSubBreakpointMap.end()) {
@@ -3321,16 +3315,16 @@ void CdbEngine::handleBreakPoints(const GdbMi &value)
currentResponse.enabled = reportedResponse.enabled;
currentResponse.fileName = reportedResponse.fileName;
currentResponse.lineNumber = reportedResponse.lineNumber;
- formatCdbBreakPointResponse(mid, currentResponse, str);
+ formatCdbBreakPointResponse(bp.id(), currentResponse, str);
if (debugBreakpoints)
qDebug(" Setting for %d: %s\n", currentResponse.id.majorPart(),
qPrintable(currentResponse.toString()));
if (it != m_pendingBreakpointMap.end()) {
- handler->setResponse(mid, currentResponse);
+ bp.setResponse(currentResponse);
m_pendingBreakpointMap.erase(it);
}
if (subIt != m_pendingSubBreakpointMap.end()) {
- handler->insertSubBreakpoint(mid, currentResponse);
+ bp.insertSubBreakpoint(currentResponse);
m_pendingSubBreakpointMap.erase(subIt);
}
}
diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h
index cf2cb6ced6..ce7f263e63 100644
--- a/src/plugins/debugger/cdb/cdbengine.h
+++ b/src/plugins/debugger/cdb/cdbengine.h
@@ -32,6 +32,7 @@
#define DEBUGGER_CDBENGINE_H
#include <debugger/debuggerengine.h>
+#include <debugger/breakhandler.h>
#include <projectexplorer/devicesupport/idevice.h>
@@ -52,7 +53,7 @@ struct MemoryViewCookie;
class ByteArrayInputStream;
class GdbMi;
-class CdbEngine : public Debugger::DebuggerEngine
+class CdbEngine : public DebuggerEngine
{
Q_OBJECT
@@ -90,7 +91,7 @@ public:
const WatchUpdateFlags & flags = WatchUpdateFlags());
virtual bool hasCapability(unsigned cap) const;
virtual void watchPoint(const QPoint &);
- virtual void setRegisterValue(int regnr, const QString &value);
+ virtual void setRegisterValue(const QByteArray &name, const QString &value);
virtual void executeStep();
virtual void executeStepOut();
@@ -111,7 +112,7 @@ public:
virtual void selectThread(ThreadId threadId);
virtual bool stateAcceptsBreakpointChanges() const;
- virtual bool acceptsBreakpoint(BreakpointModelId id) const;
+ virtual bool acceptsBreakpoint(Breakpoint bp) const;
virtual void attemptBreakpointSynchronization();
virtual void fetchDisassembler(DisassemblerAgent *agent);
diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.cpp b/src/plugins/debugger/cdb/cdbparsehelpers.cpp
index 75b2870a11..57c19eb5ee 100644
--- a/src/plugins/debugger/cdb/cdbparsehelpers.cpp
+++ b/src/plugins/debugger/cdb/cdbparsehelpers.cpp
@@ -37,6 +37,7 @@
#include <debugger/shared/hostutils.h>
#include <debugger/threaddata.h>
+#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <QDir>
@@ -87,7 +88,7 @@ static inline QString cdbBreakPointFileName(const BreakpointParameters &bp,
if (bp.fileName.isEmpty())
return bp.fileName;
if (bp.pathUsage == BreakpointUseShortPath)
- return QFileInfo(bp.fileName).fileName();
+ return Utils::FileName::fromString(bp.fileName).fileName();
return cdbSourcePathMapping(QDir::toNativeSeparators(bp.fileName), sourcePathMapping, SourceToDebugger);
}
diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp
index 6aef1913e6..31f7e5c161 100644
--- a/src/plugins/debugger/commonoptionspage.cpp
+++ b/src/plugins/debugger/commonoptionspage.cpp
@@ -230,8 +230,8 @@ CommonOptionsPageWidget::CommonOptionsPageWidget
Utils::SavedAction *registerAction = action(RegisterForPostMortem);
m_group->insert(registerAction,
checkBoxRegisterForPostMortem);
- connect(registerAction, SIGNAL(toggled(bool)),
- checkBoxRegisterForPostMortem, SLOT(setChecked(bool)));
+ connect(registerAction, &QAction::toggled,
+ checkBoxRegisterForPostMortem, &QAbstractButton::setChecked);
} else {
checkBoxRegisterForPostMortem->setVisible(false);
}
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index edf9a72709..83e790c042 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -15,7 +15,6 @@ CONFIG += exceptions
HEADERS += \
breakhandler.h \
breakpoint.h \
- breakpointmarker.h \
breakwindow.h \
commonoptionspage.h \
debugger_global.h \
@@ -25,7 +24,6 @@ HEADERS += \
debuggerinternalconstants.h \
debuggeritem.h \
debuggeritemmanager.h \
- debuggeritemmodel.h \
debuggerdialogs.h \
debuggerengine.h \
debuggermainwindow.h \
@@ -58,6 +56,7 @@ HEADERS += \
stackframe.h \
stackhandler.h \
stackwindow.h \
+ terminal.h \
threadswindow.h \
watchhandler.h \
watchutils.h \
@@ -76,7 +75,6 @@ HEADERS += \
SOURCES += \
breakhandler.cpp \
breakpoint.cpp \
- breakpointmarker.cpp \
breakwindow.cpp \
commonoptionspage.cpp \
debuggeractions.cpp \
@@ -84,7 +82,6 @@ SOURCES += \
debuggerengine.cpp \
debuggeritem.cpp \
debuggeritemmanager.cpp \
- debuggeritemmodel.cpp \
debuggermainwindow.cpp \
debuggerplugin.cpp \
debuggerprotocol.cpp \
@@ -114,6 +111,7 @@ SOURCES += \
stackwindow.cpp \
threadshandler.cpp \
threadswindow.cpp \
+ terminal.cpp \
watchdata.cpp \
watchhandler.cpp \
watchutils.cpp \
diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs
index e03c038beb..7001f560b3 100644
--- a/src/plugins/debugger/debugger.qbs
+++ b/src/plugins/debugger/debugger.qbs
@@ -28,7 +28,6 @@ QtcPlugin {
files: [
"breakhandler.cpp", "breakhandler.h",
"breakpoint.cpp", "breakpoint.h",
- "breakpointmarker.cpp", "breakpointmarker.h",
"breakwindow.cpp", "breakwindow.h",
"commonoptionspage.cpp", "commonoptionspage.h",
"debugger.qrc",
@@ -41,7 +40,6 @@ QtcPlugin {
"debuggerinternalconstants.h",
"debuggeritem.cpp", "debuggeritem.h",
"debuggeritemmanager.cpp", "debuggeritemmanager.h",
- "debuggeritemmodel.cpp", "debuggeritemmodel.h",
"debuggerkitconfigwidget.cpp", "debuggerkitconfigwidget.h",
"debuggerkitinformation.cpp", "debuggerkitinformation.h",
"debuggermainwindow.cpp", "debuggermainwindow.h",
@@ -77,6 +75,7 @@ QtcPlugin {
"stackframe.cpp", "stackframe.h",
"stackhandler.cpp", "stackhandler.h",
"stackwindow.cpp", "stackwindow.h",
+ "terminal.cpp", "terminal.h",
"threaddata.h",
"threadshandler.cpp", "threadshandler.h",
"threadswindow.cpp", "threadswindow.h",
diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index 234c44e434..e58367e479 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -34,6 +34,7 @@
#include "registerpostmortemaction.h"
#endif
+#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <utils/savedaction.h>
#include <utils/qtcassert.h>
@@ -184,6 +185,18 @@ DebuggerSettings::DebuggerSettings()
insertItem(OperateByInstruction, item);
item = new SavedAction(this);
+ item->setText(tr("Native Mixed Mode"));
+ item->setCheckable(true);
+ item->setDefaultValue(true);
+ item->setIcon(QIcon(QLatin1String(Core::Constants::ICON_LINK)));
+ item->setToolTip(tr("This switches the debugger to native-mixed "
+ "operation mode. In this mode, stepping and data display will "
+ "be handled by the native debugger backend (GDB, LLDB or CDB) "
+ "for C++, QML and JS sources."));
+ item->setIconVisibleInMenu(false);
+ insertItem(OperateNativeMixed, item);
+
+ item = new SavedAction(this);
item->setText(tr("Dereference Pointers Automatically"));
item->setCheckable(true);
item->setDefaultValue(true);
diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h
index 99ffa70b50..2b3202fcd5 100644
--- a/src/plugins/debugger/debuggeractions.h
+++ b/src/plugins/debugger/debuggeractions.h
@@ -99,6 +99,7 @@ enum DebuggerActionCode
LogTimeStamps,
VerboseLog,
OperateByInstruction,
+ OperateNativeMixed,
CloseSourceBuffersOnExit,
CloseMemoryBuffersOnExit,
SwitchModeOnExit,
diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h
index 0b1270225b..0bfb5f749b 100644
--- a/src/plugins/debugger/debuggerconstants.h
+++ b/src/plugins/debugger/debuggerconstants.h
@@ -61,6 +61,7 @@ const char NEXT[] = "Debugger.NextLine";
const char REVERSE[] = "Debugger.ReverseDirection";
const char RESET[] = "Debugger.Reset";
const char OPERATE_BY_INSTRUCTION[] = "Debugger.OperateByInstruction";
+const char OPERATE_NATIVE_MIXED[] = "Debugger.OperateNativeMixed";
const char QML_SHOW_APP_ON_TOP[] = "Debugger.QmlShowAppOnTop";
const char QML_UPDATE_ON_SAVE[] = "Debugger.QmlUpdateOnSave";
const char QML_SELECTTOOL[] = "Debugger.QmlSelectTool";
@@ -163,7 +164,8 @@ enum DebuggerCapabilities
ShowModuleSectionsCapability = 0x200000,
WatchComplexExpressionsCapability = 0x400000, // Used to filter out challenges for cdb.
AdditionalQmlStackCapability = 0x800000, // C++ debugger engine is able to retrieve QML stack as well.
- ResetInferiorCapability = 0x1000000 //!< restart program while debugging
+ ResetInferiorCapability = 0x1000000, //!< restart program while debugging
+ NativeMixedCapability = 0x2000000
};
enum LogChannel
diff --git a/src/plugins/debugger/debuggercore.h b/src/plugins/debugger/debuggercore.h
index 84b29f7ab6..d481867062 100644
--- a/src/plugins/debugger/debuggercore.h
+++ b/src/plugins/debugger/debuggercore.h
@@ -50,12 +50,10 @@ namespace CPlusPlus { class Snapshot; }
namespace Utils { class SavedAction; }
namespace Debugger {
-
-class DebuggerEngine;
-
namespace Internal {
class BreakHandler;
+class DebuggerEngine;
class Symbol;
class Section;
class GlobalDebuggerOptions;
@@ -112,6 +110,9 @@ DebuggerEngine *currentEngine();
QMessageBox *showMessageBox(int icon, const QString &title,
const QString &text, int buttons = 0);
+bool isNativeMixedActive();
+bool isNativeMixedEnabled();
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index b6e9f937c3..fd4137f78c 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -105,19 +105,19 @@ namespace Internal {
///////////////////////////////////////////////////////////////////////
DebuggerKitChooser::DebuggerKitChooser(Mode mode, QWidget *parent)
- : ProjectExplorer::KitChooser(parent)
- , m_hostAbi(ProjectExplorer::Abi::hostAbi())
+ : KitChooser(parent)
+ , m_hostAbi(Abi::hostAbi())
, m_mode(mode)
{
}
// Match valid debuggers and restrict local debugging to compatible toolchains.
-bool DebuggerKitChooser::kitMatches(const ProjectExplorer::Kit *k) const
+bool DebuggerKitChooser::kitMatches(const Kit *k) const
{
if (!DebuggerKitInformation::isValidDebugger(k))
return false;
if (m_mode == LocalDebugging) {
- const ProjectExplorer::ToolChain *tc = ToolChainKitInformation::toolChain(k);
+ const ToolChain *tc = ToolChainKitInformation::toolChain(k);
return tc && tc->targetAbi().os() == m_hostAbi.os();
}
return true;
@@ -181,7 +181,7 @@ QString StartApplicationParameters::displayName() const
{
const int maxLength = 60;
- QString name = QFileInfo(localExecutable).fileName() + QLatin1Char(' ') + processArgs;
+ QString name = FileName::fromString(localExecutable).fileName() + QLatin1Char(' ') + processArgs;
if (name.size() > 60) {
int index = name.lastIndexOf(QLatin1Char(' '), maxLength);
if (index == -1)
@@ -247,7 +247,7 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
d->serverAddressEdit = new QLineEdit(this);
d->localExecutablePathChooser = new PathChooser(this);
- d->localExecutablePathChooser->setExpectedKind(PathChooser::File);
+ d->localExecutablePathChooser->setExpectedKind(PathChooser::ExistingCommand);
d->localExecutablePathChooser->setPromptDialogTitle(tr("Select Executable"));
d->localExecutablePathChooser->setHistoryCompleter(QLatin1String("LocalExecutable"));
@@ -282,11 +282,11 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
"If empty, $SYSROOT/usr/lib/debug will be chosen."));
d->debuginfoPathChooser->setHistoryCompleter(QLatin1String("Debugger.DebugLocation.History"));
- QFrame *line = new QFrame(this);
+ auto line = new QFrame(this);
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
- QFrame *line2 = new QFrame(this);
+ auto line2 = new QFrame(this);
line2->setFrameShape(QFrame::HLine);
line2->setFrameShadow(QFrame::Sunken);
@@ -296,7 +296,7 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
d->buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
d->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
- QFormLayout *formLayout = new QFormLayout();
+ auto formLayout = new QFormLayout();
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout->addRow(tr("&Kit:"), d->kitChooser);
formLayout->addRow(d->serverPortLabel, d->serverPortSpinBox);
@@ -311,17 +311,18 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
formLayout->addRow(line2);
formLayout->addRow(tr("&Recent:"), d->historyComboBox);
- QVBoxLayout *verticalLayout = new QVBoxLayout(this);
+ auto verticalLayout = new QVBoxLayout(this);
verticalLayout->addLayout(formLayout);
verticalLayout->addStretch();
verticalLayout->addWidget(line);
verticalLayout->addWidget(d->buttonBox);
- connect(d->localExecutablePathChooser, SIGNAL(changed(QString)), SLOT(updateState()));
- connect(d->buttonBox, SIGNAL(accepted()), SLOT(accept()));
- connect(d->buttonBox, SIGNAL(rejected()), SLOT(reject()));
- connect(d->historyComboBox, SIGNAL(currentIndexChanged(int)),
- SLOT(historyIndexChanged(int)));
+ connect(d->localExecutablePathChooser, &PathChooser::changed,
+ this, &StartApplicationDialog::updateState);
+ connect(d->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(d->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+ connect(d->historyComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ this, &StartApplicationDialog::historyIndexChanged);
updateState();
}
@@ -493,20 +494,20 @@ AttachToQmlPortDialog::AttachToQmlPortDialog(QWidget *parent)
d->portSpinBox->setMaximum(65535);
d->portSpinBox->setValue(3768);
- QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
+ auto buttonBox = new QDialogButtonBox(this);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
- QFormLayout *formLayout = new QFormLayout();
+ auto formLayout = new QFormLayout();
formLayout->addRow(tr("Kit:"), d->kitChooser);
formLayout->addRow(tr("&Port:"), d->portSpinBox);
- QVBoxLayout *verticalLayout = new QVBoxLayout(this);
+ auto verticalLayout = new QVBoxLayout(this);
verticalLayout->addLayout(formLayout);
verticalLayout->addWidget(buttonBox);
- connect(buttonBox, SIGNAL(accepted()), SLOT(accept()));
- connect(buttonBox, SIGNAL(rejected()), SLOT(reject()));
+ connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
AttachToQmlPortDialog::~AttachToQmlPortDialog()
@@ -567,34 +568,38 @@ StartRemoteCdbDialog::StartRemoteCdbDialog(QWidget *parent) :
setWindowTitle(tr("Start a CDB Remote Session"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- QGroupBox *groupBox = new QGroupBox;
+ auto groupBox = new QGroupBox;
- QLabel *helpLabel = new QLabel(cdbRemoteHelp());
+ auto helpLabel = new QLabel(cdbRemoteHelp());
helpLabel->setWordWrap(true);
helpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- QLabel *label = new QLabel(tr("&Connection:"));
+ auto label = new QLabel(tr("&Connection:"));
label->setBuddy(m_lineEdit);
m_lineEdit->setMinimumWidth(400);
- QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
+ auto box = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
- QFormLayout *formLayout = new QFormLayout;
+ auto formLayout = new QFormLayout;
formLayout->addRow(helpLabel);
formLayout->addRow(label, m_lineEdit);
groupBox->setLayout(formLayout);
- QVBoxLayout *vLayout = new QVBoxLayout(this);
+ auto vLayout = new QVBoxLayout(this);
vLayout->addWidget(groupBox);
vLayout->addWidget(box);
m_okButton = box->button(QDialogButtonBox::Ok);
m_okButton->setEnabled(false);
- connect(m_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));
- connect(m_lineEdit, SIGNAL(returnPressed()), m_okButton, SLOT(animateClick()));
- connect(box, SIGNAL(accepted()), this, SLOT(accept()));
- connect(box, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(m_lineEdit, &QLineEdit::textChanged,
+ this, &StartRemoteCdbDialog::textChanged);
+ connect(m_lineEdit, &QLineEdit::returnPressed,
+ [this] { m_okButton->animateClick(); });
+ connect(box, &QDialogButtonBox::accepted,
+ this, &StartRemoteCdbDialog::accept);
+ connect(box, &QDialogButtonBox::rejected,
+ this, &QDialog::reject);
}
void StartRemoteCdbDialog::accept()
@@ -636,18 +641,20 @@ AddressDialog::AddressDialog(QWidget *parent) :
{
setWindowTitle(tr("Select Start Address"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- QHBoxLayout *hLayout = new QHBoxLayout;
+
+ auto hLayout = new QHBoxLayout;
hLayout->addWidget(new QLabel(tr("Enter an address:") + QLatin1Char(' ')));
hLayout->addWidget(m_lineEdit);
- QVBoxLayout *vLayout = new QVBoxLayout;
+
+ auto vLayout = new QVBoxLayout;
vLayout->addLayout(hLayout);
vLayout->addWidget(m_box);
setLayout(vLayout);
- connect(m_box, SIGNAL(accepted()), this, SLOT(accept()));
- connect(m_box, SIGNAL(rejected()), this, SLOT(reject()));
- connect(m_lineEdit, SIGNAL(returnPressed()), this, SLOT(accept()));
- connect(m_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
+ connect(m_box, &QDialogButtonBox::accepted, this, &AddressDialog::accept);
+ connect(m_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
+ connect(m_lineEdit, &QLineEdit::returnPressed, this, &AddressDialog::accept);
+ connect(m_lineEdit, &QLineEdit::textChanged, this, &AddressDialog::textChanged);
setOkButtonEnabled(false);
}
@@ -732,20 +739,20 @@ StartRemoteEngineDialog::StartRemoteEngineDialog(QWidget *parent)
d->buttonBox = new QDialogButtonBox(this);
d->buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
- QFormLayout *formLayout = new QFormLayout();
+ auto formLayout = new QFormLayout();
formLayout->addRow(tr("&Host:"), d->host);
formLayout->addRow(tr("&Username:"), d->username);
formLayout->addRow(tr("&Password:"), d->password);
formLayout->addRow(tr("&Engine path:"), d->enginePath);
formLayout->addRow(tr("&Inferior path:"), d->inferiorPath);
- QVBoxLayout *verticalLayout = new QVBoxLayout(this);
+ auto verticalLayout = new QVBoxLayout(this);
verticalLayout->addLayout(formLayout);
verticalLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
verticalLayout->addWidget(d->buttonBox);
- connect(d->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
- connect(d->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(d->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(d->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
StartRemoteEngineDialog::~StartRemoteEngineDialog()
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index a0b2d2d6d7..d79bee0df0 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -45,6 +45,7 @@
#include "registerhandler.h"
#include "sourcefileshandler.h"
#include "stackhandler.h"
+#include "terminal.h"
#include "threadshandler.h"
#include "watchhandler.h"
#include <debugger/shared/peutils.h>
@@ -52,6 +53,7 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icore.h>
+#include <coreplugin/messagebox.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
@@ -72,8 +74,6 @@
#include <QFileInfo>
#include <QDir>
-#include <QMessageBox>
-
using namespace Core;
using namespace Debugger::Internal;
using namespace ProjectExplorer;
@@ -100,18 +100,6 @@ const char PrefixDebugExecutable[] = "DebuggedExecutable";
namespace Debugger {
-Internal::Location::Location(const StackFrame &frame, bool marker)
-{
- init();
- m_fileName = frame.file;
- m_lineNumber = frame.line;
- m_needsMarker = marker;
- m_functionName = frame.function;
- m_hasDebugInfo = frame.isUsable();
- m_address = frame.address;
- m_from = frame.from;
-}
-
QDebug operator<<(QDebug d, DebuggerState state)
{
//return d << DebuggerEngine::stateName(state) << '(' << int(state) << ')';
@@ -134,6 +122,20 @@ QDebug operator<<(QDebug str, const DebuggerStartParameters &sp)
return str;
}
+namespace Internal {
+
+Location::Location(const StackFrame &frame, bool marker)
+{
+ init();
+ m_fileName = frame.file;
+ m_lineNumber = frame.line;
+ m_needsMarker = marker;
+ m_functionName = frame.function;
+ m_hasDebugInfo = frame.isUsable();
+ m_address = frame.address;
+ m_from = frame.from;
+}
+
//////////////////////////////////////////////////////////////////////
//
@@ -175,9 +177,12 @@ public:
m_memoryAgent(engine),
m_isStateDebugging(false)
{
- connect(&m_locationTimer, SIGNAL(timeout()), SLOT(resetLocation()));
- connect(action(IntelFlavor), SIGNAL(valueChanged(QVariant)),
- SLOT(reloadDisassembly()));
+ connect(&m_locationTimer, &QTimer::timeout,
+ this, &DebuggerEnginePrivate::resetLocation);
+ connect(action(IntelFlavor), &Utils::SavedAction::valueChanged,
+ this, &DebuggerEnginePrivate::reloadDisassembly);
+ connect(action(OperateNativeMixed), &QAction::triggered,
+ engine, &DebuggerEngine::reloadFullStack);
Utils::globalMacroExpander()->registerFileVariables(PrefixDebugExecutable,
tr("Debugged executable"),
@@ -298,6 +303,7 @@ public:
// State of RemoteSetup signal/slots.
RemoteSetupState m_remoteSetupState;
+ Terminal m_terminal;
qint64 m_inferiorPid;
ModulesHandler m_modulesHandler;
@@ -310,7 +316,7 @@ public:
DisassemblerAgent m_disassemblerAgent;
MemoryAgent m_memoryAgent;
- QScopedPointer<TextEditor::TextMark> m_locationMark;
+ QScopedPointer<TextMark> m_locationMark;
QTimer m_locationTimer;
bool m_isStateDebugging;
@@ -476,9 +482,9 @@ void DebuggerEngine::changeMemory(MemoryAgent *, QObject *,
Q_UNUSED(data);
}
-void DebuggerEngine::setRegisterValue(int regnr, const QString &value)
+void DebuggerEngine::setRegisterValue(const QByteArray &name, const QString &value)
{
- Q_UNUSED(regnr);
+ Q_UNUSED(name);
Q_UNUSED(value);
}
@@ -520,7 +526,7 @@ void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
d->m_progress.setProgressRange(0, 1000);
FutureProgress *fp = ProgressManager::addTask(d->m_progress.future(),
tr("Launching Debugger"), "Debugger.Launcher");
- connect(fp, SIGNAL(canceled()), this, SLOT(quitDebugger()));
+ connect(fp, &FutureProgress::canceled, this, &DebuggerEngine::quitDebugger);
fp->setKeepOnFinish(FutureProgress::HideOnFinish);
d->m_progress.reportStarted();
@@ -541,6 +547,20 @@ void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
d->m_lastGoodState = DebuggerNotReady;
d->m_targetState = DebuggerNotReady;
d->m_progress.setProgressValue(200);
+
+ d->m_terminal.setup();
+ if (d->m_terminal.isUsable()) {
+ connect(&d->m_terminal, &Terminal::stdOutReady, [this, runControl](const QString &msg) {
+ runControl->appendMessage(msg, Utils::StdOutFormatSameLine);
+ });
+ connect(&d->m_terminal, &Terminal::stdErrReady, [this, runControl](const QString &msg) {
+ runControl->appendMessage(msg, Utils::StdErrFormatSameLine);
+ });
+ connect(&d->m_terminal, &Terminal::error, [this, runControl](const QString &msg) {
+ runControl->appendMessage(msg, Utils::ErrorMessageFormat);
+ });
+ }
+
d->queueSetupEngine();
}
@@ -577,9 +597,9 @@ void DebuggerEngine::gotoLocation(const Location &loc)
editor->document()->setProperty(Constants::OPENED_BY_DEBUGGER, true);
if (loc.needsMarker()) {
- d->m_locationMark.reset(new TextEditor::TextMark(file, line));
+ d->m_locationMark.reset(new TextMark(file, line));
d->m_locationMark->setIcon(Internal::locationMarkIcon());
- d->m_locationMark->setPriority(TextEditor::TextMark::HighPriority);
+ d->m_locationMark->setPriority(TextMark::HighPriority);
}
//qDebug() << "MEMORY: " << d->m_memoryAgent.hasVisibleEditor();
@@ -782,6 +802,7 @@ void DebuggerEngine::notifyInferiorSetupOk()
#ifdef WITH_BENCHMARK
CALLGRIND_START_INSTRUMENTATION;
#endif
+ aboutToNotifyInferiorSetupOk();
showMessage(_("NOTE: INFERIOR SETUP OK"));
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
setState(InferiorSetupOk);
@@ -1204,9 +1225,8 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
if (state == DebuggerFinished) {
// Give up ownership on claimed breakpoints.
- BreakHandler *handler = breakHandler();
- foreach (BreakpointModelId id, handler->engineBreakpointIds(this))
- handler->notifyBreakpointReleased(id);
+ foreach (Breakpoint bp, breakHandler()->engineBreakpoints(this))
+ bp.notifyBreakpointReleased();
DebuggerToolTipManager::deregisterEngine(this);
}
@@ -1382,7 +1402,12 @@ DebuggerRunControl *DebuggerEngine::runControl() const
return d->runControl();
}
-bool DebuggerEngine::setToolTipExpression(TextEditor::TextEditorWidget *,
+Terminal *DebuggerEngine::terminal() const
+{
+ return &d->m_terminal;
+}
+
+bool DebuggerEngine::setToolTipExpression(TextEditorWidget *,
const DebuggerToolTipContext &)
{
return false;
@@ -1497,36 +1522,36 @@ void DebuggerEngine::attemptBreakpointSynchronization()
BreakHandler *handler = breakHandler();
- foreach (BreakpointModelId id, handler->unclaimedBreakpointIds()) {
+ foreach (Breakpoint bp, handler->unclaimedBreakpoints()) {
// Take ownership of the breakpoint. Requests insertion.
- if (acceptsBreakpoint(id)) {
+ if (acceptsBreakpoint(bp)) {
showMessage(_("TAKING OWNERSHIP OF BREAKPOINT %1 IN STATE %2")
- .arg(id.toString()).arg(handler->state(id)));
- handler->setEngine(id, this);
+ .arg(bp.id().toString()).arg(bp.state()));
+ bp.setEngine(this);
} else {
showMessage(_("BREAKPOINT %1 IN STATE %2 IS NOT ACCEPTABLE")
- .arg(id.toString()).arg(handler->state(id)));
+ .arg(bp.id().toString()).arg(bp.state()));
}
}
bool done = true;
- foreach (BreakpointModelId id, handler->engineBreakpointIds(this)) {
- switch (handler->state(id)) {
+ foreach (Breakpoint bp, handler->engineBreakpoints(this)) {
+ switch (bp.state()) {
case BreakpointNew:
// Should not happen once claimed.
QTC_CHECK(false);
continue;
case BreakpointInsertRequested:
done = false;
- insertBreakpoint(id);
+ insertBreakpoint(bp);
continue;
case BreakpointChangeRequested:
done = false;
- changeBreakpoint(id);
+ changeBreakpoint(bp);
continue;
case BreakpointRemoveRequested:
done = false;
- removeBreakpoint(id);
+ removeBreakpoint(bp);
continue;
case BreakpointChangeProceeding:
case BreakpointInsertProceeding:
@@ -1543,7 +1568,7 @@ void DebuggerEngine::attemptBreakpointSynchronization()
QTC_CHECK(false);
continue;
}
- QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << id << state());
+ QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << bp.id() << state());
}
if (done) {
@@ -1554,24 +1579,33 @@ void DebuggerEngine::attemptBreakpointSynchronization()
}
}
-void DebuggerEngine::insertBreakpoint(BreakpointModelId id)
+bool DebuggerEngine::acceptsBreakpoint(Breakpoint bp) const
+{
+ Q_UNUSED(bp);
+ return false;
+}
+
+void DebuggerEngine::insertBreakpoint(Breakpoint bp)
{
- BreakpointState state = breakHandler()->state(id);
- QTC_ASSERT(state == BreakpointInsertRequested, qDebug() << id << this << state);
+ BreakpointState state = bp.state();
+ QTC_ASSERT(state == BreakpointInsertRequested,
+ qDebug() << bp.id() << this << state);
QTC_CHECK(false);
}
-void DebuggerEngine::removeBreakpoint(BreakpointModelId id)
+void DebuggerEngine::removeBreakpoint(Breakpoint bp)
{
- BreakpointState state = breakHandler()->state(id);
- QTC_ASSERT(state == BreakpointRemoveRequested, qDebug() << id << this << state);
+ BreakpointState state = bp.state();
+ QTC_ASSERT(state == BreakpointRemoveRequested,
+ qDebug() << bp.id() << this << state);
QTC_CHECK(false);
}
-void DebuggerEngine::changeBreakpoint(BreakpointModelId id)
+void DebuggerEngine::changeBreakpoint(Breakpoint bp)
{
- BreakpointState state = breakHandler()->state(id);
- QTC_ASSERT(state == BreakpointChangeRequested, qDebug() << id << this << state);
+ BreakpointState state = bp.state();
+ QTC_ASSERT(state == BreakpointChangeRequested,
+ qDebug() << bp.id() << this << state);
QTC_CHECK(false);
}
@@ -1650,56 +1684,6 @@ bool DebuggerEngine::isDying() const
return targetState() == DebuggerFinished;
}
-QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointModelId id,
- const int number, const QString &expr)
-{
- return id
- ? tr("Data breakpoint %1 (%2) at %3 triggered.")
- .arg(id.toString()).arg(number).arg(expr)
- : tr("Internal data breakpoint %1 at %2 triggered.")
- .arg(number).arg(expr);
-}
-
-QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointModelId id,
- const int number, const QString &expr, const QString &threadId)
-{
- return id
- ? tr("Data breakpoint %1 (%2) at %3 in thread %4 triggered.")
- .arg(id.toString()).arg(number).arg(expr).arg(threadId)
- : tr("Internal data breakpoint %1 at %2 in thread %3 triggered.")
- .arg(number).arg(expr).arg(threadId);
-}
-
-QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointModelId id,
- const int number, quint64 address)
-{
- return id
- ? tr("Data breakpoint %1 (%2) at 0x%3 triggered.")
- .arg(id.toString()).arg(number).arg(address, 0, 16)
- : tr("Internal data breakpoint %1 at 0x%2 triggered.")
- .arg(number).arg(address, 0, 16);
-}
-
-QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointModelId id,
- const int number, quint64 address, const QString &threadId)
-{
- return id
- ? tr("Data breakpoint %1 (%2) at 0x%3 in thread %4 triggered.")
- .arg(id.toString()).arg(number).arg(address, 0, 16).arg(threadId)
- : tr("Internal data breakpoint %1 at 0x%2 in thread %3 triggered.")
- .arg(id.toString()).arg(number).arg(address, 0, 16).arg(threadId);
-}
-
-QString DebuggerEngine::msgBreakpointTriggered(BreakpointModelId id,
- const int number, const QString &threadId)
-{
- return id
- ? tr("Stopped at breakpoint %1 (%2) in thread %3.")
- .arg(id.toString()).arg(number).arg(threadId)
- : tr("Stopped at internal breakpoint %1 in thread %2.")
- .arg(number).arg(threadId);
-}
-
QString DebuggerEngine::msgStopped(const QString &reason)
{
return reason.isEmpty() ? tr("Stopped.") : tr("Stopped: \"%1\"").arg(reason);
@@ -1733,7 +1717,7 @@ void DebuggerEngine::showStoppedBySignalMessageBox(QString meaning, QString name
"<table><tr><td>Signal name : </td><td>%1</td></tr>"
"<tr><td>Signal meaning : </td><td>%2</td></tr></table>")
.arg(name, meaning);
- showMessageBox(QMessageBox::Information, tr("Signal received"), msg);
+ AsynchronousMessageBox::information(tr("Signal received"), msg);
}
void DebuggerEngine::showStoppedByExceptionMessageBox(const QString &description)
@@ -1741,14 +1725,12 @@ void DebuggerEngine::showStoppedByExceptionMessageBox(const QString &description
const QString msg =
tr("<p>The inferior stopped because it triggered an exception.<p>%1").
arg(description);
- showMessageBox(QMessageBox::Information, tr("Exception Triggered"), msg);
+ AsynchronousMessageBox::information(tr("Exception Triggered"), msg);
}
-void DebuggerEngine::openMemoryView(quint64 startAddr, unsigned flags,
- const QList<MemoryMarkup> &ml, const QPoint &pos,
- const QString &title, QWidget *parent)
+void DebuggerEngine::openMemoryView(const MemoryViewSetupData &data)
{
- d->m_memoryAgent.createBinEditor(startAddr, flags, ml, pos, title, parent);
+ d->m_memoryAgent.createBinEditor(data);
}
void DebuggerEngine::updateMemoryViews()
@@ -1783,7 +1765,7 @@ void DebuggerEngine::validateExecutable(DebuggerStartParameters *sp)
const bool warnOnRelease = boolSetting(WarnOnReleaseBuilds);
QString detailedWarning;
switch (sp->toolChainAbi.binaryFormat()) {
- case ProjectExplorer::Abi::PEFormat: {
+ case Abi::PEFormat: {
if (!warnOnRelease || (sp->masterEngineType != CdbEngineType))
return;
if (!binary.endsWith(QLatin1String(".exe"), Qt::CaseInsensitive))
@@ -1798,7 +1780,7 @@ void DebuggerEngine::validateExecutable(DebuggerStartParameters *sp)
}
break;
}
- case ProjectExplorer::Abi::ElfFormat: {
+ case Abi::ElfFormat: {
Utils::ElfReader reader(binary);
Utils::ElfData elfData = reader.readHeaders();
@@ -1897,13 +1879,14 @@ void DebuggerEngine::validateExecutable(DebuggerStartParameters *sp)
return;
}
if (warnOnRelease) {
- showMessageBox(QMessageBox::Information, tr("Warning"),
+ AsynchronousMessageBox::information(tr("Warning"),
tr("This does not seem to be a \"Debug\" build.\n"
"Setting breakpoints by file name and line number may fail.")
+ QLatin1Char('\n') + detailedWarning);
}
}
+} // namespace Internal
} // namespace Debugger
#include "debuggerengine.moc"
diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h
index 71c5ec831a..a7313a9c7c 100644
--- a/src/plugins/debugger/debuggerengine.h
+++ b/src/plugins/debugger/debuggerengine.h
@@ -33,8 +33,8 @@
#include "debugger_global.h"
#include "debuggerconstants.h"
+#include "debuggerprotocol.h"
#include "debuggerstartparameters.h"
-#include "breakpoint.h" // For BreakpointModelId.
#include "threaddata.h" // For ThreadId.
#include <QObject>
@@ -42,7 +42,6 @@
QT_BEGIN_NAMESPACE
class QDebug;
class QPoint;
-class QMessageBox;
class QAbstractItemModel;
QT_END_NAMESPACE
@@ -51,7 +50,6 @@ namespace Core { class IOptionsPage; }
namespace Debugger {
-class DebuggerEnginePrivate;
class DebuggerRunControl;
class DebuggerStartParameters;
@@ -60,6 +58,7 @@ DEBUGGER_EXPORT QDebug operator<<(QDebug str, DebuggerState state);
namespace Internal {
+class DebuggerEnginePrivate;
class DebuggerPluginPrivate;
class DisassemblerAgent;
class MemoryAgent;
@@ -72,11 +71,12 @@ class StackFrame;
class SourceFilesHandler;
class ThreadsHandler;
class WatchHandler;
-class BreakpointParameters;
+class Breakpoint;
class QmlAdapter;
class QmlCppEngine;
class DebuggerToolTipContext;
-class MemoryMarkup;
+class MemoryViewSetupData;
+class Terminal;
struct WatchUpdateFlags
{
@@ -130,11 +130,7 @@ public:
quint64 address;
};
-} // namespace Internal
-
-
-// FIXME: DEBUGGER_EXPORT?
-class DEBUGGER_EXPORT DebuggerEngine : public QObject
+class DebuggerEngine : public QObject
{
Q_OBJECT
@@ -163,10 +159,7 @@ public:
MemoryView = 0x4 //!< Open a separate view (using the pos-parameter).
};
- virtual void openMemoryView(quint64 startAddr, unsigned flags,
- const QList<Internal::MemoryMarkup> &ml,
- const QPoint &pos,
- const QString &title = QString(), QWidget *parent = 0);
+ virtual void openMemoryView(const MemoryViewSetupData &data);
virtual void fetchMemory(Internal::MemoryAgent *, QObject *,
quint64 addr, quint64 length);
virtual void changeMemory(Internal::MemoryAgent *, QObject *,
@@ -190,7 +183,7 @@ public:
virtual void loadAdditionalQmlStack();
virtual void reloadDebuggingHelpers();
- virtual void setRegisterValue(int regnr, const QString &value);
+ virtual void setRegisterValue(const QByteArray &name, const QString &value);
virtual void addOptionPages(QList<Core::IOptionsPage*> *) const;
virtual bool hasCapability(unsigned cap) const = 0;
virtual void debugLastCommand() {}
@@ -201,13 +194,12 @@ public:
virtual void createSnapshot();
virtual void updateAll();
- typedef Internal::BreakpointModelId BreakpointModelId;
virtual bool stateAcceptsBreakpointChanges() const { return true; }
virtual void attemptBreakpointSynchronization();
- virtual bool acceptsBreakpoint(BreakpointModelId id) const = 0;
- virtual void insertBreakpoint(BreakpointModelId id); // FIXME: make pure
- virtual void removeBreakpoint(BreakpointModelId id); // FIXME: make pure
- virtual void changeBreakpoint(BreakpointModelId id); // FIXME: make pure
+ virtual bool acceptsBreakpoint(Breakpoint bp) const = 0;
+ virtual void insertBreakpoint(Breakpoint bp); // FIXME: make pure
+ virtual void removeBreakpoint(Breakpoint bp); // FIXME: make pure
+ virtual void changeBreakpoint(Breakpoint bp); // FIXME: make pure
virtual bool acceptsDebuggerCommands() const { return true; }
virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);
@@ -264,9 +256,6 @@ public:
bool isMasterEngine() const;
DebuggerEngine *masterEngine() const;
- virtual bool setupQmlStep(bool /*on*/) { return false; }
- virtual void readyToExecuteQmlStep() {}
-
virtual bool canDisplayTooltip() const { return state() == InferiorStopOk; }
virtual void notifyInferiorIll();
@@ -286,6 +275,7 @@ signals:
* a server start script should be used, but none is given.
*/
void requestRemoteSetup();
+ void aboutToNotifyInferiorSetupOk();
protected:
// The base notify*() function implementation should be sufficient
@@ -319,7 +309,9 @@ protected:
virtual void notifyInferiorStopOk();
virtual void notifyInferiorSpontaneousStop();
virtual void notifyInferiorStopFailed();
- Q_SLOT virtual void notifyInferiorExited();
+
+ public:
+ virtual void notifyInferiorExited();
protected:
virtual void notifyInferiorShutdownOk();
@@ -362,17 +354,8 @@ protected:
void setMasterEngine(DebuggerEngine *masterEngine);
DebuggerRunControl *runControl() const;
+ Terminal *terminal() const;
- static QString msgWatchpointByAddressTriggered(BreakpointModelId id,
- int number, quint64 address);
- static QString msgWatchpointByAddressTriggered(BreakpointModelId id,
- int number, quint64 address, const QString &threadId);
- static QString msgWatchpointByExpressionTriggered(BreakpointModelId id,
- int number, const QString &expr);
- static QString msgWatchpointByExpressionTriggered(BreakpointModelId id,
- int number, const QString &expr, const QString &threadId);
- static QString msgBreakpointTriggered(BreakpointModelId id,
- int number, const QString &threadId);
static QString msgStopped(const QString &reason = QString());
static QString msgStoppedBySignal(const QString &meaning, const QString &name);
static QString msgStoppedByException(const QString &description,
@@ -396,9 +379,9 @@ protected:
private:
// Wrapper engine needs access to state of its subengines.
- friend class Internal::QmlCppEngine;
- friend class Internal::DebuggerPluginPrivate;
- friend class Internal::QmlAdapter;
+ friend class QmlCppEngine;
+ friend class DebuggerPluginPrivate;
+ friend class QmlAdapter;
virtual void setState(DebuggerState state, bool forced = false);
@@ -406,6 +389,7 @@ private:
DebuggerEnginePrivate *d;
};
+} // namespace Internal
} // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::ContextData)
diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp
index def87bde11..f011a861db 100644
--- a/src/plugins/debugger/debuggeritem.cpp
+++ b/src/plugins/debugger/debuggeritem.cpp
@@ -142,9 +142,18 @@ void DebuggerItem::reinitializeFromFile()
.arg(version / 10000).arg((version / 100) % 100).arg(version % 100);
return;
}
- if (ba.contains("lldb") || ba.startsWith("LLDB")) {
+ if (ba.startsWith("lldb") || ba.startsWith("LLDB")) {
m_engineType = LldbEngineType;
m_abis = Abi::abisOfBinary(m_command);
+
+ // Version
+ if (ba.startsWith(("lldb version "))) { // Linux typically.
+ int pos1 = strlen("lldb version ");
+ int pos2 = ba.indexOf(' ', pos1);
+ m_version = QString::fromLatin1(ba.mid(pos1, pos2 - pos1));
+ } else if (ba.startsWith("lldb-") || ba.startsWith("LLDB-")) { // Mac typically.
+ m_version = QString::fromLatin1(ba.mid(5));
+ }
return;
}
if (ba.startsWith("Python")) {
@@ -223,7 +232,7 @@ void DebuggerItem::setEngineType(const DebuggerEngineType &engineType)
m_engineType = engineType;
}
-void DebuggerItem::setCommand(const Utils::FileName &command)
+void DebuggerItem::setCommand(const FileName &command)
{
m_command = command;
}
@@ -248,7 +257,7 @@ void DebuggerItem::setAutoDetectionSource(const QString &autoDetectionSource)
m_autoDetectionSource = autoDetectionSource;
}
-void DebuggerItem::setAbis(const QList<ProjectExplorer::Abi> &abis)
+void DebuggerItem::setAbis(const QList<Abi> &abis)
{
m_abis = abis;
}
diff --git a/src/plugins/debugger/debuggeritem.h b/src/plugins/debugger/debuggeritem.h
index ffffb2086b..6117e6c5f3 100644
--- a/src/plugins/debugger/debuggeritem.h
+++ b/src/plugins/debugger/debuggeritem.h
@@ -97,6 +97,7 @@ public:
QStringList abiNames() const;
bool operator==(const DebuggerItem &other) const;
+ bool operator!=(const DebuggerItem &other) const { return !operator==(other); }
private:
DebuggerItem(const QVariant &id);
diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp
index b4a38c2927..f7cad5d96c 100644
--- a/src/plugins/debugger/debuggeritemmanager.cpp
+++ b/src/plugins/debugger/debuggeritemmanager.cpp
@@ -29,8 +29,6 @@
****************************************************************************/
#include "debuggeritemmanager.h"
-
-#include "debuggeritemmodel.h"
#include "debuggerkitinformation.h"
#include <coreplugin/icore.h>
@@ -46,26 +44,36 @@
#include <QFileInfo>
#include <QProcess>
+using namespace Core;
using namespace ProjectExplorer;
using namespace Utils;
namespace Debugger {
-static const char DEBUGGER_COUNT_KEY[] = "DebuggerItem.Count";
-static const char DEBUGGER_DATA_KEY[] = "DebuggerItem.";
-static const char DEBUGGER_LEGACY_FILENAME[] = "/qtcreator/profiles.xml";
-static const char DEBUGGER_FILE_VERSION_KEY[] = "Version";
-static const char DEBUGGER_FILENAME[] = "/qtcreator/debuggers.xml";
+const char DEBUGGER_COUNT_KEY[] = "DebuggerItem.Count";
+const char DEBUGGER_DATA_KEY[] = "DebuggerItem.";
+const char DEBUGGER_LEGACY_FILENAME[] = "/qtcreator/profiles.xml";
+const char DEBUGGER_FILE_VERSION_KEY[] = "Version";
+const char DEBUGGER_FILENAME[] = "/qtcreator/debuggers.xml";
+
+namespace {
+QList<DebuggerItem> m_debuggers;
+PersistentSettingsWriter *m_writer = 0;
+}
// --------------------------------------------------------------------------
// DebuggerItemManager
// --------------------------------------------------------------------------
-static DebuggerItemManager *m_instance = 0;
+static void addDebugger(const DebuggerItem &item)
+{
+ QTC_ASSERT(item.id().isValid(), return);
+ m_debuggers.append(item);
+}
static FileName userSettingsFileName()
{
- QFileInfo settingsLocation(Core::ICore::settings()->fileName());
+ QFileInfo settingsLocation(ICore::settings()->fileName());
return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME));
}
@@ -111,27 +119,15 @@ static void readDebuggers(const FileName &fileName, bool isSystem)
}
}
-QList<DebuggerItem> DebuggerItemManager::m_debuggers;
-PersistentSettingsWriter * DebuggerItemManager::m_writer = 0;
-
-DebuggerItemManager::DebuggerItemManager(QObject *parent)
- : QObject(parent)
+DebuggerItemManager::DebuggerItemManager()
{
- m_instance = this;
m_writer = new PersistentSettingsWriter(userSettingsFileName(), QLatin1String("QtCreatorDebuggers"));
- connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()),
- this, SLOT(saveDebuggers()));
-}
-
-DebuggerItemManager *DebuggerItemManager::instance()
-{
- return m_instance;
+ connect(ICore::instance(), &ICore::saveSettingsRequested,
+ this, &DebuggerItemManager::saveDebuggers);
}
DebuggerItemManager::~DebuggerItemManager()
{
- disconnect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()),
- this, SLOT(saveDebuggers()));
delete m_writer;
}
@@ -227,7 +223,7 @@ void DebuggerItemManager::autoDetectGdbOrLldbDebuggers()
}
*/
- QFileInfoList suspects;
+ QList<FileName> suspects;
if (HostOsInfo::isMacHost()) {
QProcess lldbInfo;
@@ -238,43 +234,38 @@ void DebuggerItemManager::autoDetectGdbOrLldbDebuggers()
lldbInfo.waitForFinished();
} else {
QByteArray lPath = lldbInfo.readAll();
- suspects.append(QFileInfo(QString::fromLocal8Bit(lPath.data(), lPath.size() -1)));
+ const QFileInfo fi(QString::fromLocal8Bit(lPath.data(), lPath.size() -1));
+ if (fi.exists() && fi.isExecutable() && !fi.isDir())
+ suspects.append(FileName::fromString(fi.absoluteFilePath()));
}
}
QStringList path = Environment::systemEnvironment().path();
+ path.removeDuplicates();
+ QDir dir;
+ dir.setNameFilters(filters);
+ dir.setFilter(QDir::Files | QDir::Executable);
foreach (const QString &base, path) {
- QDir dir(base);
- dir.setNameFilters(filters);
- suspects += dir.entryInfoList();
+ dir.setPath(base);
+ foreach (const QString &entry, dir.entryList())
+ suspects.append(FileName::fromString(dir.absoluteFilePath(entry)));
}
- foreach (const QFileInfo &fi, suspects) {
- if (fi.exists() && fi.isExecutable() && !fi.isDir()) {
- FileName command = FileName::fromString(fi.absoluteFilePath());
- if (findByCommand(command))
- continue;
- DebuggerItem item;
- item.createId();
- item.setCommand(command);
- item.reinitializeFromFile();
- //: %1: Debugger engine type (GDB, LLDB, CDB...), %2: Path
- item.setDisplayName(tr("System %1 at %2")
- .arg(item.engineTypeName()).arg(QDir::toNativeSeparators(fi.absoluteFilePath())));
- item.setAutoDetected(true);
- addDebugger(item);
- }
+ foreach (const FileName &command, suspects) {
+ if (findByCommand(command))
+ continue;
+ DebuggerItem item;
+ item.createId();
+ item.setCommand(command);
+ item.reinitializeFromFile();
+ //: %1: Debugger engine type (GDB, LLDB, CDB...), %2: Path
+ item.setDisplayName(tr("System %1 at %2")
+ .arg(item.engineTypeName()).arg(command.toUserOutput()));
+ item.setAutoDetected(true);
+ addDebugger(item);
}
}
-void DebuggerItemManager::readLegacyDebuggers()
-{
- QFileInfo systemLocation(Core::ICore::settings(QSettings::SystemScope)->fileName());
- readLegacyDebuggers(FileName::fromString(systemLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)));
- QFileInfo userLocation(Core::ICore::settings()->fileName());
- readLegacyDebuggers(FileName::fromString(userLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)));
-}
-
void DebuggerItemManager::readLegacyDebuggers(const FileName &file)
{
PersistentSettingsReader reader;
@@ -341,7 +332,7 @@ const DebuggerItem *DebuggerItemManager::findByEngineType(DebuggerEngineType eng
void DebuggerItemManager::restoreDebuggers()
{
// Read debuggers from SDK
- QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
+ QFileInfo systemSettingsFile(ICore::settings(QSettings::SystemScope)->fileName());
readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)), true);
// Read all debuggers from user file.
@@ -352,7 +343,10 @@ void DebuggerItemManager::restoreDebuggers()
autoDetectGdbOrLldbDebuggers();
// Add debuggers from pre-3.x profiles.xml
- readLegacyDebuggers();
+ QFileInfo systemLocation(ICore::settings(QSettings::SystemScope)->fileName());
+ readLegacyDebuggers(FileName::fromString(systemLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)));
+ QFileInfo userLocation(ICore::settings()->fileName());
+ readLegacyDebuggers(FileName::fromString(userLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)));
}
void DebuggerItemManager::saveDebuggers()
@@ -372,7 +366,7 @@ void DebuggerItemManager::saveDebuggers()
}
}
data.insert(QLatin1String(DEBUGGER_COUNT_KEY), count);
- m_writer->save(data, Core::ICore::mainWindow());
+ m_writer->save(data, ICore::mainWindow());
// Do not save default debuggers as they are set by the SDK.
}
@@ -390,44 +384,23 @@ QVariant DebuggerItemManager::registerDebugger(const DebuggerItem &item)
}
}
- // If item already has an id, add it. Otherwise, create a new id.
- if (item.id().isValid())
- return addDebugger(item);
-
+ // If item already has an id, use it. Otherwise, create a new id.
DebuggerItem di = item;
- di.createId();
- return addDebugger(di);
-}
+ if (!di.id().isValid())
+ di.createId();
-void DebuggerItemManager::deregisterDebugger(const QVariant &id)
-{
- if (findById(id))
- removeDebugger(id);
+ addDebugger(di);
+ return di.id();
}
-QVariant DebuggerItemManager::addDebugger(const DebuggerItem &item)
-{
- QTC_ASSERT(item.id().isValid(), return QVariant());
- m_debuggers.append(item);
- QVariant id = item.id();
- emit m_instance->debuggerAdded(id);
- return id;
-}
-
-void DebuggerItemManager::removeDebugger(const QVariant &id)
+void DebuggerItemManager::deregisterDebugger(const QVariant &id)
{
- bool ok = false;
for (int i = 0, n = m_debuggers.size(); i != n; ++i) {
if (m_debuggers.at(i).id() == id) {
- emit m_instance->aboutToRemoveDebugger(id);
m_debuggers.removeAt(i);
- emit m_instance->debuggerRemoved(id);
- ok = true;
break;
}
}
-
- QTC_ASSERT(ok, return);
}
QString DebuggerItemManager::uniqueDisplayName(const QString &base)
@@ -439,26 +412,18 @@ QString DebuggerItemManager::uniqueDisplayName(const QString &base)
return base;
}
-void DebuggerItemManager::setItemData(const QVariant &id, const QString &displayName, const FileName &fileName)
+void DebuggerItemManager::updateOrAddDebugger(const DebuggerItem &treeItem)
{
for (int i = 0, n = m_debuggers.size(); i != n; ++i) {
DebuggerItem &item = m_debuggers[i];
- if (item.id() == id) {
- bool changed = false;
- if (item.displayName() != displayName) {
- item.setDisplayName(displayName);
- changed = true;
- }
- if (item.command() != fileName) {
- item.setCommand(fileName);
- item.reinitializeFromFile();
- changed = true;
- }
- if (changed)
- emit m_instance->debuggerUpdated(id);
- break;
+ if (item.id() == treeItem.id()) {
+ item = treeItem;
+ return;
}
}
+
+ // This is a new item.
+ addDebugger(treeItem);
}
} // namespace Debugger;
diff --git a/src/plugins/debugger/debuggeritemmanager.h b/src/plugins/debugger/debuggeritemmanager.h
index 5bddfccbb5..25afa1b2df 100644
--- a/src/plugins/debugger/debuggeritemmanager.h
+++ b/src/plugins/debugger/debuggeritemmanager.h
@@ -33,35 +33,27 @@
#include "debugger_global.h"
#include "debuggeritem.h"
-#include "debuggeritemmodel.h"
#include <QList>
#include <QObject>
#include <QString>
-namespace Utils { class PersistentSettingsWriter; }
-
namespace Debugger {
-namespace Internal { class DebuggerPlugin; }
-
// -----------------------------------------------------------------------
// DebuggerItemManager
// -----------------------------------------------------------------------
class DEBUGGER_EXPORT DebuggerItemManager : public QObject
{
- Q_OBJECT
-
public:
- static DebuggerItemManager *instance();
+ DebuggerItemManager();
~DebuggerItemManager();
static QList<DebuggerItem> debuggers();
static QVariant registerDebugger(const DebuggerItem &item);
static void deregisterDebugger(const QVariant &id);
- static void setItemData(const QVariant &id, const QString& displayName, const Utils::FileName &fileName);
static const DebuggerItem *findByCommand(const Utils::FileName &command);
static const DebuggerItem *findById(const QVariant &id);
@@ -70,30 +62,13 @@ public:
static void restoreDebuggers();
static QString uniqueDisplayName(const QString &base);
- static void removeDebugger(const QVariant &id);
- static QVariant addDebugger(const DebuggerItem &item);
-
-signals:
- void debuggerAdded(const QVariant &id);
- void aboutToRemoveDebugger(const QVariant &id);
- void debuggerRemoved(const QVariant &id);
- void debuggerUpdated(const QVariant &id);
-
-public slots:
- void saveDebuggers();
+ static void updateOrAddDebugger(const DebuggerItem &item);
+ static void saveDebuggers();
private:
- explicit DebuggerItemManager(QObject *parent = 0);
static void autoDetectGdbOrLldbDebuggers();
static void autoDetectCdbDebuggers();
- static void readLegacyDebuggers();
static void readLegacyDebuggers(const Utils::FileName &file);
-
- static Utils::PersistentSettingsWriter *m_writer;
- static QList<DebuggerItem> m_debuggers;
-
- friend class Internal::DebuggerItemModel;
- friend class Internal::DebuggerPlugin; // Enable constrcutor for DebuggerPlugin
};
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggeritemmodel.cpp b/src/plugins/debugger/debuggeritemmodel.cpp
deleted file mode 100644
index 9b24144510..0000000000
--- a/src/plugins/debugger/debuggeritemmodel.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms and
-** conditions see http://www.qt.io/terms-conditions. For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "debuggeritemmodel.h"
-
-#include "debuggeritem.h"
-#include "debuggeritemmanager.h"
-
-#include <utils/qtcassert.h>
-
-namespace Debugger {
-namespace Internal {
-
-const int AbiRole = Qt::UserRole + 2;
-
-static QList<QStandardItem *> describeItem(const DebuggerItem &item)
-{
- QList<QStandardItem *> row;
- row.append(new QStandardItem(item.displayName()));
- row.append(new QStandardItem(item.command().toUserOutput()));
- row.append(new QStandardItem(item.engineTypeName()));
- row.at(0)->setData(item.id());
- row.at(0)->setData(item.abiNames(), AbiRole);
- row.at(0)->setEditable(false);
- row.at(1)->setEditable(false);
- row.at(1)->setData(item.toMap());
- row.at(2)->setEditable(false);
- row.at(2)->setData(static_cast<int>(item.engineType()));
- row.at(0)->setSelectable(true);
- row.at(1)->setSelectable(true);
- row.at(2)->setSelectable(true);
- return row;
-}
-
-static QList<QStandardItem *> createRow(const QString &display)
-{
- QList<QStandardItem *> row;
- row.append(new QStandardItem(display));
- row.append(new QStandardItem());
- row.append(new QStandardItem());
- row.at(0)->setEditable(false);
- row.at(1)->setEditable(false);
- row.at(2)->setEditable(false);
- row.at(0)->setSelectable(false);
- row.at(1)->setSelectable(false);
- row.at(2)->setSelectable(false);
- return row;
-}
-
-// --------------------------------------------------------------------------
-// DebuggerItemModel
-// --------------------------------------------------------------------------
-
-DebuggerItemModel::DebuggerItemModel(QObject *parent)
- : QStandardItemModel(parent)
-{
- setColumnCount(3);
-
- QList<QStandardItem *> row = createRow(tr("Auto-detected"));
- m_autoRoot = row.at(0);
- appendRow(row);
-
- row = createRow(tr("Manual"));
- m_manualRoot = row.at(0);
- appendRow(row);
-
- foreach (const DebuggerItem &item, DebuggerItemManager::debuggers())
- addDebuggerStandardItem(item, false);
-
- QObject *manager = DebuggerItemManager::instance();
- connect(manager, SIGNAL(debuggerAdded(QVariant)),
- this, SLOT(onDebuggerAdded(QVariant)));
- connect(manager, SIGNAL(debuggerUpdated(QVariant)),
- this, SLOT(onDebuggerUpdate(QVariant)));
- connect(manager, SIGNAL(debuggerRemoved(QVariant)),
- this, SLOT(onDebuggerRemoval(QVariant)));
-}
-
-QVariant DebuggerItemModel::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
- switch (section) {
- case 0:
- return tr("Name");
- case 1:
- return tr("Path");
- case 2:
- return tr("Type");
- }
- }
- return QVariant();
-}
-
-bool DebuggerItemModel::addDebuggerStandardItem(const DebuggerItem &item, bool changed)
-{
- if (findStandardItemById(item.id()))
- return false;
-
- QList<QStandardItem *> row = describeItem(item);
- foreach (QStandardItem *cell, row) {
- QFont font = cell->font();
- font.setBold(changed);
- cell->setFont(font);
- }
- (item.isAutoDetected() ? m_autoRoot : m_manualRoot)->appendRow(row);
- return true;
-}
-
-bool DebuggerItemModel::removeDebuggerStandardItem(const QVariant &id)
-{
- QStandardItem *sitem = findStandardItemById(id);
- QTC_ASSERT(sitem, return false);
- QStandardItem *parent = sitem->parent();
- QTC_ASSERT(parent, return false);
- // This will trigger a change of m_currentDebugger via changing the
- // view selection.
- parent->removeRow(sitem->row());
- return true;
-}
-
-bool DebuggerItemModel::updateDebuggerStandardItem(const DebuggerItem &item, bool changed)
-{
- QStandardItem *sitem = findStandardItemById(item.id());
- QTC_ASSERT(sitem, return false);
- QStandardItem *parent = sitem->parent();
- QTC_ASSERT(parent, return false);
-
- // Do not mark items as changed if they actually are not:
- const DebuggerItem *orig = DebuggerItemManager::findById(item.id());
- if (orig && *orig == item)
- changed = false;
-
- int row = sitem->row();
- QFont font = sitem->font();
- font.setBold(changed);
- parent->child(row, 0)->setData(item.displayName(), Qt::DisplayRole);
- parent->child(row, 0)->setData(item.abiNames(), AbiRole);
- parent->child(row, 0)->setFont(font);
- parent->child(row, 1)->setData(item.command().toUserOutput(), Qt::DisplayRole);
- parent->child(row, 1)->setFont(font);
- parent->child(row, 2)->setData(item.engineTypeName(), Qt::DisplayRole);
- parent->child(row, 2)->setData(static_cast<int>(item.engineType()));
- parent->child(row, 2)->setFont(font);
- return true;
-}
-
-DebuggerItem DebuggerItemModel::debuggerItem(QStandardItem *sitem) const
-{
- DebuggerItem item = DebuggerItem(QVariant());
- if (sitem && sitem->parent()) {
- item.setAutoDetected(sitem->parent() == m_autoRoot);
-
- QStandardItem *i = sitem->parent()->child(sitem->row(), 0);
- item.m_id = i->data();
- item.setDisplayName(i->data(Qt::DisplayRole).toString());
-
- QStringList abis = i->data(AbiRole).toStringList();
- QList<ProjectExplorer::Abi> abiList;
- foreach (const QString &abi, abis)
- abiList << ProjectExplorer::Abi(abi);
- item.setAbis(abiList);
-
- i = sitem->parent()->child(sitem->row(), 1);
- item.setCommand(Utils::FileName::fromUserInput(i->data(Qt::DisplayRole).toString()));
-
- i = sitem->parent()->child(sitem->row(), 2);
- item.setEngineType(static_cast<DebuggerEngineType>(i->data().toInt()));
- }
- return item;
-}
-
-QList<DebuggerItem> DebuggerItemModel::debuggerItems() const
-{
- QList<DebuggerItem> result;
- for (int i = 0, n = m_autoRoot->rowCount(); i != n; ++i)
- result << debuggerItem(m_autoRoot->child(i));
- for (int i = 0, n = m_manualRoot->rowCount(); i != n; ++i)
- result << debuggerItem(m_manualRoot->child(i));
- return result;
-}
-
-QStandardItem *DebuggerItemModel::currentStandardItem() const
-{
- return findStandardItemById(m_currentDebugger);
-}
-
-QStandardItem *DebuggerItemModel::findStandardItemById(const QVariant &id) const
-{
- for (int i = 0, n = m_autoRoot->rowCount(); i != n; ++i) {
- QStandardItem *sitem = m_autoRoot->child(i);
- if (sitem->data() == id)
- return sitem;
- }
- for (int i = 0, n = m_manualRoot->rowCount(); i != n; ++i) {
- QStandardItem *sitem = m_manualRoot->child(i);
- if (sitem->data() == id)
- return sitem;
- }
- return 0;
-}
-
-QModelIndex DebuggerItemModel::currentIndex() const
-{
- QStandardItem *current = currentStandardItem();
- return current ? current->index() : QModelIndex();
-}
-
-QModelIndex DebuggerItemModel::lastIndex() const
-{
- int n = m_manualRoot->rowCount();
- QStandardItem *current = m_manualRoot->child(n - 1);
- return current ? current->index() : QModelIndex();
-}
-
-void DebuggerItemModel::onDebuggerAdded(const QVariant &id)
-{
- const DebuggerItem *item = DebuggerItemManager::findById(id);
- QTC_ASSERT(item, return);
- if (!addDebuggerStandardItem(*item, false))
- updateDebuggerStandardItem(*item, false); // already had it added, so just update it.
-}
-
-void DebuggerItemModel::onDebuggerUpdate(const QVariant &id)
-{
- const DebuggerItem *item = DebuggerItemManager::findById(id);
- QTC_ASSERT(item, return);
- updateDebuggerStandardItem(*item, false);
-}
-
-void DebuggerItemModel::onDebuggerRemoval(const QVariant &id)
-{
- removeDebuggerStandardItem(id);
-}
-
-void DebuggerItemModel::addDebugger(const DebuggerItem &item)
-{
- addDebuggerStandardItem(item, true);
-}
-
-void DebuggerItemModel::removeDebugger(const QVariant &id)
-{
- if (!removeDebuggerStandardItem(id)) // Nothing there!
- return;
-
- if (DebuggerItemManager::findById(id))
- m_removedItems.append(id);
-}
-
-void DebuggerItemModel::updateDebugger(const DebuggerItem &item)
-{
- updateDebuggerStandardItem(item, true);
-}
-
-void DebuggerItemModel::apply()
-{
- foreach (const QVariant &id, m_removedItems)
- DebuggerItemManager::deregisterDebugger(id);
-
- foreach (const DebuggerItem &item, debuggerItems()) {
- const DebuggerItem *managed = DebuggerItemManager::findById(item.id());
- if (managed) {
- if (*managed == item)
- continue;
- else
- DebuggerItemManager::setItemData(item.id(), item.displayName(), item.command());
- } else {
- DebuggerItemManager::registerDebugger(item);
- }
- }
-}
-
-void DebuggerItemModel::setCurrentIndex(const QModelIndex &index)
-{
- QStandardItem *sit = itemFromIndex(index);
- m_currentDebugger = sit ? sit->data() : QVariant();
-}
-
-DebuggerItem DebuggerItemModel::currentDebugger() const
-{
- return debuggerItem(currentStandardItem());
-}
-
-} // namespace Internal
-} // namespace Debugger
diff --git a/src/plugins/debugger/debuggeritemmodel.h b/src/plugins/debugger/debuggeritemmodel.h
deleted file mode 100644
index 682bd60247..0000000000
--- a/src/plugins/debugger/debuggeritemmodel.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms and
-** conditions see http://www.qt.io/terms-conditions. For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#ifndef DEBUGGER_DEBUGGERITEMMODEL_H
-#define DEBUGGER_DEBUGGERITEMMODEL_H
-
-#include "debuggeritem.h"
-
-#include <QStandardItemModel>
-#include <QVariant>
-
-namespace Debugger {
-namespace Internal {
-
-// -----------------------------------------------------------------------
-// DebuggerItemModel
-//------------------------------------------------------------------------
-
-class DebuggerItemModel : public QStandardItemModel
-{
- Q_OBJECT
-
-public:
- DebuggerItemModel(QObject *parent = 0);
-
- QModelIndex currentIndex() const;
- QModelIndex lastIndex() const;
- void setCurrentIndex(const QModelIndex &index);
- QVariant currentDebuggerId() const { return m_currentDebugger; }
- DebuggerItem currentDebugger() const;
- void addDebugger(const DebuggerItem &item);
- void removeDebugger(const QVariant &id);
- void updateDebugger(const DebuggerItem &item);
-
- void apply();
-
-private slots:
- void onDebuggerAdded(const QVariant &id);
- void onDebuggerUpdate(const QVariant &id);
- void onDebuggerRemoval(const QVariant &id);
-
-private:
- QStandardItem *currentStandardItem() const;
- QStandardItem *findStandardItemById(const QVariant &id) const;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
-
- bool addDebuggerStandardItem(const DebuggerItem &item, bool changed);
- bool removeDebuggerStandardItem(const QVariant &id);
- bool updateDebuggerStandardItem(const DebuggerItem &item, bool changed);
-
- DebuggerItem debuggerItem(QStandardItem *sitem) const;
- QList<DebuggerItem> debuggerItems() const;
-
- QVariant m_currentDebugger;
-
- QStandardItem *m_autoRoot;
- QStandardItem *m_manualRoot;
- QStringList removed;
-
- QList<QVariant> m_removedItems;
-};
-
-} // namespace Internal
-} // namespace Debugger
-
-#endif // DEBUGGER_DEBUGGERITEMMODEL_H
diff --git a/src/plugins/debugger/debuggerkitconfigwidget.cpp b/src/plugins/debugger/debuggerkitconfigwidget.cpp
index 40f7e18c2a..1812cb76e0 100644
--- a/src/plugins/debugger/debuggerkitconfigwidget.cpp
+++ b/src/plugins/debugger/debuggerkitconfigwidget.cpp
@@ -31,7 +31,6 @@
#include "debuggerkitconfigwidget.h"
#include "debuggeritemmanager.h"
-#include "debuggeritemmodel.h"
#include "debuggerkitinformation.h"
#include <coreplugin/icore.h>
@@ -64,8 +63,6 @@ using namespace ProjectExplorer;
namespace Debugger {
namespace Internal {
-class DebuggerItemConfigWidget;
-
// -----------------------------------------------------------------------
// DebuggerKitConfigWidget
// -----------------------------------------------------------------------
@@ -88,14 +85,6 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(Kit *workingCopy, const KitInfo
m_manageButton->setContentsMargins(0, 0, 0, 0);
connect(m_manageButton, &QAbstractButton::clicked,
this, &DebuggerKitConfigWidget::manageDebuggers);
-
- DebuggerItemManager *manager = DebuggerItemManager::instance();
- connect(manager, &DebuggerItemManager::debuggerAdded,
- this, &DebuggerKitConfigWidget::onDebuggerAdded);
- connect(manager, &DebuggerItemManager::debuggerUpdated,
- this, &DebuggerKitConfigWidget::onDebuggerUpdated);
- connect(manager, &DebuggerItemManager::debuggerRemoved,
- this, &DebuggerKitConfigWidget::onDebuggerRemoved);
}
DebuggerKitConfigWidget::~DebuggerKitConfigWidget()
@@ -150,31 +139,6 @@ void DebuggerKitConfigWidget::currentDebuggerChanged(int)
m_kit->setValue(DebuggerKitInformation::id(), id);
}
-void DebuggerKitConfigWidget::onDebuggerAdded(const QVariant &id)
-{
- const DebuggerItem *item = DebuggerItemManager::findById(id);
- QTC_ASSERT(item, return);
- m_comboBox->addItem(item->displayName(), id);
-}
-
-void DebuggerKitConfigWidget::onDebuggerUpdated(const QVariant &id)
-{
- const DebuggerItem *item = DebuggerItemManager::findById(id);
- QTC_ASSERT(item, return);
- const int pos = indexOf(id);
- if (pos < 0)
- return;
- m_comboBox->setItemText(pos, item->displayName());
-}
-
-void DebuggerKitConfigWidget::onDebuggerRemoved(const QVariant &id)
-{
- if (const int pos = indexOf(id)) {
- m_comboBox->removeItem(pos);
- refresh();
- }
-}
-
int DebuggerKitConfigWidget::indexOf(const QVariant &id)
{
QTC_ASSERT(id.isValid(), return -1);
diff --git a/src/plugins/debugger/debuggerkitconfigwidget.h b/src/plugins/debugger/debuggerkitconfigwidget.h
index fc5d569e84..cbe4e8b594 100644
--- a/src/plugins/debugger/debuggerkitconfigwidget.h
+++ b/src/plugins/debugger/debuggerkitconfigwidget.h
@@ -31,8 +31,6 @@
#ifndef DEBUGGER_DEBUGGERKITCONFIGWIDGET_H
#define DEBUGGER_DEBUGGERKITCONFIGWIDGET_H
-#include "debuggeritemmodel.h"
-
#include <coreplugin/dialogs/ioptionspage.h>
#include <projectexplorer/kitconfigwidget.h>
#include <projectexplorer/abi.h>
@@ -72,14 +70,10 @@ public:
QWidget *buttonWidget() const;
QWidget *mainWidget() const;
-private slots:
+private:
void manageDebuggers();
void currentDebuggerChanged(int idx);
- void onDebuggerAdded(const QVariant &id);
- void onDebuggerUpdated(const QVariant &id);
- void onDebuggerRemoved(const QVariant &id);
-private:
int indexOf(const QVariant &id);
QVariant currentId() const;
void updateComboBox(const QVariant &id);
diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp
index 06e24d80f3..f41f0edea2 100644
--- a/src/plugins/debugger/debuggerkitinformation.cpp
+++ b/src/plugins/debugger/debuggerkitinformation.cpp
@@ -306,13 +306,28 @@ void DebuggerKitInformation::addToMacroExpander(Kit *kit, MacroExpander *expande
expander->registerVariable("Debugger:Type", tr("Type of Debugger Backend"),
[this, kit]() -> QString {
const DebuggerItem *item = debugger(kit);
- return item ? item->engineTypeName() : tr("unknown");
+ return item ? item->engineTypeName() : tr("Unknown debugger type");
});
- // FIXME: Use better strings.
+
expander->registerVariable("Debugger:Name", tr("Debugger"),
[this, kit]() -> QString {
const DebuggerItem *item = debugger(kit);
- return item ? item->displayName() : tr("unknown");
+ return item ? item->displayName() : tr("Unknown debugger");
+ });
+
+ expander->registerVariable("Debugger:Version", tr("Debugger"),
+ [this, kit]() -> QString {
+ const DebuggerItem *item = debugger(kit);
+ return item && !item->version().isEmpty()
+ ? item->version() : tr("Unknown debugger version");
+ });
+
+ expander->registerVariable("Debugger:Abi", tr("Debugger"),
+ [this, kit]() -> QString {
+ const DebuggerItem *item = debugger(kit);
+ return item && !item->abis().isEmpty()
+ ? item->abiNames().join(QLatin1Char(' '))
+ : tr("Unknown debugger ABI");
});
}
@@ -321,14 +336,14 @@ KitInformation::ItemList DebuggerKitInformation::toUserOutput(const Kit *k) cons
return ItemList() << qMakePair(tr("Debugger"), displayString(k));
}
-FileName DebuggerKitInformation::debuggerCommand(const ProjectExplorer::Kit *k)
+FileName DebuggerKitInformation::debuggerCommand(const Kit *k)
{
const DebuggerItem *item = debugger(k);
QTC_ASSERT(item, return FileName());
return item->command();
}
-DebuggerEngineType DebuggerKitInformation::engineType(const ProjectExplorer::Kit *k)
+DebuggerEngineType DebuggerKitInformation::engineType(const Kit *k)
{
const DebuggerItem *item = debugger(k);
QTC_ASSERT(item, return NoEngineType);
diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp
index 8f433d05fd..b2610ebf43 100644
--- a/src/plugins/debugger/debuggermainwindow.cpp
+++ b/src/plugins/debugger/debuggermainwindow.cpp
@@ -89,16 +89,16 @@ public:
bool isQmlActive() const;
void setSimpleDockWidgetArrangement();
// Debuggable languages are registered with this function.
- void addLanguage(DebuggerLanguage language, const Core::Context &context);
+ void addLanguage(DebuggerLanguage language, const Context &context);
QDockWidget *dockWidget(const QString &objectName) const
{ return q->findChild<QDockWidget *>(objectName); }
public slots:
void resetDebuggerLayout();
- void updateUiForProject(ProjectExplorer::Project *project);
- void updateUiForTarget(ProjectExplorer::Target *target);
- void updateUiForRunConfiguration(ProjectExplorer::RunConfiguration *rc);
+ void updateUiForProject(Project *project);
+ void updateUiForTarget(Target *target);
+ void updateUiForRunConfiguration(RunConfiguration *rc);
void updateUiForCurrentRunConfiguration();
void updateActiveLanguages();
void updateDockWidgetSettings();
@@ -162,26 +162,24 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *mw)
void DebuggerMainWindowPrivate::updateUiForProject(Project *project)
{
if (m_previousProject) {
- disconnect(m_previousProject,
- SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
- this, SLOT(updateUiForTarget(ProjectExplorer::Target*)));
+ disconnect(m_previousProject, &Project::activeTargetChanged,
+ this, &DebuggerMainWindowPrivate::updateUiForTarget);
}
m_previousProject = project;
if (!project) {
updateUiForTarget(0);
return;
}
- connect(project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
- SLOT(updateUiForTarget(ProjectExplorer::Target*)));
+ connect(project, &Project::activeTargetChanged,
+ this, &DebuggerMainWindowPrivate::updateUiForTarget);
updateUiForTarget(project->activeTarget());
}
void DebuggerMainWindowPrivate::updateUiForTarget(Target *target)
{
if (m_previousTarget) {
- disconnect(m_previousTarget,
- SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
- this, SLOT(updateUiForRunConfiguration(ProjectExplorer::RunConfiguration*)));
+ disconnect(m_previousTarget, &Target::activeRunConfigurationChanged,
+ this, &DebuggerMainWindowPrivate::updateUiForRunConfiguration);
}
m_previousTarget = target;
@@ -191,9 +189,8 @@ void DebuggerMainWindowPrivate::updateUiForTarget(Target *target)
return;
}
- connect(target,
- SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
- SLOT(updateUiForRunConfiguration(ProjectExplorer::RunConfiguration*)));
+ connect(target, &Target::activeRunConfigurationChanged,
+ this, &DebuggerMainWindowPrivate::updateUiForRunConfiguration);
updateUiForRunConfiguration(target->activeRunConfiguration());
}
@@ -201,16 +198,15 @@ void DebuggerMainWindowPrivate::updateUiForTarget(Target *target)
void DebuggerMainWindowPrivate::updateUiForRunConfiguration(RunConfiguration *rc)
{
if (m_previousRunConfiguration)
- disconnect(m_previousRunConfiguration->extraAspect<Debugger::DebuggerRunConfigurationAspect>(),
- SIGNAL(requestRunActionsUpdate()),
- this, SLOT(updateUiForCurrentRunConfiguration()));
+ disconnect(m_previousRunConfiguration, &RunConfiguration::requestRunActionsUpdate,
+ this, &DebuggerMainWindowPrivate::updateUiForCurrentRunConfiguration);
m_previousRunConfiguration = rc;
updateUiForCurrentRunConfiguration();
if (!rc)
return;
- connect(m_previousRunConfiguration->extraAspect<Debugger::DebuggerRunConfigurationAspect>(),
- SIGNAL(requestRunActionsUpdate()),
- SLOT(updateUiForCurrentRunConfiguration()));
+
+ connect(m_previousRunConfiguration, &RunConfiguration::requestRunActionsUpdate,
+ this, &DebuggerMainWindowPrivate::updateUiForCurrentRunConfiguration);
}
void DebuggerMainWindowPrivate::updateUiForCurrentRunConfiguration()
@@ -298,30 +294,30 @@ void DebuggerMainWindow::onModeChanged(IMode *mode)
void DebuggerMainWindowPrivate::createViewsMenuItems()
{
Context debugcontext(Constants::C_DEBUGMODE);
- m_viewsMenu = Core::ActionManager::actionContainer(Id(Core::Constants::M_WINDOW_VIEWS));
+ m_viewsMenu = ActionManager::actionContainer(Id(Core::Constants::M_WINDOW_VIEWS));
QTC_ASSERT(m_viewsMenu, return);
QAction *openMemoryEditorAction = new QAction(this);
openMemoryEditorAction->setText(tr("Memory..."));
- connect(openMemoryEditorAction, SIGNAL(triggered()),
- SLOT(openMemoryEditor()));
+ connect(openMemoryEditorAction, &QAction::triggered,
+ this, &DebuggerMainWindowPrivate::openMemoryEditor);
// Add menu items
Command *cmd = 0;
- cmd = Core::ActionManager::registerAction(openMemoryEditorAction,
+ cmd = ActionManager::registerAction(openMemoryEditorAction,
"Debugger.Views.OpenMemoryEditor", debugcontext);
cmd->setAttribute(Command::CA_Hide);
m_viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
- cmd = Core::ActionManager::registerAction(q->menuSeparator1(),
+ cmd = ActionManager::registerAction(q->menuSeparator1(),
"Debugger.Views.Separator1", debugcontext);
cmd->setAttribute(Command::CA_Hide);
m_viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
- cmd = Core::ActionManager::registerAction(q->autoHideTitleBarsAction(),
+ cmd = ActionManager::registerAction(q->autoHideTitleBarsAction(),
"Debugger.Views.AutoHideTitleBars", debugcontext);
cmd->setAttribute(Command::CA_Hide);
m_viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
- cmd = Core::ActionManager::registerAction(q->menuSeparator2(),
+ cmd = ActionManager::registerAction(q->menuSeparator2(),
"Debugger.Views.Separator2", debugcontext);
cmd->setAttribute(Command::CA_Hide);
m_viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
@@ -407,8 +403,8 @@ QDockWidget *DebuggerMainWindow::createDockWidget(const DebuggerLanguage &langua
Context globalContext(Core::Constants::C_GLOBAL);
QAction *toggleViewAction = dockWidget->toggleViewAction();
- Command *cmd = Core::ActionManager::registerAction(toggleViewAction,
- Core::Id("Debugger.").withSuffix(widget->objectName()), globalContext);
+ Command *cmd = ActionManager::registerAction(toggleViewAction,
+ Id("Debugger.").withSuffix(widget->objectName()), globalContext);
cmd->setAttribute(Command::CA_Hide);
dockWidget->installEventFilter(&d->m_resizeEventFilter);
@@ -430,10 +426,10 @@ void DebuggerMainWindow::addStagedMenuEntries()
QWidget *DebuggerMainWindow::createContents(IMode *mode)
{
- connect(SessionManager::instance(), SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
- d, SLOT(updateUiForProject(ProjectExplorer::Project*)));
+ connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
+ d, &DebuggerMainWindowPrivate::updateUiForProject);
- d->m_viewsMenu = Core::ActionManager::actionContainer(Core::Id(Core::Constants::M_WINDOW_VIEWS));
+ d->m_viewsMenu = ActionManager::actionContainer(Id(Core::Constants::M_WINDOW_VIEWS));
QTC_ASSERT(d->m_viewsMenu, return 0);
//d->m_mainWindow = new Internal::DebuggerMainWindow(this);
@@ -444,17 +440,17 @@ QWidget *DebuggerMainWindow::createContents(IMode *mode)
connect(autoHideTitleBarsAction(), SIGNAL(triggered()),
d, SLOT(updateDockWidgetSettings()));
- QBoxLayout *editorHolderLayout = new QVBoxLayout;
+ auto editorHolderLayout = new QVBoxLayout;
editorHolderLayout->setMargin(0);
editorHolderLayout->setSpacing(0);
- QWidget *editorAndFindWidget = new QWidget;
+ auto editorAndFindWidget = new QWidget;
editorAndFindWidget->setLayout(editorHolderLayout);
auto editorManagerPlaceHolder = new EditorManagerPlaceHolder(mode);
editorHolderLayout->addWidget(editorManagerPlaceHolder);
editorHolderLayout->addWidget(new FindToolBarPlaceHolder(editorAndFindWidget));
- MiniSplitter *documentAndRightPane = new MiniSplitter;
+ auto documentAndRightPane = new MiniSplitter;
documentAndRightPane->addWidget(editorAndFindWidget);
documentAndRightPane->addWidget(new RightPanePlaceHolder(mode));
documentAndRightPane->setStretchFactor(0, 1);
@@ -466,18 +462,18 @@ QWidget *DebuggerMainWindow::createContents(IMode *mode)
hackyName.replace(QLatin1Char('&'), QString());
d->m_viewButton->setText(hackyName);
- Utils::StyledBar *debugToolBar = new Utils::StyledBar;
+ auto debugToolBar = new Utils::StyledBar;
debugToolBar->setProperty("topBorder", true);
- QHBoxLayout *debugToolBarLayout = new QHBoxLayout(debugToolBar);
+ auto debugToolBarLayout = new QHBoxLayout(debugToolBar);
debugToolBarLayout->setMargin(0);
debugToolBarLayout->setSpacing(0);
debugToolBarLayout->addWidget(d->m_debugToolBar);
debugToolBarLayout->addWidget(new Utils::StyledSeparator);
debugToolBarLayout->addWidget(d->m_viewButton);
- connect(d->m_viewButton, SIGNAL(clicked()), this, SLOT(showViewsMenu()));
+ connect(d->m_viewButton, &QAbstractButton::clicked, this, &DebuggerMainWindow::showViewsMenu);
- QDockWidget *dock = new QDockWidget(DebuggerMainWindowPrivate::tr("Debugger Toolbar"));
+ auto dock = new QDockWidget(DebuggerMainWindowPrivate::tr("Debugger Toolbar"));
dock->setObjectName(QLatin1String("Debugger Toolbar"));
dock->setWidget(debugToolBar);
dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
@@ -487,10 +483,10 @@ QWidget *DebuggerMainWindow::createContents(IMode *mode)
addDockWidget(Qt::BottomDockWidgetArea, dock);
setToolBarDockWidget(dock);
- QWidget *centralWidget = new QWidget;
+ auto centralWidget = new QWidget;
setCentralWidget(centralWidget);
- QVBoxLayout *centralLayout = new QVBoxLayout(centralWidget);
+ auto centralLayout = new QVBoxLayout(centralWidget);
centralWidget->setLayout(centralLayout);
centralLayout->setMargin(0);
centralLayout->setSpacing(0);
@@ -499,9 +495,9 @@ QWidget *DebuggerMainWindow::createContents(IMode *mode)
centralLayout->setStretch(1, 0);
// Right-side window with editor, output etc.
- MiniSplitter *mainWindowSplitter = new MiniSplitter;
+ auto mainWindowSplitter = new MiniSplitter;
mainWindowSplitter->addWidget(this);
- QWidget *outputPane = new OutputPanePlaceHolder(mode, mainWindowSplitter);
+ auto outputPane = new OutputPanePlaceHolder(mode, mainWindowSplitter);
outputPane->setObjectName(QLatin1String("DebuggerOutputPanePlaceHolder"));
mainWindowSplitter->addWidget(outputPane);
mainWindowSplitter->setStretchFactor(0, 10);
@@ -509,7 +505,7 @@ QWidget *DebuggerMainWindow::createContents(IMode *mode)
mainWindowSplitter->setOrientation(Qt::Vertical);
// Navigation and right-side window.
- MiniSplitter *splitter = new MiniSplitter;
+ auto splitter = new MiniSplitter;
splitter->setFocusProxy(editorManagerPlaceHolder);
splitter->addWidget(new NavigationWidgetPlaceHolder(mode));
splitter->addWidget(mainWindowSplitter);
diff --git a/src/plugins/debugger/debuggermainwindow.h b/src/plugins/debugger/debuggermainwindow.h
index 1dbf5f4712..c6a0e1118c 100644
--- a/src/plugins/debugger/debuggermainwindow.h
+++ b/src/plugins/debugger/debuggermainwindow.h
@@ -36,16 +36,11 @@
#include <utils/fancymainwindow.h>
-namespace Core {
-class Context;
-class IMode;
-}
+namespace Core { class IMode; }
namespace Debugger {
-
-class DebuggerEngine;
-
namespace Internal {
+
class DebuggerMainWindowPrivate;
// DebuggerMainWindow dock widget names
diff --git a/src/plugins/debugger/debuggeroptionspage.cpp b/src/plugins/debugger/debuggeroptionspage.cpp
index d0b04a9b32..0484757ca8 100644
--- a/src/plugins/debugger/debuggeroptionspage.cpp
+++ b/src/plugins/debugger/debuggeroptionspage.cpp
@@ -29,15 +29,14 @@
****************************************************************************/
#include "debuggeroptionspage.h"
-
#include "debuggeritemmanager.h"
-#include "debuggeritemmodel.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/detailswidget.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
+#include <utils/treemodel.h>
#include <utils/winutils.h>
#include <QFileInfo>
@@ -55,19 +54,176 @@ using namespace Utils;
namespace Debugger {
namespace Internal {
-static const char debuggingToolsWikiLinkC[] = "http://qt-project.org/wiki/Qt_Creator_Windows_Debugging";
+const char debuggingToolsWikiLinkC[] = "http://qt-project.org/wiki/Qt_Creator_Windows_Debugging";
+
+// --------------------------------------------------------------------------
+// DebuggerTreeItem
+// --------------------------------------------------------------------------
+
+class DebuggerTreeItem : public TreeItem
+{
+public:
+ DebuggerTreeItem(const DebuggerItem &item, bool changed) : m_item(item), m_changed(changed) {}
+
+ QVariant data(int column, int role) const
+ {
+ switch (role) {
+ case Qt::DisplayRole:
+ switch (column) {
+ case 0: return m_item.displayName();
+ case 1: return m_item.command().toUserOutput();
+ case 2: return m_item.engineTypeName();
+ }
+
+ case Qt::FontRole: {
+ QFont font;
+ font.setBold(m_changed);
+ return font;
+ }
+ }
+ return QVariant();
+ }
+
+ DebuggerItem m_item;
+ bool m_changed;
+};
+
+// --------------------------------------------------------------------------
+// DebuggerItemModel
+// --------------------------------------------------------------------------
+
+class DebuggerItemModel : public TreeModel
+{
+ Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage)
+
+public:
+ DebuggerItemModel();
+
+ QModelIndex lastIndex() const;
+ void setCurrentIndex(const QModelIndex &index);
+ DebuggerItem *currentDebugger() const;
+ void addDebugger(const DebuggerItem &item, bool changed);
+ void updateDebugger(const DebuggerItem &item);
+ void removeCurrentDebugger();
+ void apply();
+
+private:
+ DebuggerTreeItem *m_currentTreeItem;
+ QStringList removed;
+
+ QList<QVariant> m_removedItems;
+};
+
+DebuggerItemModel::DebuggerItemModel()
+ : m_currentTreeItem(0)
+{
+ setHeader(QStringList() << tr("Name") << tr("Location") << tr("Type"));
+ rootItem()->appendChild(new TreeItem(QStringList() << tr("Auto-detected") << QString() << QString()));
+ rootItem()->appendChild(new TreeItem(QStringList() << tr("Manual") << QString() << QString()));
+
+ foreach (const DebuggerItem &item, DebuggerItemManager::debuggers())
+ addDebugger(item, false);
+}
+
+void DebuggerItemModel::addDebugger(const DebuggerItem &item, bool changed)
+{
+ int group = item.isAutoDetected() ? 0 : 1;
+ rootItem()->child(group)->appendChild(new DebuggerTreeItem(item, changed));
+}
+
+void DebuggerItemModel::updateDebugger(const DebuggerItem &item)
+{
+ auto matcher = [item](DebuggerTreeItem *n) { return n->m_item.m_id == item.id(); };
+ DebuggerTreeItem *treeItem = findItemAtLevel<DebuggerTreeItem *>(2, matcher);
+ QTC_ASSERT(treeItem, return);
+
+ TreeItem *parent = treeItem->parent();
+ QTC_ASSERT(parent, return);
+
+ const DebuggerItem *orig = DebuggerItemManager::findById(item.id());
+ treeItem->m_changed = !orig || *orig != item;
+ treeItem->m_item = item;
+ treeItem->update(); // Notify views.
+}
+
+QModelIndex DebuggerItemModel::lastIndex() const
+{
+ TreeItem *manualGroup = rootItem()->lastChild();
+ TreeItem *lastItem = manualGroup->lastChild();
+ return lastItem ? indexFromItem(lastItem) : QModelIndex();
+}
+
+DebuggerItem *DebuggerItemModel::currentDebugger() const
+{
+ return m_currentTreeItem ? &m_currentTreeItem->m_item : 0;
+}
+
+void DebuggerItemModel::removeCurrentDebugger()
+{
+ QTC_ASSERT(m_currentTreeItem, return);
+ QVariant id = m_currentTreeItem->m_item.id();
+ DebuggerTreeItem *treeItem = m_currentTreeItem;
+ m_currentTreeItem = 0;
+ removeItem(treeItem);
+ delete treeItem;
+ m_removedItems.append(id);
+}
+
+void DebuggerItemModel::apply()
+{
+ foreach (const QVariant &id, m_removedItems)
+ DebuggerItemManager::deregisterDebugger(id);
+
+ foreach (auto item, treeLevelItems<DebuggerTreeItem *>(2)) {
+ item->m_changed = false;
+ DebuggerItemManager::updateOrAddDebugger(item->m_item);
+ }
+}
+
+void DebuggerItemModel::setCurrentIndex(const QModelIndex &index)
+{
+ TreeItem *treeItem = itemFromIndex(index);
+ m_currentTreeItem = treeItem && treeItem->level() == 2 ? static_cast<DebuggerTreeItem *>(treeItem) : 0;
+}
// -----------------------------------------------------------------------
// DebuggerItemConfigWidget
// -----------------------------------------------------------------------
-DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) :
- m_model(model)
+class DebuggerItemConfigWidget : public QWidget
+{
+ Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage)
+
+public:
+ explicit DebuggerItemConfigWidget(DebuggerItemModel *model);
+ void load(const DebuggerItem *item);
+ void store() const;
+
+private:
+ void binaryPathHasChanged();
+ DebuggerItem item() const;
+ void setAbis(const QStringList &abiNames);
+
+ DebuggerItemModel *m_model;
+ QLineEdit *m_displayNameLineEdit;
+ QLineEdit *m_typeLineEdit;
+ QLabel *m_cdbLabel;
+ QLineEdit *m_versionLabel;
+ PathChooser *m_binaryChooser;
+ QLineEdit *m_abis;
+ bool m_autodetected;
+ DebuggerEngineType m_engineType;
+ QVariant m_id;
+};
+
+DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model)
+ : m_model(model)
{
- QTC_CHECK(model);
-
m_displayNameLineEdit = new QLineEdit(this);
+ m_typeLineEdit = new QLineEdit(this);
+ m_typeLineEdit->setEnabled(false);
+
m_binaryChooser = new PathChooser(this);
m_binaryChooser->setExpectedKind(PathChooser::ExistingCommand);
m_binaryChooser->setMinimumWidth(400);
@@ -87,21 +243,21 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) :
QFormLayout *formLayout = new QFormLayout(this);
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit);
-// formLayout->addRow(new QLabel(tr("Type:")), m_engineTypeComboBox);
formLayout->addRow(m_cdbLabel);
formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser);
+ formLayout->addRow(new QLabel(tr("Type:")), m_typeLineEdit);
formLayout->addRow(new QLabel(tr("ABIs:")), m_abis);
formLayout->addRow(new QLabel(tr("Version:")), m_versionLabel);
- connect(m_binaryChooser, SIGNAL(changed(QString)), this, SLOT(binaryPathHasChanged()));
+ connect(m_binaryChooser, &PathChooser::changed,
+ this, &DebuggerItemConfigWidget::binaryPathHasChanged);
+ connect(m_displayNameLineEdit, &QLineEdit::textChanged,
+ this, &DebuggerItemConfigWidget::store);
}
DebuggerItem DebuggerItemConfigWidget::item() const
{
DebuggerItem item(m_id);
- if (m_id.isNull())
- return item;
-
item.setDisplayName(m_displayNameLineEdit->text());
item.setCommand(m_binaryChooser->fileName());
item.setAutoDetected(m_autodetected);
@@ -117,12 +273,10 @@ DebuggerItem DebuggerItemConfigWidget::item() const
return item;
}
-
void DebuggerItemConfigWidget::store() const
{
- DebuggerItem i = item();
- if (i.isValid())
- m_model->updateDebugger(i);
+ if (!m_id.isNull())
+ m_model->updateDebugger(item());
}
void DebuggerItemConfigWidget::setAbis(const QStringList &abiNames)
@@ -130,50 +284,26 @@ void DebuggerItemConfigWidget::setAbis(const QStringList &abiNames)
m_abis->setText(abiNames.join(QLatin1String(", ")));
}
-void DebuggerItemConfigWidget::handleCommandChange()
+void DebuggerItemConfigWidget::load(const DebuggerItem *item)
{
- // Use DebuggerItemManager as a cache:
- const DebuggerItem *existing
- = DebuggerItemManager::findByCommand(m_binaryChooser->fileName());
- if (existing) {
- setAbis(existing->abiNames());
- m_versionLabel->setText(existing->version());
- m_engineType = existing->engineType();
- } else {
- QFileInfo fi = QFileInfo(m_binaryChooser->path());
- if (fi.isExecutable()) {
- DebuggerItem tmp = item();
- tmp.reinitializeFromFile();
- setAbis(tmp.abiNames());
- m_versionLabel->setText(tmp.version());
- m_engineType = tmp.engineType();
- } else {
- setAbis(QStringList());
- m_versionLabel->setText(QString());
- m_engineType = NoEngineType;
- }
- }
- m_model->updateDebugger(item());
-}
-
-void DebuggerItemConfigWidget::setItem(const DebuggerItem &item)
-{
- store(); // store away the (changed) settings for future use
-
m_id = QVariant(); // reset Id to avoid intermediate signal handling
+ if (!item)
+ return;
// Set values:
- m_autodetected = item.isAutoDetected();
+ m_autodetected = item->isAutoDetected();
- m_displayNameLineEdit->setEnabled(!item.isAutoDetected());
- m_displayNameLineEdit->setText(item.displayName());
+ m_displayNameLineEdit->setEnabled(!item->isAutoDetected());
+ m_displayNameLineEdit->setText(item->displayName());
- m_binaryChooser->setReadOnly(item.isAutoDetected());
- m_binaryChooser->setFileName(item.command());
+ m_typeLineEdit->setText(item->engineTypeName());
+
+ m_binaryChooser->setReadOnly(item->isAutoDetected());
+ m_binaryChooser->setFileName(item->command());
QString text;
QString versionCommand;
- if (item.engineType() == CdbEngineType) {
+ if (item->engineType() == CdbEngineType) {
const bool is64bit = is64BitWindowsSystem();
const QString versionString = is64bit ? tr("64-bit version") : tr("32-bit version");
//: Label text for path configuration. %2 is "x-bit version".
@@ -189,20 +319,10 @@ void DebuggerItemConfigWidget::setItem(const DebuggerItem &item)
m_cdbLabel->setText(text);
m_cdbLabel->setVisible(!text.isEmpty());
m_binaryChooser->setCommandVersionArguments(QStringList(versionCommand));
- m_versionLabel->setText(item.version());
- setAbis(item.abiNames());
- m_engineType = item.engineType();
- m_id = item.id();
-}
-
-void DebuggerItemConfigWidget::apply()
-{
- DebuggerItem current = m_model->currentDebugger();
- if (!current.isValid())
- return; // Nothing was selected here.
-
- store();
- setItem(item());
+ m_versionLabel->setText(item->version());
+ setAbis(item->abiNames());
+ m_engineType = item->engineType();
+ m_id = item->id();
}
void DebuggerItemConfigWidget::binaryPathHasChanged()
@@ -211,58 +331,57 @@ void DebuggerItemConfigWidget::binaryPathHasChanged()
if (!m_id.isValid())
return;
- handleCommandChange();
+ DebuggerItem tmp;
+ QFileInfo fi = QFileInfo(m_binaryChooser->path());
+ if (fi.isExecutable()) {
+ tmp = item();
+ tmp.reinitializeFromFile();
+ }
+
+ setAbis(tmp.abiNames());
+ m_versionLabel->setText(tmp.version());
+ m_engineType = tmp.engineType();
+ m_typeLineEdit->setText(tmp.engineTypeName());
+
+ store();
}
// --------------------------------------------------------------------------
-// DebuggerOptionsPage
+// DebuggerConfigWidget
// --------------------------------------------------------------------------
-DebuggerOptionsPage::DebuggerOptionsPage()
+class DebuggerConfigWidget : public QWidget
{
- m_model = 0;
- m_debuggerView = 0;
- m_container = 0;
- m_addButton = 0;
- m_cloneButton = 0;
- m_delButton = 0;
+public:
+ DebuggerConfigWidget()
+ {
+ m_addButton = new QPushButton(tr("Add"), this);
- setId(ProjectExplorer::Constants::DEBUGGER_SETTINGS_PAGE_ID);
- setDisplayName(tr("Debuggers"));
- setCategory(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
- setDisplayCategory(QCoreApplication::translate("ProjectExplorer",
- ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_TR_CATEGORY));
- setCategoryIcon(QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY_ICON));
-}
-
-QWidget *DebuggerOptionsPage::widget()
-{
- if (!m_configWidget) {
- m_configWidget = new QWidget;
+ m_cloneButton = new QPushButton(tr("Clone"), this);
+ m_cloneButton->setEnabled(false);
- m_addButton = new QPushButton(tr("Add"), m_configWidget);
- m_cloneButton = new QPushButton(tr("Clone"), m_configWidget);
- m_delButton = new QPushButton(tr("Remove"), m_configWidget);
+ m_delButton = new QPushButton(tr("Remove"), this);
+ m_delButton->setEnabled(false);
- m_container = new DetailsWidget(m_configWidget);
+ m_container = new DetailsWidget(this);
m_container->setState(DetailsWidget::NoSummary);
m_container->setVisible(false);
- m_debuggerView = new QTreeView(m_configWidget);
- m_model = new DebuggerItemModel(m_debuggerView);
- m_debuggerView->setModel(m_model);
+ m_debuggerView = new QTreeView(this);
+ m_debuggerView->setModel(&m_model);
m_debuggerView->setUniformRowHeights(true);
+ m_debuggerView->setRootIsDecorated(false);
m_debuggerView->setSelectionMode(QAbstractItemView::SingleSelection);
m_debuggerView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_debuggerView->expandAll();
- QHeaderView *header = m_debuggerView->header();
+ auto header = m_debuggerView->header();
header->setStretchLastSection(false);
header->setSectionResizeMode(0, QHeaderView::ResizeToContents);
header->setSectionResizeMode(1, QHeaderView::ResizeToContents);
header->setSectionResizeMode(2, QHeaderView::Stretch);
- QVBoxLayout *buttonLayout = new QVBoxLayout();
+ auto buttonLayout = new QVBoxLayout();
buttonLayout->setSpacing(6);
buttonLayout->setContentsMargins(0, 0, 0, 0);
buttonLayout->addWidget(m_addButton);
@@ -270,54 +389,62 @@ QWidget *DebuggerOptionsPage::widget()
buttonLayout->addWidget(m_delButton);
buttonLayout->addItem(new QSpacerItem(10, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
- QVBoxLayout *verticalLayout = new QVBoxLayout();
+ auto verticalLayout = new QVBoxLayout();
verticalLayout->addWidget(m_debuggerView);
verticalLayout->addWidget(m_container);
- QHBoxLayout *horizontalLayout = new QHBoxLayout(m_configWidget);
+ auto horizontalLayout = new QHBoxLayout(this);
horizontalLayout->addLayout(verticalLayout);
horizontalLayout->addLayout(buttonLayout);
- connect(m_debuggerView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(debuggerSelectionChanged()));
+ connect(m_debuggerView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &DebuggerConfigWidget::currentDebuggerChanged, Qt::QueuedConnection);
- connect(m_addButton, SIGNAL(clicked()), this, SLOT(addDebugger()), Qt::QueuedConnection);
- connect(m_cloneButton, SIGNAL(clicked()), this, SLOT(cloneDebugger()), Qt::QueuedConnection);
- connect(m_delButton, SIGNAL(clicked()), this, SLOT(removeDebugger()), Qt::QueuedConnection);
+ connect(m_addButton, &QAbstractButton::clicked,
+ this, &DebuggerConfigWidget::addDebugger, Qt::QueuedConnection);
+ connect(m_cloneButton, &QAbstractButton::clicked,
+ this, &DebuggerConfigWidget::cloneDebugger, Qt::QueuedConnection);
+ connect(m_delButton, &QAbstractButton::clicked,
+ this, &DebuggerConfigWidget::removeDebugger, Qt::QueuedConnection);
- m_itemConfigWidget = new DebuggerItemConfigWidget(m_model);
+ m_itemConfigWidget = new DebuggerItemConfigWidget(&m_model);
m_container->setWidget(m_itemConfigWidget);
-
- updateState();
}
- return m_configWidget;
-}
-void DebuggerOptionsPage::apply()
+ void cloneDebugger();
+ void addDebugger();
+ void removeDebugger();
+ void currentDebuggerChanged(const QModelIndex &newCurrent);
+ void updateState();
+
+ DebuggerItemModel m_model;
+ QTreeView *m_debuggerView;
+ QPushButton *m_addButton;
+ QPushButton *m_cloneButton;
+ QPushButton *m_delButton;
+ DetailsWidget *m_container;
+ DebuggerItemConfigWidget *m_itemConfigWidget;
+};
+
+void DebuggerConfigWidget::cloneDebugger()
{
- m_itemConfigWidget->apply();
- m_model->apply();
-}
-
-void DebuggerOptionsPage::cloneDebugger()
-{
- DebuggerItem item = m_model->currentDebugger();
- if (!item.isValid())
+ DebuggerItem *item = m_model.currentDebugger();
+ if (!item)
return;
DebuggerItem newItem;
newItem.createId();
newItem.setAutoDetected(false);
- newItem.setCommand(item.command());
- newItem.setEngineType(item.engineType());
- newItem.setAbis(item.abis());
- newItem.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("Clone of %1").arg(item.displayName())));
+ newItem.setCommand(item->command());
+ newItem.setEngineType(item->engineType());
+ newItem.setAbis(item->abis());
+ newItem.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("Clone of %1").arg(item->displayName())));
newItem.setAutoDetected(false);
- m_model->addDebugger(newItem);
- m_debuggerView->setCurrentIndex(m_model->lastIndex());
+ m_model.addDebugger(newItem, true);
+ m_debuggerView->setCurrentIndex(m_model.lastIndex());
}
-void DebuggerOptionsPage::addDebugger()
+void DebuggerConfigWidget::addDebugger()
{
DebuggerItem item;
item.createId();
@@ -325,72 +452,60 @@ void DebuggerOptionsPage::addDebugger()
item.setEngineType(NoEngineType);
item.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("New Debugger")));
item.setAutoDetected(false);
- m_model->addDebugger(item);
- m_debuggerView->setCurrentIndex(m_model->lastIndex());
+ m_model.addDebugger(item, true);
+ m_debuggerView->setCurrentIndex(m_model.lastIndex());
}
-void DebuggerOptionsPage::removeDebugger()
+void DebuggerConfigWidget::removeDebugger()
{
- QVariant id = m_model->currentDebuggerId();
- m_model->removeDebugger(id);
- m_debuggerView->setCurrentIndex(m_model->lastIndex());
+ m_model.removeCurrentDebugger();
+ m_debuggerView->setCurrentIndex(m_model.lastIndex());
}
-void DebuggerOptionsPage::finish()
+void DebuggerConfigWidget::currentDebuggerChanged(const QModelIndex &newCurrent)
{
- delete m_configWidget;
-
- // Children of m_configWidget.
- m_model = 0;
- m_container = 0;
- m_debuggerView = 0;
- m_addButton = 0;
- m_cloneButton = 0;
- m_delButton = 0;
-}
+ m_model.setCurrentIndex(newCurrent);
-void DebuggerOptionsPage::debuggerSelectionChanged()
-{
- QTC_ASSERT(m_container, return);
+ DebuggerItem *item = m_model.currentDebugger();
- QModelIndex mi = m_debuggerView->currentIndex();
- mi = mi.sibling(mi.row(), 0);
- m_model->setCurrentIndex(mi);
+ m_itemConfigWidget->load(item);
+ m_container->setVisible(item);
+ m_cloneButton->setEnabled(item && item->isValid() && item->canClone());
+ m_delButton->setEnabled(item && !item->isAutoDetected());
+}
- DebuggerItem item = m_model->currentDebugger();
+// --------------------------------------------------------------------------
+// DebuggerOptionsPage
+// --------------------------------------------------------------------------
- m_itemConfigWidget->setItem(item);
- m_container->setVisible(item.isValid());
- updateState();
+DebuggerOptionsPage::DebuggerOptionsPage()
+{
+ setId(ProjectExplorer::Constants::DEBUGGER_SETTINGS_PAGE_ID);
+ setDisplayName(tr("Debuggers"));
+ setCategory(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
+ setDisplayCategory(QCoreApplication::translate("ProjectExplorer",
+ ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_TR_CATEGORY));
+ setCategoryIcon(QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY_ICON));
}
-void DebuggerOptionsPage::debuggerModelChanged()
+QWidget *DebuggerOptionsPage::widget()
{
- QTC_ASSERT(m_container, return);
-
- QVariant id = m_model->currentDebuggerId();
- const DebuggerItem *item = DebuggerItemManager::findById(id);
- if (!item)
- return;
-
- m_itemConfigWidget->setItem(*item);
- m_container->setVisible(m_model->currentDebuggerId().isValid());
- m_debuggerView->setCurrentIndex(m_model->currentIndex());
- updateState();
+ if (!m_configWidget)
+ m_configWidget = new DebuggerConfigWidget;
+ return m_configWidget;
}
-void DebuggerOptionsPage::updateState()
+void DebuggerOptionsPage::apply()
{
- if (!m_cloneButton)
- return;
-
- DebuggerItem item = m_model->currentDebugger();
-
- bool canCopy = item.isValid() && item.canClone();
- bool canDelete = m_model->currentIndex().parent().isValid() && !item.isAutoDetected();
+ QTC_ASSERT(m_configWidget, return);
+ m_configWidget->m_itemConfigWidget->store();
+ m_configWidget->m_model.apply();
+}
- m_cloneButton->setEnabled(canCopy);
- m_delButton->setEnabled(canDelete);
+void DebuggerOptionsPage::finish()
+{
+ delete m_configWidget;
+ m_configWidget = 0;
}
} // namespace Internal
diff --git a/src/plugins/debugger/debuggeroptionspage.h b/src/plugins/debugger/debuggeroptionspage.h
index df9b169853..5db065b49c 100644
--- a/src/plugins/debugger/debuggeroptionspage.h
+++ b/src/plugins/debugger/debuggeroptionspage.h
@@ -31,73 +31,19 @@
#ifndef DEBUGGER_DEBUGGEROPTIONSPAGE_H
#define DEBUGGER_DEBUGGEROPTIONSPAGE_H
-#include "debuggeritem.h"
-
#include <coreplugin/dialogs/ioptionspage.h>
+#include <QCoreApplication>
#include <QPointer>
-#include <QWidget>
-
-QT_BEGIN_NAMESPACE
-class QLabel;
-class QLineEdit;
-class QPushButton;
-class QTreeView;
-QT_END_NAMESPACE
-
-namespace Utils {
-class DetailsWidget;
-class PathChooser;
-} // namespace Utils
namespace Debugger {
namespace Internal {
-class DebuggerItemModel;
-class DebuggerItemConfigWidget;
-class DebuggerKitConfigWidget;
-
-// -----------------------------------------------------------------------
-// DebuggerItemConfigWidget
-// -----------------------------------------------------------------------
-
-class DebuggerItemConfigWidget : public QWidget
-{
- Q_OBJECT
-
-public:
- explicit DebuggerItemConfigWidget(DebuggerItemModel *model);
- void setItem(const DebuggerItem &item);
- void apply();
-
-private slots:
- void binaryPathHasChanged();
-
-private:
- DebuggerItem item() const;
- void store() const;
- void setAbis(const QStringList &abiNames);
-
- void handleCommandChange();
-
- QLineEdit *m_displayNameLineEdit;
- QLabel *m_cdbLabel;
- QLineEdit *m_versionLabel;
- Utils::PathChooser *m_binaryChooser;
- QLineEdit *m_abis;
- DebuggerItemModel *m_model;
- bool m_autodetected;
- DebuggerEngineType m_engineType;
- QVariant m_id;
-};
-
-// --------------------------------------------------------------------------
-// DebuggerOptionsPage
-// --------------------------------------------------------------------------
+class DebuggerConfigWidget;
class DebuggerOptionsPage : public Core::IOptionsPage
{
- Q_OBJECT
+ Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage)
public:
DebuggerOptionsPage();
@@ -106,24 +52,8 @@ public:
void apply();
void finish();
-private slots:
- void debuggerSelectionChanged();
- void debuggerModelChanged();
- void updateState();
- void cloneDebugger();
- void addDebugger();
- void removeDebugger();
-
private:
- QPointer<QWidget> m_configWidget;
-
- DebuggerItemModel *m_model;
- DebuggerItemConfigWidget *m_itemConfigWidget;
- QTreeView *m_debuggerView;
- Utils::DetailsWidget *m_container;
- QPushButton *m_addButton;
- QPushButton *m_cloneButton;
- QPushButton *m_delButton;
+ QPointer<DebuggerConfigWidget> m_configWidget;
};
} // namespace Internal
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index aaddbd5e9d..6ab869034c 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -78,6 +78,7 @@
#include <coreplugin/imode.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
+#include <coreplugin/messagebox.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/modemanager.h>
@@ -93,6 +94,7 @@
#include <projectexplorer/devicesupport/deviceprocesslist.h>
#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projecttree.h>
#include <projectexplorer/projectexplorersettings.h>
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
@@ -387,19 +389,6 @@ namespace PE = ProjectExplorer::Constants;
namespace Debugger {
namespace Internal {
-// To be passed through margin menu action's data
-struct BreakpointMenuContextData : public ContextData
-{
- enum Mode
- {
- Breakpoint,
- MessageTracePoint
- };
-
- BreakpointMenuContextData() : mode(Breakpoint) {}
- Mode mode;
-};
-
struct TestCallBack
{
TestCallBack() : receiver(0), slot(0) {}
@@ -414,27 +403,13 @@ struct TestCallBack
} // namespace Internal
} // namespace Debugger
-Q_DECLARE_METATYPE(Debugger::Internal::BreakpointMenuContextData)
Q_DECLARE_METATYPE(Debugger::Internal::TestCallBack)
-
namespace Debugger {
namespace Internal {
-// FIXME: Outdated?
-// The createCdbEngine function takes a list of options pages it can add to.
-// This allows for having a "enabled" toggle on the page independently
-// of the engine. That's good for not enabling the related ActiveX control
-// unnecessarily.
-
void addCdbOptionPages(QList<IOptionsPage*> *opts);
void addGdbOptionPages(QList<IOptionsPage*> *opts);
-void addScriptOptionPages(QList<IOptionsPage*> *opts);
-void addTcfOptionPages(QList<IOptionsPage*> *opts);
-
-#ifdef WITH_LLDB
-void addLldbOptionPages(QList<IOptionsPage*> *opts);
-#endif
static QToolButton *toolButton(QAction *action)
{
@@ -443,12 +418,12 @@ static QToolButton *toolButton(QAction *action)
return button;
}
-static void setProxyAction(ProxyAction *proxy, Core::Id id)
+static void setProxyAction(ProxyAction *proxy, Id id)
{
proxy->setAction(ActionManager::command(id)->action());
}
-static QToolButton *toolButton(Core::Id id)
+static QToolButton *toolButton(Id id)
{
return toolButton(ActionManager::command(id)->action());
}
@@ -461,8 +436,6 @@ static QToolButton *toolButton(Core::Id id)
class DummyEngine : public DebuggerEngine
{
- Q_OBJECT
-
public:
DummyEngine() : DebuggerEngine(DebuggerStartParameters()) {}
~DummyEngine() {}
@@ -473,7 +446,7 @@ public:
void shutdownEngine() {}
void shutdownInferior() {}
bool hasCapability(unsigned cap) const;
- bool acceptsBreakpoint(BreakpointModelId) const { return false; }
+ bool acceptsBreakpoint(Breakpoint) const { return false; }
bool acceptsDebuggerCommands() const { return false; }
void selectThread(ThreadId) {}
};
@@ -481,7 +454,7 @@ public:
bool DummyEngine::hasCapability(unsigned cap) const
{
// This can only be a first approximation of what to expect when running.
- Project *project = ProjectExplorerPlugin::currentProject();
+ Project *project = ProjectTree::currentProject();
if (!project)
return 0;
Target *target = project->activeTarget();
@@ -494,6 +467,7 @@ bool DummyEngine::hasCapability(unsigned cap) const
return cap & (WatchpointByAddressCapability
| BreakConditionCapability
| TracePointCapability
+ | OperateNativeMixed
| OperateByInstructionCapability);
// This is a Qml or unknown engine.
@@ -578,7 +552,7 @@ static bool currentTextEditorPosition(ContextData *data)
return false;
const TextDocument *document = textEditor->textDocument();
QTC_ASSERT(document, return false);
- data->fileName = document->filePath();
+ data->fileName = document->filePath().toString();
if (document->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()) {
int lineNumber = textEditor->currentLine();
QString line = textEditor->textDocument()->plainText()
@@ -639,7 +613,6 @@ public:
}
DebuggerRunControl *attachToRunningProcess(Kit *kit, DeviceProcessItem process);
-public slots:
void writeSettings()
{
m_debuggerSettings->writeSettings();
@@ -652,20 +625,16 @@ public slots:
m_currentEngine->selectThread(id);
}
- void breakpointSetMarginActionTriggered()
+ void breakpointSetMarginActionTriggered(bool isMessageOnly, const ContextData &data)
{
- const QAction *action = qobject_cast<const QAction *>(sender());
- QTC_ASSERT(action, return);
- const BreakpointMenuContextData data =
- action->data().value<BreakpointMenuContextData>();
QString message;
- if (data.mode == BreakpointMenuContextData::MessageTracePoint) {
+ if (isMessageOnly) {
if (data.address) {
//: Message tracepoint: Address hit.
message = tr("0x%1 hit").arg(data.address, 0, 16);
} else {
//: Message tracepoint: %1 file, %2 line %3 function hit.
- message = tr("%1:%2 %3() hit").arg(QFileInfo(data.fileName).fileName()).
+ message = tr("%1:%2 %3() hit").arg(FileName::fromString(data.fileName).fileName()).
arg(data.lineNumber).
arg(cppFunctionAt(data.fileName, data.lineNumber));
}
@@ -686,30 +655,6 @@ public slots:
toggleBreakpointByFileAndLine(data.fileName, data.lineNumber, message);
}
- void breakpointRemoveMarginActionTriggered()
- {
- const QAction *act = qobject_cast<QAction *>(sender());
- QTC_ASSERT(act, return);
- BreakpointModelId id = act->data().value<BreakpointModelId>();
- m_breakHandler->removeBreakpoint(id);
- }
-
- void breakpointEnableMarginActionTriggered()
- {
- const QAction *act = qobject_cast<QAction *>(sender());
- QTC_ASSERT(act, return);
- BreakpointModelId id = act->data().value<BreakpointModelId>();
- breakHandler()->setEnabled(id, true);
- }
-
- void breakpointDisableMarginActionTriggered()
- {
- const QAction *act = qobject_cast<QAction *>(sender());
- QTC_ASSERT(act, return);
- BreakpointModelId id = act->data().value<BreakpointModelId>();
- breakHandler()->setEnabled(id, false);
- }
-
void updateWatchersHeader(int section, int, int newSize)
{
m_watchersView->header()->resizeSection(section, newSize);
@@ -743,12 +688,12 @@ public slots:
}
}
- void editorOpened(Core::IEditor *editor);
- void updateBreakMenuItem(Core::IEditor *editor);
+ void editorOpened(IEditor *editor);
+ void updateBreakMenuItem(IEditor *editor);
void setBusyCursor(bool busy);
- void requestMark(TextEditor::TextEditorWidget *widget, int lineNumber,
- TextEditor::TextMarkRequestKind kind);
- void requestContextMenu(TextEditor::TextEditorWidget *widget,
+ void requestMark(TextEditorWidget *widget, int lineNumber,
+ TextMarkRequestKind kind);
+ void requestContextMenu(TextEditorWidget *widget,
int lineNumber, QMenu *menu);
void activatePreviousMode();
@@ -758,7 +703,7 @@ public slots:
const QString &tracePointMessage = QString());
void toggleBreakpointByAddress(quint64 address,
const QString &tracePointMessage = QString());
- void onModeChanged(Core::IMode *mode);
+ void onModeChanged(IMode *mode);
void onCoreAboutToOpen();
void showSettingsDialog();
void updateDebugWithoutDeployMenu();
@@ -776,7 +721,7 @@ public slots:
void attachToFoundProcess();
void continueOnAttach(Debugger::DebuggerState state);
void attachToQmlPort();
- void runScheduled();
+ Q_SLOT void runScheduled();
void attachCore();
void enableReverseDebuggingTriggered(const QVariant &value);
@@ -800,11 +745,11 @@ public slots:
void cleanupViews();
void setInitialState();
- void fontSettingsChanged(const TextEditor::FontSettings &settings);
+ void fontSettingsChanged(const FontSettings &settings);
void updateState(DebuggerEngine *engine);
void updateWatchersWindow(bool showWatch, bool showReturn);
- void onCurrentProjectChanged(ProjectExplorer::Project *project);
+ void onCurrentProjectChanged(Project *project);
void sessionLoaded();
void aboutToUnloadSession();
@@ -815,7 +760,7 @@ public slots:
#ifdef WITH_TESTS
public slots:
void testLoadProject(const QString &proFile, const TestCallBack &cb);
- void testProjectLoaded(ProjectExplorer::Project *project);
+ void testProjectLoaded(Project *project);
void testProjectEvaluated();
void testProjectBuilt(bool success);
void testUnloadProject();
@@ -957,31 +902,6 @@ public slots:
}
}
- void slotEditBreakpoint()
- {
- const QAction *act = qobject_cast<QAction *>(sender());
- QTC_ASSERT(act, return);
- const BreakpointModelId id = act->data().value<BreakpointModelId>();
- QTC_ASSERT(id > 0, return);
- BreakTreeView::editBreakpoint(id, ICore::dialogParent());
- }
-
- void slotRunToLine()
- {
- const QAction *action = qobject_cast<const QAction *>(sender());
- QTC_ASSERT(action, return);
- const BreakpointMenuContextData data = action->data().value<BreakpointMenuContextData>();
- currentEngine()->executeRunToLine(data);
- }
-
- void slotJumpToLine()
- {
- const QAction *action = qobject_cast<const QAction *>(sender());
- QTC_ASSERT(action, return);
- const BreakpointMenuContextData data = action->data().value<BreakpointMenuContextData>();
- currentEngine()->executeJumpToLine(data);
- }
-
void slotDisassembleFunction()
{
const QAction *action = qobject_cast<const QAction *>(sender());
@@ -1356,9 +1276,9 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
// Cpp/Qml ui setup
m_mainWindow = new DebuggerMainWindow;
- TaskHub::addCategory(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO,
+ TaskHub::addCategory(TASK_CATEGORY_DEBUGGER_DEBUGINFO,
tr("Debug Information"));
- TaskHub::addCategory(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME,
+ TaskHub::addCategory(TASK_CATEGORY_DEBUGGER_RUNTIME,
tr("Debugger Runtime"));
return true;
@@ -1410,7 +1330,7 @@ void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project)
m_startAction->setEnabled(canRun);
m_startAction->setToolTip(whyNot);
m_debugWithoutDeployAction->setEnabled(canRun);
- setProxyAction(m_visibleStartAction, Core::Id(Constants::DEBUG));
+ setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
}
void DebuggerPluginPrivate::debugProject()
@@ -1521,7 +1441,7 @@ void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
DebuggerKitChooser::RemoteDebugging : DebuggerKitChooser::LocalDebugging;
DebuggerKitChooser *kitChooser = new DebuggerKitChooser(mode);
DeviceProcessesDialog *dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
- dlg->addAcceptButton(ProjectExplorer::DeviceProcessesDialog::tr("&Attach to Process"));
+ dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
dlg->showAllDevices();
if (dlg->exec() == QDialog::Rejected) {
delete dlg;
@@ -1588,8 +1508,8 @@ DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
QTC_ASSERT(device, return 0);
if (process.pid == 0) {
- QMessageBox::warning(ICore::dialogParent(), tr("Warning"),
- tr("Cannot attach to process with PID 0"));
+ AsynchronousMessageBox::warning(tr("Warning"),
+ tr("Cannot attach to process with PID 0"));
return 0;
}
@@ -1597,14 +1517,14 @@ DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
if (const ToolChain *tc = ToolChainKitInformation::toolChain(kit))
isWindows = tc->targetAbi().os() == Abi::WindowsOS;
if (isWindows && isWinProcessBeingDebugged(process.pid)) {
- QMessageBox::warning(ICore::mainWindow(), tr("Process Already Under Debugger Control"),
+ AsynchronousMessageBox::warning(tr("Process Already Under Debugger Control"),
tr("The process %1 is already under the control of a debugger.\n"
"Qt Creator cannot attach to it.").arg(process.pid));
return 0;
}
if (device->type() != PE::DESKTOP_DEVICE_TYPE) {
- QMessageBox::warning(ICore::mainWindow(), tr("Not a Desktop Device Type"),
+ AsynchronousMessageBox::warning(tr("Not a Desktop Device Type"),
tr("It is only possible to attach to a locally running process."));
return 0;
}
@@ -1727,13 +1647,13 @@ void DebuggerPluginPrivate::updateBreakMenuItem(IEditor *editor)
void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
int lineNumber, QMenu *menu)
{
- BreakpointMenuContextData args;
+ ContextData args;
args.lineNumber = lineNumber;
bool contextUsable = true;
- BreakpointModelId id = BreakpointModelId();
+ Breakpoint bp;
TextDocument *document = widget->textDocument();
- args.fileName = document->filePath();
+ args.fileName = document->filePath().toString();
if (document->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()) {
QString line = document->plainText()
.section(QLatin1Char('\n'), lineNumber - 1, lineNumber - 1);
@@ -1742,87 +1662,77 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
needle.address = DisassemblerLine::addressFromDisassemblyLine(line);
args.address = needle.address;
needle.lineNumber = -1;
- id = breakHandler()->findSimilarBreakpoint(needle);
+ bp = breakHandler()->findSimilarBreakpoint(needle);
contextUsable = args.address != 0;
} else {
- id = breakHandler()
+ bp = breakHandler()
->findBreakpointByFileAndLine(args.fileName, lineNumber);
- if (!id)
- id = breakHandler()->findBreakpointByFileAndLine(args.fileName, lineNumber, false);
+ if (!bp)
+ bp = breakHandler()->findBreakpointByFileAndLine(args.fileName, lineNumber, false);
}
- if (id) {
+ if (bp) {
+ QString id = bp.id().toString();
+
// Remove existing breakpoint.
- QAction *act = new QAction(menu);
- act->setData(QVariant::fromValue(id));
- act->setText(tr("Remove Breakpoint %1").arg(id.toString()));
- connect(act, SIGNAL(triggered()),
- SLOT(breakpointRemoveMarginActionTriggered()));
- menu->addAction(act);
+ auto act = menu->addAction(tr("Remove Breakpoint %1").arg(id));
+ connect(act, &QAction::triggered, [bp] { bp.removeBreakpoint(); });
// Enable/disable existing breakpoint.
- act = new QAction(menu);
- act->setData(QVariant::fromValue(id));
- if (breakHandler()->isEnabled(id)) {
- act->setText(tr("Disable Breakpoint %1").arg(id.toString()));
- connect(act, SIGNAL(triggered()),
- SLOT(breakpointDisableMarginActionTriggered()));
+ if (bp.isEnabled()) {
+ act = menu->addAction(tr("Disable Breakpoint %1").arg(id));
+ connect(act, &QAction::triggered, [bp] { bp.setEnabled(false); });
} else {
- act->setText(tr("Enable Breakpoint %1").arg(id.toString()));
- connect(act, SIGNAL(triggered()),
- SLOT(breakpointEnableMarginActionTriggered()));
+ act = menu->addAction(tr("Enable Breakpoint %1").arg(id));
+ connect(act, &QAction::triggered, [bp] { bp.setEnabled(true); });
}
- menu->addAction(act);
// Edit existing breakpoint.
- act = new QAction(menu);
- act->setText(tr("Edit Breakpoint %1...").arg(id.toString()));
- connect(act, SIGNAL(triggered()), SLOT(slotEditBreakpoint()));
- act->setData(QVariant::fromValue(id));
- menu->addAction(act);
+ act = menu->addAction(tr("Edit Breakpoint %1...").arg(id));
+ connect(act, &QAction::triggered, [bp] {
+ BreakTreeView::editBreakpoint(bp, ICore::dialogParent());
+ });
+
} else {
// Handle non-existing breakpoint.
const QString text = args.address
? tr("Set Breakpoint at 0x%1").arg(args.address, 0, 16)
: tr("Set Breakpoint at Line %1").arg(lineNumber);
- QAction *act = new QAction(text, menu);
- act->setData(QVariant::fromValue(args));
+ auto act = menu->addAction(text);
act->setEnabled(contextUsable);
- connect(act, SIGNAL(triggered()),
- SLOT(breakpointSetMarginActionTriggered()));
- menu->addAction(act);
+ connect(act, &QAction::triggered, [this, args] {
+ breakpointSetMarginActionTriggered(false, args);
+ });
+
// Message trace point
- args.mode = BreakpointMenuContextData::MessageTracePoint;
const QString tracePointText = args.address
? tr("Set Message Tracepoint at 0x%1...").arg(args.address, 0, 16)
: tr("Set Message Tracepoint at Line %1...").arg(lineNumber);
- act = new QAction(tracePointText, menu);
- act->setData(QVariant::fromValue(args));
+ act = menu->addAction(tracePointText);
act->setEnabled(contextUsable);
- connect(act, SIGNAL(triggered()),
- SLOT(breakpointSetMarginActionTriggered()));
- menu->addAction(act);
+ connect(act, &QAction::triggered, [this, args] {
+ breakpointSetMarginActionTriggered(true, args);
+ });
}
+
// Run to, jump to line below in stopped state.
if (currentEngine()->state() == InferiorStopOk && contextUsable) {
menu->addSeparator();
if (currentEngine()->hasCapability(RunToLineCapability)) {
- const QString runText = args.address
+ auto act = menu->addAction(args.address
? DebuggerEngine::tr("Run to Address 0x%1").arg(args.address, 0, 16)
- : DebuggerEngine::tr("Run to Line %1").arg(args.lineNumber);
- QAction *runToLineAction = new QAction(runText, menu);
- runToLineAction->setData(QVariant::fromValue(args));
- connect(runToLineAction, SIGNAL(triggered()), SLOT(slotRunToLine()));
- menu->addAction(runToLineAction);
+ : DebuggerEngine::tr("Run to Line %1").arg(args.lineNumber));
+ connect(act, &QAction::triggered, [this, args] {
+ currentEngine()->executeRunToLine(args);
+ });
}
if (currentEngine()->hasCapability(JumpToLineCapability)) {
- const QString jumpText = args.address
+ auto act = menu->addAction(args.address
? DebuggerEngine::tr("Jump to Address 0x%1").arg(args.address, 0, 16)
- : DebuggerEngine::tr("Jump to Line %1").arg(args.lineNumber);
- QAction *jumpToLineAction = new QAction(jumpText, menu);
- jumpToLineAction->setData(QVariant::fromValue(args));
- connect(jumpToLineAction, SIGNAL(triggered()), SLOT(slotJumpToLine()));
- menu->addAction(jumpToLineAction);
+ : DebuggerEngine::tr("Jump to Line %1").arg(args.lineNumber));
+ connect(act, &QAction::triggered, [this, args] {
+ currentEngine()->executeJumpToLine(args);
+ });
}
// Disassemble current function in stopped state.
if (currentEngine()->state() == InferiorStopOk
@@ -1835,7 +1745,7 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
.arg(frame.function);
QAction *disassembleAction = new QAction(text, menu);
disassembleAction->setData(QVariant::fromValue(frame));
- connect(disassembleAction, SIGNAL(triggered()), SLOT(slotDisassembleFunction()));
+ connect(disassembleAction, &QAction::triggered, this, &DebuggerPluginPrivate::slotDisassembleFunction);
menu->addAction(disassembleAction );
}
}
@@ -1853,7 +1763,7 @@ void DebuggerPluginPrivate::toggleBreakpoint()
quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
toggleBreakpointByAddress(address);
} else if (lineNumber >= 0) {
- toggleBreakpointByFileAndLine(textEditor->document()->filePath(), lineNumber);
+ toggleBreakpointByFileAndLine(textEditor->document()->filePath().toString(), lineNumber);
}
}
@@ -1861,13 +1771,12 @@ void DebuggerPluginPrivate::toggleBreakpointByFileAndLine(const QString &fileNam
int lineNumber, const QString &tracePointMessage)
{
BreakHandler *handler = m_breakHandler;
- BreakpointModelId id =
- handler->findBreakpointByFileAndLine(fileName, lineNumber, true);
- if (!id)
- id = handler->findBreakpointByFileAndLine(fileName, lineNumber, false);
+ Breakpoint bp = handler->findBreakpointByFileAndLine(fileName, lineNumber, true);
+ if (!bp)
+ bp = handler->findBreakpointByFileAndLine(fileName, lineNumber, false);
- if (id) {
- handler->removeBreakpoint(id);
+ if (bp) {
+ bp.removeBreakpoint();
} else {
BreakpointParameters data(BreakpointByFileAndLine);
if (boolSetting(BreakpointsFullPathByDefault))
@@ -1884,10 +1793,8 @@ void DebuggerPluginPrivate::toggleBreakpointByAddress(quint64 address,
const QString &tracePointMessage)
{
BreakHandler *handler = m_breakHandler;
- BreakpointModelId id = handler->findBreakpointByAddress(address);
-
- if (id) {
- handler->removeBreakpoint(id);
+ if (Breakpoint bp = handler->findBreakpointByAddress(address)) {
+ bp.removeBreakpoint();
} else {
BreakpointParameters data(BreakpointByAddress);
data.tracepoint = !tracePointMessage.isEmpty();
@@ -1910,7 +1817,7 @@ void DebuggerPluginPrivate::requestMark(TextEditorWidget *widget, int lineNumber
quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
toggleBreakpointByAddress(address);
} else {
- toggleBreakpointByFileAndLine(document->filePath(), lineNumber);
+ toggleBreakpointByFileAndLine(document->filePath().toString(), lineNumber);
}
}
@@ -1958,7 +1865,7 @@ static void changeFontSize(QWidget *widget, qreal size)
}
void DebuggerPluginPrivate::fontSettingsChanged
- (const TextEditor::FontSettings &settings)
+ (const FontSettings &settings)
{
if (!boolSetting(FontSizeFollowsEditor))
return;
@@ -1992,7 +1899,7 @@ void DebuggerPluginPrivate::cleanupViews()
bool keepIt = true;
if (document->isModified())
keepIt = true;
- else if (document->filePath().contains(_("qeventdispatcher")))
+ else if (document->filePath().toString().contains(_("qeventdispatcher")))
keepIt = false;
else if (isMemory)
keepIt = !closeMemory;
@@ -2069,7 +1976,6 @@ void DebuggerPluginPrivate::setInitialState()
action(AutoDerefPointers)->setEnabled(true);
action(ExpandStack)->setEnabled(false);
-
}
void DebuggerPluginPrivate::updateWatchersWindow(bool showWatch, bool showReturn)
@@ -2107,7 +2013,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
m_exitAction->setEnabled(false);
m_startAction->setEnabled(true);
m_debugWithoutDeployAction->setEnabled(true);
- setProxyAction(m_visibleStartAction, Core::Id(Constants::DEBUG));
+ setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
m_hiddenStopAction->setAction(m_undisturbableAction);
} else if (state == InferiorStopOk) {
// F5 continues, Shift-F5 kills. It is "continuable".
@@ -2116,7 +2022,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
m_exitAction->setEnabled(true);
m_startAction->setEnabled(false);
m_debugWithoutDeployAction->setEnabled(false);
- setProxyAction(m_visibleStartAction, Core::Id(Constants::CONTINUE));
+ setProxyAction(m_visibleStartAction, Id(Constants::CONTINUE));
m_hiddenStopAction->setAction(m_exitAction);
m_localsAndExpressionsWindow->setShowLocals(true);
} else if (state == InferiorRunOk) {
@@ -2126,7 +2032,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
m_exitAction->setEnabled(true);
m_startAction->setEnabled(false);
m_debugWithoutDeployAction->setEnabled(false);
- setProxyAction(m_visibleStartAction, Core::Id(Constants::INTERRUPT));
+ setProxyAction(m_visibleStartAction, Id(Constants::INTERRUPT));
m_hiddenStopAction->setAction(m_interruptAction);
m_localsAndExpressionsWindow->setShowLocals(false);
} else if (state == DebuggerFinished) {
@@ -2138,7 +2044,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
m_exitAction->setEnabled(false);
m_startAction->setEnabled(canRun);
m_debugWithoutDeployAction->setEnabled(canRun);
- setProxyAction(m_visibleStartAction, Core::Id(Constants::DEBUG));
+ setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
m_hiddenStopAction->setAction(m_undisturbableAction);
m_codeModelSnapshot = CPlusPlus::Snapshot();
setBusyCursor(false);
@@ -2526,16 +2432,27 @@ QMessageBox *showMessageBox(int icon, const QString &title,
return mb;
}
+bool isNativeMixedEnabled()
+{
+ static bool enabled = qEnvironmentVariableIsSet("QTC_DEBUGGER_NATIVE_MIXED");
+ return enabled;
+}
+
+bool isNativeMixedActive()
+{
+ return isNativeMixedEnabled() && boolSetting(OperateNativeMixed);
+}
+
void DebuggerPluginPrivate::extensionsInitialized()
{
const QKeySequence debugKey = QKeySequence(UseMacShortcuts ? tr("Ctrl+Y") : tr("F5"));
- QSettings *settings = Core::ICore::settings();
+ QSettings *settings = ICore::settings();
m_debuggerSettings = new DebuggerSettings;
m_debuggerSettings->readSettings();
- connect(ICore::instance(), SIGNAL(coreAboutToClose()), this, SLOT(coreShutdown()));
+ connect(ICore::instance(), &ICore::coreAboutToClose, this, &DebuggerPluginPrivate::coreShutdown);
const Context globalcontext(CC::C_GLOBAL);
const Context cppDebuggercontext(C_CPPDEBUGGER);
@@ -2608,22 +2525,22 @@ void DebuggerPluginPrivate::extensionsInitialized()
m_snapshotWindow = addSearch(m_snapshotView, tr("Snapshots"), DOCKWIDGET_SNAPSHOTS);
// Watchers
- connect(m_localsView->header(), SIGNAL(sectionResized(int,int,int)),
- SLOT(updateWatchersHeader(int,int,int)), Qt::QueuedConnection);
+ connect(m_localsView->header(), &QHeaderView::sectionResized,
+ this, &DebuggerPluginPrivate::updateWatchersHeader, Qt::QueuedConnection);
QAction *act = 0;
act = m_continueAction = new QAction(tr("Continue"), this);
act->setIcon(m_continueIcon);
- connect(act, SIGNAL(triggered()), SLOT(handleExecContinue()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecContinue);
act = m_exitAction = new QAction(tr("Stop Debugger"), this);
act->setIcon(m_exitIcon);
- connect(act, SIGNAL(triggered()), SLOT(handleExecExit()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecExit);
act = m_interruptAction = new QAction(tr("Interrupt"), this);
act->setIcon(m_interruptIcon);
- connect(act, SIGNAL(triggered()), SLOT(handleExecInterrupt()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecInterrupt);
// A "disabled pause" seems to be a good choice.
act = m_undisturbableAction = new QAction(tr("Debugger is Busy"), this);
@@ -2633,46 +2550,46 @@ void DebuggerPluginPrivate::extensionsInitialized()
act = m_abortAction = new QAction(tr("Abort Debugging"), this);
act->setToolTip(tr("Aborts debugging and "
"resets the debugger to the initial state."));
- connect(act, SIGNAL(triggered()), SLOT(handleAbort()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleAbort);
act = m_resetAction = new QAction(tr("Restart Debugging"),this);
act->setToolTip(tr("Restart the debugging session."));
act->setIcon(m_resetIcon);
- connect(act,SIGNAL(triggered()),SLOT(handleReset()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleReset);
act = m_nextAction = new QAction(tr("Step Over"), this);
act->setIcon(QIcon(QLatin1String(":/debugger/images/debugger_stepover_small.png")));
- connect(act, SIGNAL(triggered()), SLOT(handleExecNext()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecNext);
act = m_stepAction = new QAction(tr("Step Into"), this);
act->setIcon(QIcon(QLatin1String(":/debugger/images/debugger_stepinto_small.png")));
- connect(act, SIGNAL(triggered()), SLOT(handleExecStep()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecStep);
act = m_stepOutAction = new QAction(tr("Step Out"), this);
act->setIcon(QIcon(QLatin1String(":/debugger/images/debugger_stepout_small.png")));
- connect(act, SIGNAL(triggered()), SLOT(handleExecStepOut()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecStepOut);
act = m_runToLineAction = new QAction(tr("Run to Line"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleExecRunToLine()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecRunToLine);
act = m_runToSelectedFunctionAction =
new QAction(tr("Run to Selected Function"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleExecRunToSelectedFunction()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecRunToSelectedFunction);
act = m_returnFromFunctionAction =
new QAction(tr("Immediately Return From Inner Function"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleExecReturn()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecReturn);
act = m_jumpToLineAction = new QAction(tr("Jump to Line"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleExecJumpToLine()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecJumpToLine);
m_breakAction = new QAction(tr("Toggle Breakpoint"), this);
act = m_watchAction1 = new QAction(tr("Add Expression Evaluator"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleAddToWatchWindow);
act = m_watchAction2 = new QAction(tr("Add Expression Evaluator"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleAddToWatchWindow);
//m_snapshotAction = new QAction(tr("Create Snapshot"), this);
//m_snapshotAction->setProperty(Role, RequestCreateSnapshotRole);
@@ -2688,10 +2605,10 @@ void DebuggerPluginPrivate::extensionsInitialized()
act->setIconVisibleInMenu(false);
act = m_frameDownAction = new QAction(tr("Move to Called Frame"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleFrameDown()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleFrameDown);
act = m_frameUpAction = new QAction(tr("Move to Calling Frame"), this);
- connect(act, SIGNAL(triggered()), SLOT(handleFrameUp()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleFrameUp);
connect(action(OperateByInstruction), SIGNAL(triggered(bool)),
SLOT(handleOperateByInstructionTriggered(bool)));
@@ -2701,16 +2618,16 @@ void DebuggerPluginPrivate::extensionsInitialized()
// Dock widgets
QDockWidget *dock = 0;
dock = m_mainWindow->createDockWidget(CppLanguage, m_modulesWindow);
- connect(dock->toggleViewAction(), SIGNAL(toggled(bool)),
- SLOT(modulesDockToggled(bool)), Qt::QueuedConnection);
+ connect(dock->toggleViewAction(), &QAction::toggled,
+ this, &DebuggerPluginPrivate::modulesDockToggled, Qt::QueuedConnection);
dock = m_mainWindow->createDockWidget(CppLanguage, m_registerWindow);
- connect(dock->toggleViewAction(), SIGNAL(toggled(bool)),
- SLOT(registerDockToggled(bool)), Qt::QueuedConnection);
+ connect(dock->toggleViewAction(), &QAction::toggled,
+ this, &DebuggerPluginPrivate::registerDockToggled, Qt::QueuedConnection);
dock = m_mainWindow->createDockWidget(CppLanguage, m_sourceFilesWindow);
- connect(dock->toggleViewAction(), SIGNAL(toggled(bool)),
- SLOT(sourceFilesDockToggled(bool)), Qt::QueuedConnection);
+ connect(dock->toggleViewAction(), &QAction::toggled,
+ this, &DebuggerPluginPrivate::sourceFilesDockToggled, Qt::QueuedConnection);
dock = m_mainWindow->createDockWidget(AnyLanguage, m_logWindow);
dock->setProperty(DOCKWIDGET_DEFAULT_AREA, Qt::TopDockWidgetArea);
@@ -2741,49 +2658,49 @@ void DebuggerPluginPrivate::extensionsInitialized()
debuggerIcon.addFile(QLatin1String(":/projectexplorer/images/debugger_start.png"));
act->setIcon(debuggerIcon);
act->setText(tr("Start Debugging"));
- connect(act, SIGNAL(triggered()), this, SLOT(debugProject()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::debugProject);
act = m_debugWithoutDeployAction = new QAction(this);
act->setText(tr("Start Debugging Without Deployment"));
- connect(act, SIGNAL(triggered()), this, SLOT(debugProjectWithoutDeploy()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::debugProjectWithoutDeploy);
act = m_startAndDebugApplicationAction = new QAction(this);
act->setText(tr("Start and Debug External Application..."));
- connect(act, SIGNAL(triggered()), SLOT(startAndDebugApplication()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startAndDebugApplication);
act = m_attachToCoreAction = new QAction(this);
act->setText(tr("Load Core File..."));
- connect(act, SIGNAL(triggered()), SLOT(attachCore()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachCore);
act = m_attachToRemoteServerAction = new QAction(this);
act->setText(tr("Attach to Remote Debug Server..."));
- connect(act, SIGNAL(triggered()), SLOT(attachToRemoteServer()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRemoteServer);
act = m_startRemoteServerAction = new QAction(this);
act->setText(tr("Start Remote Debug Server Attached to Process..."));
- connect(act, SIGNAL(triggered()), SLOT(startRemoteServer()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startRemoteServer);
act = m_attachToRunningApplication = new QAction(this);
act->setText(tr("Attach to Running Application..."));
- connect(act, SIGNAL(triggered()), SLOT(attachToRunningApplication()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRunningApplication);
act = m_attachToUnstartedApplication = new QAction(this);
act->setText(tr("Attach to Unstarted Application..."));
- connect(act, SIGNAL(triggered()), SLOT(attachToUnstartedApplicationDialog()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToUnstartedApplicationDialog);
act = m_attachToQmlPortAction = new QAction(this);
act->setText(tr("Attach to QML Port..."));
- connect(act, SIGNAL(triggered()), SLOT(attachToQmlPort()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToQmlPort);
if (HostOsInfo::isWindowsHost()) {
m_startRemoteCdbAction = new QAction(tr("Attach to Remote CDB Session..."), this);
- connect(m_startRemoteCdbAction, SIGNAL(triggered()),
- SLOT(startRemoteCdbSession()));
+ connect(m_startRemoteCdbAction, &QAction::triggered,
+ this, &DebuggerPluginPrivate::startRemoteCdbSession);
}
act = m_detachAction = new QAction(this);
act->setText(tr("Detach Debugger"));
- connect(act, SIGNAL(triggered()), SLOT(handleExecDetach()));
+ connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecDetach);
// "Start Debugging" sub-menu
// groups:
@@ -2816,17 +2733,17 @@ void DebuggerPluginPrivate::extensionsInitialized()
cmd = ActionManager::registerAction(m_attachToRunningApplication,
"Debugger.AttachToRemoteProcess", globalcontext);
cmd->setDescription(tr("Attach to Running Application"));
- mstart->addAction(cmd, Debugger::Constants::G_GENERAL);
+ mstart->addAction(cmd, G_GENERAL);
cmd = ActionManager::registerAction(m_attachToUnstartedApplication,
"Debugger.AttachToUnstartedProcess", globalcontext);
cmd->setDescription(tr("Attach to Unstarted Application"));
- mstart->addAction(cmd, Debugger::Constants::G_GENERAL);
+ mstart->addAction(cmd, G_GENERAL);
cmd = ActionManager::registerAction(m_startAndDebugApplicationAction,
"Debugger.StartAndDebugApplication", globalcontext);
cmd->setAttribute(Command::CA_Hide);
- mstart->addAction(cmd, Debugger::Constants::G_GENERAL);
+ mstart->addAction(cmd, G_GENERAL);
cmd = ActionManager::registerAction(m_attachToCoreAction,
"Debugger.AttachCore", globalcontext);
@@ -2964,12 +2881,23 @@ void DebuggerPluginPrivate::extensionsInitialized()
cmd->setAttribute(Command::CA_Hide);
debugMenu->addAction(cmd);
+ if (isNativeMixedEnabled()) {
+ SavedAction *act = action(OperateNativeMixed);
+ act->setValue(true);
+ cmd = ActionManager::registerAction(act,
+ Constants::OPERATE_NATIVE_MIXED, globalcontext);
+ cmd->setAttribute(Command::CA_Hide);
+ debugMenu->addAction(cmd);
+ connect(cmd->action(), &QAction::triggered,
+ [this] { currentEngine()->updateAll(); });
+ }
+
cmd = ActionManager::registerAction(m_breakAction,
"Debugger.ToggleBreak", globalcontext);
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("F8") : tr("F9")));
debugMenu->addAction(cmd);
- connect(m_breakAction, SIGNAL(triggered()),
- SLOT(toggleBreakpoint()));
+ connect(m_breakAction, &QAction::triggered,
+ this, &DebuggerPluginPrivate::toggleBreakpoint);
debugMenu->addSeparator(globalcontext);
@@ -3032,32 +2960,26 @@ void DebuggerPluginPrivate::extensionsInitialized()
QList<IOptionsPage *> engineOptionPages;
addGdbOptionPages(&engineOptionPages);
addCdbOptionPages(&engineOptionPages);
-#ifdef WITH_LLDB
- addLldbOptionPages(&engineOptionPages);
-#endif
-
- // addScriptOptionPages(&engineOptionPages);
- // addTcfOptionPages(&engineOptionPages);
foreach (IOptionsPage *op, engineOptionPages)
m_plugin->addAutoReleasedObject(op);
m_plugin->addAutoReleasedObject(new LocalsAndExpressionsOptionsPage);
m_plugin->addAutoReleasedObject(new DebuggerOptionsPage);
- connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
- SLOT(onModeChanged(Core::IMode*)));
- connect(ICore::instance(), SIGNAL(coreAboutToOpen()),
- SLOT(onCoreAboutToOpen()));
- connect(ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
- this, SLOT(updateDebugWithoutDeployMenu()));
+ connect(ModeManager::instance(), &ModeManager::currentModeChanged,
+ this, &DebuggerPluginPrivate::onModeChanged);
+ connect(ICore::instance(), &ICore::coreAboutToOpen,
+ this, &DebuggerPluginPrivate::onCoreAboutToOpen);
+ connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
+ this, &DebuggerPluginPrivate::updateDebugWithoutDeployMenu);
// Debug mode setup
DebugMode *debugMode = new DebugMode;
QWidget *widget = m_mainWindow->createContents(debugMode);
- Core::IContext *modeContextObject = new Core::IContext(this);
- modeContextObject->setContext(Core::Context(CC::C_EDITORMANAGER));
+ IContext *modeContextObject = new IContext(this);
+ modeContextObject->setContext(Context(CC::C_EDITORMANAGER));
modeContextObject->setWidget(widget);
- Core::ICore::addContextObject(modeContextObject);
+ ICore::addContextObject(modeContextObject);
debugMode->setWidget(widget);
m_plugin->addAutoReleasedObject(debugMode);
@@ -3112,6 +3034,8 @@ void DebuggerPluginPrivate::extensionsInitialized()
hbox->addWidget(toolButton(Constants::STEPOUT));
hbox->addWidget(toolButton(Constants::RESET));
hbox->addWidget(toolButton(Constants::OPERATE_BY_INSTRUCTION));
+ if (isNativeMixedEnabled())
+ hbox->addWidget(toolButton(Constants::OPERATE_NATIVE_MIXED));
//hbox->addWidget(new StyledSeparator);
m_reverseToolButton = toolButton(Constants::REVERSE);
@@ -3347,8 +3271,11 @@ bool isDockVisible(const QString &objectName)
void openMemoryEditor()
{
AddressDialog dialog;
- if (dialog.exec() == QDialog::Accepted)
- currentEngine()->openMemoryView(dialog.address(), 0, QList<MemoryMarkup>(), QPoint());
+ if (dialog.exec() == QDialog::Accepted) {
+ MemoryViewSetupData data;
+ data.startAddress = dialog.address();
+ currentEngine()->openMemoryView(data);
+ }
}
void setThreads(const QStringList &list, int index)
@@ -3437,7 +3364,7 @@ void DebuggerPlugin::extensionsInitialized()
void DebuggerPluginPrivate::testLoadProject(const QString &proFile, const TestCallBack &cb)
{
- connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::currentProjectChanged,
+ connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
this, &DebuggerPluginPrivate::testProjectLoaded);
m_testCallbacks.append(cb);
@@ -3471,7 +3398,7 @@ void DebuggerPluginPrivate::testProjectEvaluated()
QVERIFY(!fileName.isEmpty());
qWarning("Project %s loaded", qPrintable(fileName));
connect(BuildManager::instance(), SIGNAL(buildQueueFinished(bool)),
- SLOT(testProjectBuilt(bool)));
+ this, SLOT(testProjectBuilt(bool)));
ProjectExplorerPlugin::buildProject(m_testProject);
}
@@ -3578,7 +3505,7 @@ void DebuggerPluginPrivate::testBenchmark1()
{
#ifdef WITH_BENCHMARK
CALLGRIND_START_INSTRUMENTATION;
- volatile Core::Id id1 = Core::Id(DEBUGGER_COMMON_SETTINGS_ID);
+ volatile Id id1 = Id(DEBUGGER_COMMON_SETTINGS_ID);
CALLGRIND_STOP_INSTRUMENTATION;
CALLGRIND_DUMP_STATS;
diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp
index 3bb5db075c..5393e89d8f 100644
--- a/src/plugins/debugger/debuggerprotocol.cpp
+++ b/src/plugins/debugger/debuggerprotocol.cpp
@@ -395,19 +395,19 @@ qulonglong GdbMi::toAddress() const
//
//////////////////////////////////////////////////////////////////////////////////
-QByteArray GdbResponse::stringFromResultClass(GdbResultClass resultClass)
+QByteArray DebuggerResponse::stringFromResultClass(ResultClass resultClass)
{
switch (resultClass) {
- case GdbResultDone: return "done";
- case GdbResultRunning: return "running";
- case GdbResultConnected: return "connected";
- case GdbResultError: return "error";
- case GdbResultExit: return "exit";
+ case ResultDone: return "done";
+ case ResultRunning: return "running";
+ case ResultConnected: return "connected";
+ case ResultError: return "error";
+ case ResultExit: return "exit";
default: return "unknown";
}
}
-QByteArray GdbResponse::toString() const
+QByteArray DebuggerResponse::toString() const
{
QByteArray result;
if (token != -1)
@@ -716,10 +716,136 @@ QString decodeData(const QByteArray &ba, int encoding)
}
return dateTime.toString();
}
+ case Hex2EncodedFloat4: {
+ const QByteArray s = QByteArray::fromHex(ba);
+ QTC_ASSERT(s.size() == 4, break);
+ union { char c[4]; float f; } u = { { s[3], s[2], s[1], s[0] } };
+ return QString::number(u.f);
+ }
+ case Hex2EncodedFloat8: {
+ const QByteArray s = QByteArray::fromHex(ba);
+ QTC_ASSERT(s.size() == 8, break);
+ union { char c[8]; double d; } u = { { s[7], s[6], s[5], s[4], s[3], s[2], s[1], s[0] } };
+ return QString::number(u.d);
+ }
}
qDebug() << "ENCODING ERROR: " << encoding;
return QCoreApplication::translate("Debugger", "<Encoding error>");
}
+//////////////////////////////////////////////////////////////////////////////////
+//
+// DebuggerCommand
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+void DebuggerCommand::argHelper(const char *name, const QByteArray &data)
+{
+ args.append('"');
+ args.append(name);
+ args.append("\":");
+ args.append(data);
+ args.append(",");
+}
+
+QByteArray DebuggerCommand::toData(const QList<QByteArray> &value)
+{
+ QByteArray res;
+ foreach (const QByteArray &item, value) {
+ if (!res.isEmpty())
+ res.append(',');
+ res += item;
+ }
+ return '[' + res + ']';
+}
+
+QByteArray DebuggerCommand::toData(const QHash<QByteArray, QByteArray> &value)
+{
+ QByteArray res;
+ QHashIterator<QByteArray, QByteArray> it(value);
+ while (it.hasNext()) {
+ it.next();
+ if (!res.isEmpty())
+ res.append(',');
+ res += '"' + it.key() + "\":" + it.value();
+ }
+ return '{' + res + '}';
+}
+
+void DebuggerCommand::arg(const char *name, int value)
+{
+ argHelper(name, QByteArray::number(value));
+}
+
+void DebuggerCommand::arg(const char *name, qlonglong value)
+{
+ argHelper(name, QByteArray::number(value));
+}
+
+void DebuggerCommand::arg(const char *name, qulonglong value)
+{
+ argHelper(name, QByteArray::number(value));
+}
+
+void DebuggerCommand::arg(const char *name, const QString &value)
+{
+ arg(name, value.toUtf8().data());
+}
+
+void DebuggerCommand::arg(const char *name, const QByteArray &value)
+{
+ arg(name, value.data());
+}
+
+void DebuggerCommand::arg(const char *name, const char *value)
+{
+ args.append('"');
+ args.append(name);
+ args.append("\":\"");
+ args.append(value);
+ args.append("\",");
+}
+
+void DebuggerCommand::arg(const char *value)
+{
+ args.append("\"");
+ args.append(value);
+ args.append("\",");
+}
+
+void DebuggerCommand::beginList(const char *name)
+{
+ if (name) {
+ args += '"';
+ args += name;
+ args += "\":";
+ }
+ args += '[';
+}
+
+void DebuggerCommand::endList()
+{
+ if (args.endsWith(','))
+ args.chop(1);
+ args += "],";
+}
+
+void DebuggerCommand::beginGroup(const char *name)
+{
+ if (name) {
+ args += '"';
+ args += name;
+ args += "\":";
+ }
+ args += '{';
+}
+
+void DebuggerCommand::endGroup()
+{
+ if (args.endsWith(','))
+ args.chop(1);
+ args += "},";
+}
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerprotocol.h b/src/plugins/debugger/debuggerprotocol.h
index dc8908fe13..943fe8b442 100644
--- a/src/plugins/debugger/debuggerprotocol.h
+++ b/src/plugins/debugger/debuggerprotocol.h
@@ -32,10 +32,52 @@
#define DEBUGGER_PROTOCOL_H
#include <QVariant>
+#include <QTime>
+
+#include <functional>
namespace Debugger {
namespace Internal {
+class DebuggerResponse;
+
+// Convenience structure to build up backend commands.
+class DebuggerCommand
+{
+public:
+ typedef std::function<void(const DebuggerResponse &)> Callback;
+
+ DebuggerCommand() : flags(0) {}
+ DebuggerCommand(const char *f, int flags = 0, Callback cb = Callback())
+ : function(f), callback(cb), flags(flags)
+ {}
+ DebuggerCommand(const QByteArray &f) : function(f), flags(0) {}
+
+ void arg(const char *name);
+ void arg(const char *name, int value);
+ void arg(const char *name, qlonglong value);
+ void arg(const char *name, qulonglong value);
+ void arg(const char *name, const QString &value);
+ void arg(const char *name, const QByteArray &value);
+ void arg(const char *name, const char *value);
+ void beginList(const char *name = 0);
+ void endList();
+ void beginGroup(const char *name = 0);
+ void endGroup();
+
+ static QByteArray toData(const QList<QByteArray> &value);
+ static QByteArray toData(const QHash<QByteArray, QByteArray> &value);
+
+ QByteArray function;
+ QByteArray args;
+ Callback callback;
+ QTime postTime;
+ int flags;
+
+private:
+ void argHelper(const char *name, const QByteArray &value);
+};
+
/*
output ==>
@@ -141,28 +183,27 @@ public:
void dumpChildren(QByteArray *str, bool multiline, int indent) const;
};
-enum GdbResultClass
+enum ResultClass
{
// "done" | "running" | "connected" | "error" | "exit"
- GdbResultUnknown,
- GdbResultDone,
- GdbResultRunning,
- GdbResultConnected,
- GdbResultError,
- GdbResultExit
+ ResultUnknown,
+ ResultDone,
+ ResultRunning,
+ ResultConnected,
+ ResultError,
+ ResultExit
};
-class GdbResponse
+class DebuggerResponse
{
public:
- GdbResponse() : token(-1), resultClass(GdbResultUnknown) {}
+ DebuggerResponse() : token(-1), resultClass(ResultUnknown) {}
QByteArray toString() const;
- static QByteArray stringFromResultClass(GdbResultClass resultClass);
+ static QByteArray stringFromResultClass(ResultClass resultClass);
int token;
- GdbResultClass resultClass;
+ ResultClass resultClass;
GdbMi data;
- QVariant cookie;
QByteArray logStreamOutput;
QByteArray consoleStreamOutput;
};
diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
index aba7ead634..6356815491 100644
--- a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
+++ b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
@@ -122,18 +122,18 @@ DebuggerRunConfigWidget::DebuggerRunConfigWidget(DebuggerRunConfigurationAspect
connect(m_qmlDebuggerInfoLabel, SIGNAL(linkActivated(QString)),
Core::HelpManager::instance(), SLOT(handleHelpRequest(QString)));
- connect(m_useQmlDebugger, SIGNAL(toggled(bool)),
- SLOT(useQmlDebuggerToggled(bool)));
- connect(m_useQmlDebugger, SIGNAL(clicked(bool)),
- SLOT(useQmlDebuggerClicked(bool)));
- connect(m_useCppDebugger, SIGNAL(clicked(bool)),
- SLOT(useCppDebuggerClicked(bool)));
- connect(m_debugServerPort, SIGNAL(valueChanged(int)),
- SLOT(qmlDebugServerPortChanged(int)));
- connect(m_useMultiProcess, SIGNAL(toggled(bool)),
- SLOT(useMultiProcessToggled(bool)));
-
- QHBoxLayout *qmlLayout = new QHBoxLayout;
+ connect(m_useQmlDebugger, &QAbstractButton::toggled,
+ this, &DebuggerRunConfigWidget::useQmlDebuggerToggled);
+ connect(m_useQmlDebugger, &QAbstractButton::clicked,
+ this, &DebuggerRunConfigWidget::useQmlDebuggerClicked);
+ connect(m_useCppDebugger, &QAbstractButton::clicked,
+ this, &DebuggerRunConfigWidget::useCppDebuggerClicked);
+ connect(m_debugServerPort, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ this, &DebuggerRunConfigWidget::qmlDebugServerPortChanged);
+ connect(m_useMultiProcess, &QAbstractButton::toggled,
+ this, &DebuggerRunConfigWidget::useMultiProcessToggled);
+
+ auto qmlLayout = new QHBoxLayout;
qmlLayout->setMargin(0);
qmlLayout->addWidget(m_useQmlDebugger);
qmlLayout->addWidget(m_debugServerPortLabel);
@@ -141,7 +141,7 @@ DebuggerRunConfigWidget::DebuggerRunConfigWidget(DebuggerRunConfigurationAspect
qmlLayout->addWidget(m_qmlDebuggerInfoLabel);
qmlLayout->addStretch();
- QVBoxLayout *layout = new QVBoxLayout;
+ auto layout = new QVBoxLayout;
layout->setMargin(0);
layout->addWidget(m_useCppDebugger);
layout->addLayout(qmlLayout);
@@ -234,13 +234,13 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(
void DebuggerRunConfigurationAspect::setUseQmlDebugger(bool value)
{
m_useQmlDebugger = value ? EnabledLanguage : DisabledLanguage;
- emit requestRunActionsUpdate();
+ runConfiguration()->requestRunActionsUpdate();
}
void DebuggerRunConfigurationAspect::setUseCppDebugger(bool value)
{
m_useCppDebugger = value ? EnabledLanguage : DisabledLanguage;
- emit requestRunActionsUpdate();
+ runConfiguration()->requestRunActionsUpdate();
}
bool DebuggerRunConfigurationAspect::useCppDebugger() const
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index ea2c1bb61c..48c5cb24d6 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -108,6 +108,13 @@ DebuggerRunControl::DebuggerRunControl(RunConfiguration *runConfiguration, Debug
{
setIcon(QLatin1String(ProjectExplorer::Constants::ICON_DEBUG_SMALL));
connect(this, &RunControl::finished, this, &DebuggerRunControl::handleFinished);
+
+ connect(engine, &DebuggerEngine::requestRemoteSetup,
+ this, &DebuggerRunControl::requestRemoteSetup);
+ connect(engine, &DebuggerEngine::stateChanged,
+ this, &DebuggerRunControl::stateChanged);
+ connect(engine, &DebuggerEngine::aboutToNotifyInferiorSetupOk,
+ this, &DebuggerRunControl::aboutToNotifyInferiorSetupOk);
}
DebuggerRunControl::~DebuggerRunControl()
@@ -141,10 +148,9 @@ void DebuggerRunControl::start()
if (m_engine->startParameters().startMode == StartInternal) {
QStringList unhandledIds;
- foreach (const BreakpointModelId &id, breakHandler()->allBreakpointIds()) {
- if (m_engine->breakHandler()->breakpointData(id).enabled
- && !m_engine->acceptsBreakpoint(id))
- unhandledIds.append(id.toString());
+ foreach (Breakpoint bp, breakHandler()->allBreakpoints()) {
+ if (bp.isEnabled() && !m_engine->acceptsBreakpoint(bp))
+ unhandledIds.append(bp.id().toString());
}
if (!unhandledIds.isEmpty()) {
QString warningMessage =
@@ -186,6 +192,16 @@ void DebuggerRunControl::startFailed()
m_engine->handleStartFailed();
}
+void DebuggerRunControl::notifyEngineRemoteServerRunning(const QByteArray &msg, int pid)
+{
+ m_engine->notifyEngineRemoteServerRunning(msg, pid);
+}
+
+void DebuggerRunControl::notifyEngineRemoteSetupFinished(const RemoteSetupResult &result)
+{
+ m_engine->notifyEngineRemoteSetupFinished(result);
+}
+
void DebuggerRunControl::handleFinished()
{
appendMessage(tr("Debugging has finished") + QLatin1Char('\n'), NormalMessageFormat);
@@ -222,15 +238,39 @@ void DebuggerRunControl::debuggingFinished()
emit finished();
}
+void DebuggerRunControl::showMessage(const QString &msg, int channel)
+{
+ m_engine->showMessage(msg, channel);
+}
+
bool DebuggerRunControl::isRunning() const
{
return m_running;
}
-DebuggerEngine *DebuggerRunControl::engine()
+DebuggerStartParameters &DebuggerRunControl::startParameters()
+{
+ return m_engine->startParameters();
+}
+
+void DebuggerRunControl::notifyInferiorIll()
+{
+ m_engine->notifyInferiorIll();
+}
+
+void DebuggerRunControl::notifyInferiorExited()
+{
+ m_engine->notifyInferiorExited();
+}
+
+void DebuggerRunControl::quitDebugger()
+{
+ m_engine->quitDebugger();
+}
+
+void DebuggerRunControl::abortDebugger()
{
- QTC_CHECK(m_engine);
- return m_engine;
+ m_engine->abortDebugger();
}
////////////////////////////////////////////////////////////////////////
@@ -255,7 +295,7 @@ bool DebuggerRunControlFactory::fillParametersFromLocalRunConfiguration
QTC_ASSERT(runConfiguration, return false);
auto rc = qobject_cast<const LocalApplicationRunConfiguration *>(runConfiguration);
QTC_ASSERT(rc, return false);
- EnvironmentAspect *environmentAspect = rc->extraAspect<ProjectExplorer::EnvironmentAspect>();
+ EnvironmentAspect *environmentAspect = rc->extraAspect<EnvironmentAspect>();
QTC_ASSERT(environmentAspect, return false);
Target *target = runConfiguration->target();
@@ -291,7 +331,7 @@ bool DebuggerRunControlFactory::fillParametersFromLocalRunConfiguration
sp->languages |= CppLanguage;
if (debuggerAspect->useQmlDebugger()) {
- const ProjectExplorer::IDevice::ConstPtr device =
+ const IDevice::ConstPtr device =
DeviceKitInformation::device(runConfiguration->target()->kit());
QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return sp);
QTcpServer server;
@@ -338,46 +378,12 @@ RunControl *DebuggerRunControlFactory::create
if (mode == DebugRunModeWithBreakOnMain)
sp.breakOnMain = true;
- return doCreate(sp, runConfiguration, errorMessage);
-}
-
-static bool fixupEngineTypes(DebuggerStartParameters &sp, RunConfiguration *rc, QString *errorMessage)
-{
- if (sp.masterEngineType != NoEngineType)
- return true;
-
- if (sp.executable.endsWith(_(".py"))) {
- sp.masterEngineType = PdbEngineType;
- return true;
- }
-
- if (rc) {
- DebuggerRunConfigurationAspect *aspect
- = rc->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
- if (const Target *target = rc->target())
- if (!DebuggerRunControlFactory::fillParametersFromKit(&sp, target->kit(), errorMessage))
- return false;
- const bool useCppDebugger = aspect->useCppDebugger() && (sp.languages & CppLanguage);
- const bool useQmlDebugger = aspect->useQmlDebugger() && (sp.languages & QmlLanguage);
- if (useQmlDebugger) {
- if (useCppDebugger) {
- sp.masterEngineType = QmlCppEngineType;
- sp.firstSlaveEngineType = sp.cppEngineType;
- sp.secondSlaveEngineType = QmlCppEngineType;
- } else {
- sp.masterEngineType = QmlEngineType;
- }
- } else {
- sp.masterEngineType = sp.cppEngineType;
- }
- return true;
- }
- sp.masterEngineType = sp.cppEngineType;
- return true;
+ sp.runConfiguration = runConfiguration;
+ return doCreate(sp, errorMessage);
}
DebuggerRunControl *DebuggerRunControlFactory::doCreate
- (const DebuggerStartParameters &sp0, RunConfiguration *rc, QString *errorMessage)
+ (const DebuggerStartParameters &sp0, QString *errorMessage)
{
TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO);
TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME);
@@ -395,8 +401,34 @@ DebuggerRunControl *DebuggerRunControlFactory::doCreate
}
}
- if (!fixupEngineTypes(sp, rc, errorMessage))
- return 0;
+ if (sp.masterEngineType == NoEngineType) {
+ if (sp.executable.endsWith(_(".py"))) {
+ sp.masterEngineType = PdbEngineType;
+ } else {
+ if (RunConfiguration *rc = sp.runConfiguration) {
+ DebuggerRunConfigurationAspect *aspect
+ = rc->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
+ if (const Target *target = rc->target())
+ if (!DebuggerRunControlFactory::fillParametersFromKit(&sp, target->kit(), errorMessage))
+ return 0;
+ const bool useCppDebugger = aspect->useCppDebugger() && (sp.languages & CppLanguage);
+ const bool useQmlDebugger = aspect->useQmlDebugger() && (sp.languages & QmlLanguage);
+ if (useQmlDebugger) {
+ if (useCppDebugger) {
+ sp.masterEngineType = QmlCppEngineType;
+ sp.firstSlaveEngineType = sp.cppEngineType;
+ sp.secondSlaveEngineType = QmlCppEngineType;
+ } else {
+ sp.masterEngineType = QmlEngineType;
+ }
+ } else {
+ sp.masterEngineType = sp.cppEngineType;
+ }
+ } else {
+ sp.masterEngineType = sp.cppEngineType;
+ }
+ }
+ }
QString error;
DebuggerEngine *engine = createEngine(sp.masterEngineType, sp, &error);
@@ -406,7 +438,7 @@ DebuggerRunControl *DebuggerRunControlFactory::doCreate
*errorMessage = error;
return 0;
}
- return new DebuggerRunControl(rc, engine);
+ return new DebuggerRunControl(sp.runConfiguration, engine);
}
IRunConfigurationAspect *DebuggerRunControlFactory::createRunConfigurationAspect(RunConfiguration *rc)
@@ -417,7 +449,7 @@ IRunConfigurationAspect *DebuggerRunControlFactory::createRunConfigurationAspect
DebuggerRunControl *DebuggerRunControlFactory::createAndScheduleRun(const DebuggerStartParameters &sp)
{
QString errorMessage;
- DebuggerRunControl *rc = doCreate(sp, 0, &errorMessage);
+ DebuggerRunControl *rc = doCreate(sp, &errorMessage);
if (!rc) {
ProjectExplorerPlugin::showRunErrorMessage(errorMessage);
return 0;
@@ -451,7 +483,7 @@ bool DebuggerRunControlFactory::fillParametersFromKit(DebuggerStartParameters *s
sp->executable = executableForPid(sp->attachPID);
}
if (!sp->executable.isEmpty())
- abis = Abi::abisOfBinary(Utils::FileName::fromString(sp->executable));
+ abis = Abi::abisOfBinary(FileName::fromString(sp->executable));
}
if (!abis.isEmpty()) {
// Try exact abis.
diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h
index c09aa46c1b..9b7b15d8e8 100644
--- a/src/plugins/debugger/debuggerruncontrol.h
+++ b/src/plugins/debugger/debuggerruncontrol.h
@@ -40,7 +40,10 @@ namespace ProjectExplorer { class Kit; }
namespace Debugger {
-class DebuggerEngine;
+class RemoteSetupResult;
+
+namespace Internal { class DebuggerEngine; }
+
class DebuggerStartParameters;
class DEBUGGER_EXPORT DebuggerRunControl
@@ -59,20 +62,32 @@ public:
QString displayName() const;
void startFailed();
+ void notifyEngineRemoteServerRunning(const QByteArray &msg, int pid);
+ void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
+ void notifyInferiorIll();
+ Q_SLOT void notifyInferiorExited();
+ void quitDebugger();
+ void abortDebugger();
void debuggingFinished();
- DebuggerEngine *engine();
+
+ void showMessage(const QString &msg, int channel = LogDebug);
+
+ DebuggerStartParameters &startParameters();
signals:
- void engineRequestSetup();
+ void requestRemoteSetup();
+ void aboutToNotifyInferiorSetupOk();
+ void stateChanged(Debugger::DebuggerState state);
private slots:
void handleFinished();
private:
friend class DebuggerRunControlFactory;
- DebuggerRunControl(ProjectExplorer::RunConfiguration *runConfiguration, DebuggerEngine *engine);
+ DebuggerRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
+ Internal::DebuggerEngine *engine);
- DebuggerEngine *m_engine;
+ Internal::DebuggerEngine *m_engine;
bool m_running;
};
@@ -91,7 +106,7 @@ public:
bool canRun(ProjectExplorer::RunConfiguration *runConfiguration,
ProjectExplorer::RunMode mode) const;
- static DebuggerEngine *createEngine(DebuggerEngineType et,
+ static Internal::DebuggerEngine *createEngine(DebuggerEngineType et,
const DebuggerStartParameters &sp,
QString *errorMessage);
@@ -103,8 +118,7 @@ public:
static DebuggerRunControl *createAndScheduleRun(const DebuggerStartParameters &sp);
- static DebuggerRunControl *doCreate(const DebuggerStartParameters &sp,
- ProjectExplorer::RunConfiguration *rc, QString *errorMessage);
+ static DebuggerRunControl *doCreate(const DebuggerStartParameters &sp, QString *errorMessage);
ProjectExplorer::IRunConfigurationAspect *createRunConfigurationAspect(
ProjectExplorer::RunConfiguration *rc);
diff --git a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp
index 1f081559b5..1f9dfaa43e 100644
--- a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp
+++ b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp
@@ -228,40 +228,41 @@ DebuggerSourcePathMappingWidget::DebuggerSourcePathMappingWidget(QWidget *parent
m_treeView->setSelectionMode(QAbstractItemView::SingleSelection);
m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_treeView->setModel(m_model);
- connect(m_treeView->selectionModel(),
- SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
- SLOT(slotCurrentRowChanged(QModelIndex,QModelIndex)));
+ connect(m_treeView->selectionModel(), &QItemSelectionModel::currentRowChanged,
+ this, &DebuggerSourcePathMappingWidget::slotCurrentRowChanged);
// Top list/Right part: Buttons.
- QVBoxLayout *buttonLayout = new QVBoxLayout;
+ auto buttonLayout = new QVBoxLayout;
buttonLayout->addWidget(m_addButton);
buttonLayout->addWidget(m_addQtButton);
m_addQtButton->setVisible(sizeof(qtBuildPaths) > 0);
m_addQtButton->setToolTip(tr("Add a mapping for Qt's source folders "
"when using an unpatched version of Qt."));
buttonLayout->addWidget(m_removeButton);
- connect(m_addButton, SIGNAL(clicked()), this, SLOT(slotAdd()));
- connect(m_addQtButton, SIGNAL(clicked()), this, SLOT(slotAddQt()));
-
- connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemove()));
+ connect(m_addButton, &QAbstractButton::clicked,
+ this, &DebuggerSourcePathMappingWidget::slotAdd);
+ connect(m_addQtButton, &QAbstractButton::clicked,
+ this, &DebuggerSourcePathMappingWidget::slotAddQt);
+ connect(m_removeButton, &QAbstractButton::clicked,
+ this, &DebuggerSourcePathMappingWidget::slotRemove);
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
// Assemble top
- QHBoxLayout *treeHLayout = new QHBoxLayout;
+ auto treeHLayout = new QHBoxLayout;
treeHLayout->addWidget(m_treeView);
treeHLayout->addLayout(buttonLayout);
// Edit part
m_targetChooser->setExpectedKind(PathChooser::ExistingDirectory);
m_targetChooser->setHistoryCompleter(QLatin1String("Debugger.MappingTarget.History"));
- connect(m_sourceLineEdit, SIGNAL(textChanged(QString)),
- this, SLOT(slotEditSourceFieldChanged()));
- connect(m_targetChooser, SIGNAL(changed(QString)),
- this, SLOT(slotEditTargetFieldChanged()));
- QFormLayout *editLayout = new QFormLayout;
+ connect(m_sourceLineEdit, &QLineEdit::textChanged,
+ this, &DebuggerSourcePathMappingWidget::slotEditSourceFieldChanged);
+ connect(m_targetChooser, &PathChooser::changed,
+ this, &DebuggerSourcePathMappingWidget::slotEditTargetFieldChanged);
+ auto editLayout = new QFormLayout;
const QString sourceToolTip = tr("The source path contained in the "
"debug information of the executable as reported by the debugger");
- QLabel *editSourceLabel = new QLabel(tr("&Source path:"));
+ auto editSourceLabel = new QLabel(tr("&Source path:"));
editSourceLabel->setToolTip(sourceToolTip);
m_sourceLineEdit->setToolTip(sourceToolTip);
editSourceLabel->setBuddy(m_sourceLineEdit);
@@ -269,7 +270,7 @@ DebuggerSourcePathMappingWidget::DebuggerSourcePathMappingWidget(QWidget *parent
const QString targetToolTip = tr("The actual location of the source "
"tree on the local machine");
- QLabel *editTargetLabel = new QLabel(tr("&Target path:"));
+ auto editTargetLabel = new QLabel(tr("&Target path:"));
editTargetLabel->setToolTip(targetToolTip);
editTargetLabel->setBuddy(m_targetChooser);
m_targetChooser->setToolTip(targetToolTip);
@@ -279,7 +280,7 @@ DebuggerSourcePathMappingWidget::DebuggerSourcePathMappingWidget(QWidget *parent
chooser->addSupportedWidget(m_targetChooser->lineEdit());
// Main layout
- QVBoxLayout *mainLayout = new QVBoxLayout;
+ auto mainLayout = new QVBoxLayout;
mainLayout->addLayout(treeHLayout);
mainLayout->addLayout(editLayout);
setLayout(mainLayout);
diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h
index 3233511ce0..d89af005cc 100644
--- a/src/plugins/debugger/debuggerstartparameters.h
+++ b/src/plugins/debugger/debuggerstartparameters.h
@@ -39,9 +39,11 @@
#include <utils/environment.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/kit.h>
+#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/devicesupport/idevice.h>
#include <QMetaType>
+#include <QVector>
namespace Debugger {
@@ -81,6 +83,7 @@ public:
firstSlaveEngineType(NoEngineType),
secondSlaveEngineType(NoEngineType),
cppEngineType(NoEngineType),
+ runConfiguration(0),
isSnapshot(false),
attachPID(-1),
useTerminal(false),
@@ -111,6 +114,7 @@ public:
QString debuggerCommand;
ProjectExplorer::Abi toolChainAbi;
ProjectExplorer::IDevice::ConstPtr device;
+ QPointer<ProjectExplorer::RunConfiguration> runConfiguration;
QString platform;
QString executable;
@@ -156,6 +160,9 @@ public:
bool useContinueInsteadOfRun; // if connected to a hw debugger run is not possible but continue is used
QByteArray commandsAfterConnect; // additional commands to post after connection to debug target
+ // Used by Valgrind
+ QVector<QByteArray> expectedSignals;
+
QStringList solibSearchPath;
DebuggerStartMode startMode;
DebuggerCloseMode closeMode;
diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp
index 7fa9e63ee5..5855b03366 100644
--- a/src/plugins/debugger/debuggertooltipmanager.cpp
+++ b/src/plugins/debugger/debuggertooltipmanager.cpp
@@ -44,7 +44,7 @@
#include <texteditor/texteditor.h>
#include <utils/tooltip/tooltip.h>
-#include <utils/tooltip/tipcontents.h>
+#include <utils/treemodel.h>
#include <utils/qtcassert.h>
#include <QAbstractItemModel>
@@ -66,6 +66,7 @@
using namespace Core;
using namespace TextEditor;
+using namespace Utils;
namespace Debugger {
namespace Internal {
@@ -94,9 +95,9 @@ const char dateAttributeC[] = "date";
const char treeElementC[] = "tree";
const char treeExpressionAttributeC[] = "expression";
const char treeInameAttributeC[] = "iname";
-const char modelElementC[] = "model";
-const char modelColumnCountAttributeC[] = "columncount";
-const char modelRowElementC[] = "row";
+// const char modelElementC[] = "model";
+// const char modelColumnCountAttributeC[] = "columncount";
+// const char modelRowElementC[] = "row";
const char modelItemElementC[] = "item";
static void purgeClosedToolTips();
@@ -179,299 +180,176 @@ void DraggableLabel::mouseMoveEvent(QMouseEvent * event)
QLabel::mouseMoveEvent(event);
}
-// Helper for building a QStandardItemModel of a tree form (see TreeModelVisitor).
-// The recursion/building is based on the scheme: \code
-// <row><item1><item2>
-// <row><item11><item12></row>
-// </row>
-// \endcode
-
-class StandardItemTreeModelBuilder
-{
-public:
- typedef QList<QStandardItem *> StandardItemRow;
-
- explicit StandardItemTreeModelBuilder(QStandardItemModel *m, Qt::ItemFlags f = Qt::ItemIsSelectable);
-
- void addItem(const QString &);
- void startRow();
- void endRow();
-
-private:
- void pushRow();
-
- QStandardItemModel *m_model;
- const Qt::ItemFlags m_flags;
- StandardItemRow m_row;
- QStack<QStandardItem *> m_rowParents;
-};
-
-StandardItemTreeModelBuilder::StandardItemTreeModelBuilder(QStandardItemModel *m, Qt::ItemFlags f) :
- m_model(m), m_flags(f)
-{
- m_model->removeRows(0, m_model->rowCount());
-}
-
-void StandardItemTreeModelBuilder::addItem(const QString &s)
-{
- QStandardItem *item = new QStandardItem(s);
- item->setFlags(m_flags);
- m_row.push_back(item);
-}
-
-void StandardItemTreeModelBuilder::pushRow()
-{
- if (m_rowParents.isEmpty())
- m_model->appendRow(m_row);
- else
- m_rowParents.top()->appendRow(m_row);
- m_rowParents.push(m_row.front());
- m_row.clear();
-}
-
-void StandardItemTreeModelBuilder::startRow()
-{
- // Push parent in case rows are nested. This is a Noop for the very first row.
- if (!m_row.isEmpty())
- pushRow();
-}
-
-void StandardItemTreeModelBuilder::endRow()
-{
- if (!m_row.isEmpty()) // Push row if no child rows have been encountered
- pushRow();
- m_rowParents.pop();
-}
+/////////////////////////////////////////////////////////////////////////
+//
+// ToolTipWatchItem
+//
+/////////////////////////////////////////////////////////////////////////
-// Helper visitor base class for recursing over a tree model
-// (see StandardItemTreeModelBuilder for the scheme).
-class TreeModelVisitor
+class ToolTipWatchItem : public Utils::TreeItem
{
public:
- virtual void run() { run(QModelIndex()); }
-
-protected:
- TreeModelVisitor(const QAbstractItemModel *model) : m_model(model) {}
-
- virtual void rowStarted() {}
- virtual void handleItem(const QModelIndex &m) = 0;
- virtual void rowEnded() {}
+ ToolTipWatchItem() : expandable(false) {}
+ ToolTipWatchItem(WatchItem *item);
- const QAbstractItemModel *model() const { return m_model; }
+ bool hasChildren() const { return expandable; }
+ bool canFetchMore() const { return children().isEmpty() && expandable && model(); }
+ void fetchMore() {}
+ QVariant data(int column, int role) const;
-private:
- void run(const QModelIndex &parent);
-
- const QAbstractItemModel *m_model;
-};
-
-void TreeModelVisitor::run(const QModelIndex &parent)
-{
- const int columnCount = m_model->columnCount(parent);
- const int rowCount = m_model->rowCount(parent);
- for (int r = 0; r < rowCount; r++) {
- rowStarted();
- QModelIndex left;
- for (int c = 0; c < columnCount; c++) {
- const QModelIndex index = m_model->index(r, c, parent);
- handleItem(index);
- if (!c)
- left = index;
- }
- if (left.isValid())
- run(left);
- rowEnded();
- }
-}
-
-// Visitor writing out a tree model in XML format.
-class XmlWriterTreeModelVisitor : public TreeModelVisitor
-{
public:
- XmlWriterTreeModelVisitor(const QAbstractItemModel *model, QXmlStreamWriter &w);
-
- virtual void run();
-
-protected:
- virtual void rowStarted() { m_writer.writeStartElement(QLatin1String(modelRowElementC)); }
- virtual void handleItem(const QModelIndex &m);
- virtual void rowEnded() { m_writer.writeEndElement(); }
-
-private:
- const QString m_modelItemElement;
- QXmlStreamWriter &m_writer;
+ QString name;
+ QString value;
+ QString type;
+ QColor color;
+ bool expandable;
+ QByteArray iname;
};
-XmlWriterTreeModelVisitor::XmlWriterTreeModelVisitor(const QAbstractItemModel *model, QXmlStreamWriter &w) :
- TreeModelVisitor(model), m_modelItemElement(QLatin1String(modelItemElementC)), m_writer(w)
+ToolTipWatchItem::ToolTipWatchItem(WatchItem *item)
{
+ name = item->displayName();
+ value = item->displayValue();
+ type = item->displayType();
+ iname = item->d.iname;
+ color = item->color();
+ expandable = item->d.hasChildren;
+ foreach (TreeItem *child, item->children())
+ appendChild(new ToolTipWatchItem(static_cast<WatchItem *>(child)));
}
-void XmlWriterTreeModelVisitor::run()
-{
- m_writer.writeStartElement(QLatin1String(modelElementC));
- const int columnCount = model()->columnCount();
- m_writer.writeAttribute(QLatin1String(modelColumnCountAttributeC), QString::number(columnCount));
- TreeModelVisitor::run();
- m_writer.writeEndElement();
-}
-
-void XmlWriterTreeModelVisitor::handleItem(const QModelIndex &m)
-{
- const QString value = m.data(Qt::DisplayRole).toString();
- if (value.isEmpty())
- m_writer.writeEmptyElement(m_modelItemElement);
- else
- m_writer.writeTextElement(m_modelItemElement, value);
-}
+/////////////////////////////////////////////////////////////////////////
+//
+// ToolTipModel
+//
+/////////////////////////////////////////////////////////////////////////
-// TreeModelVisitor for debugging/copying models
-class DumpTreeModelVisitor : public TreeModelVisitor
+class ToolTipModel : public TreeModel
{
public:
- enum Mode
+ ToolTipModel()
{
- DebugMode, // For debugging, "|'data'|"
- ClipboardMode // Tab-delimited "\tdata" for clipboard (see stack window)
- };
- explicit DumpTreeModelVisitor(const QAbstractItemModel *model, Mode m, QTextStream &s);
-
-protected:
- virtual void rowStarted();
- virtual void handleItem(const QModelIndex &m);
- virtual void rowEnded();
-
-private:
- const Mode m_mode;
-
- QTextStream &m_stream;
- int m_level;
- unsigned m_itemsInRow;
-};
-
-DumpTreeModelVisitor::DumpTreeModelVisitor(const QAbstractItemModel *model, Mode m, QTextStream &s) :
- TreeModelVisitor(model), m_mode(m), m_stream(s), m_level(0), m_itemsInRow(0)
-{
- if (m_mode == DebugMode)
- m_stream << model->metaObject()->className() << '/' << model->objectName();
-}
-
-void DumpTreeModelVisitor::rowStarted()
-{
- m_level++;
- if (m_itemsInRow) { // Nested row.
- m_stream << '\n';
- m_itemsInRow = 0;
- }
- switch (m_mode) {
- case DebugMode:
- m_stream << QString(2 * m_level, QLatin1Char(' '));
- break;
- case ClipboardMode:
- m_stream << QString(m_level, QLatin1Char('\t'));
- break;
+ QStringList headers;
+ headers.append(tr("Name"));
+ headers.append(tr("Value"));
+ headers.append(tr("Type"));
+ setHeader(headers);
+ m_enabled = true;
+ auto item = new ToolTipWatchItem;
+ item->expandable = true;
+ setRootItem(item);
}
-}
-void DumpTreeModelVisitor::handleItem(const QModelIndex &m)
-{
- const QString data = m.data().toString();
- switch (m_mode) {
- case DebugMode:
- if (m.column())
- m_stream << '|';
- m_stream << '\'' << data << '\'';
- break;
- case ClipboardMode:
- if (m.column())
- m_stream << '\t';
- m_stream << data;
- break;
+ void expandNode(const QModelIndex &idx)
+ {
+ m_expandedINames.insert(idx.data(LocalsINameRole).toByteArray());
+ if (canFetchMore(idx))
+ fetchMore(idx);
}
- m_itemsInRow++;
-}
-void DumpTreeModelVisitor::rowEnded()
-{
- if (m_itemsInRow) {
- m_stream << '\n';
- m_itemsInRow = 0;
+ void collapseNode(const QModelIndex &idx)
+ {
+ m_expandedINames.remove(idx.data(LocalsINameRole).toByteArray());
}
- m_level--;
-}
-/*
-static QDebug operator<<(QDebug d, const QAbstractItemModel &model)
-{
- QString s;
- QTextStream str(&s);
- Debugger::Internal::DumpTreeModelVisitor v(&model, Debugger::Internal::DumpTreeModelVisitor::DebugMode, str);
- v.run();
- qCDebug(tooltip).nospace() << s;
- return d;
-}
-*/
+ void fetchMore(const QModelIndex &idx)
+ {
+ if (!idx.isValid())
+ return;
+ auto item = dynamic_cast<ToolTipWatchItem *>(itemFromIndex(idx));
+ if (!item)
+ return;
+ QByteArray iname = item->iname;
+ if (!m_engine)
+ return;
-/*!
- \class Debugger::Internal::TooltipFilterModel
+ WatchItem *it = m_engine->watchHandler()->findItem(iname);
+ QTC_ASSERT(it, return);
+ it->fetchMore();
+ }
- \brief The TooltipFilterModel class is a model for tooltips filtering an
- item on the watchhandler matching its tree on the iname.
+ void restoreTreeModel(QXmlStreamReader &r);
- In addition, suppress the model's tooltip data to avoid a tooltip on a tooltip.
-*/
+ QPointer<DebuggerEngine> m_engine;
+ QSet<QByteArray> m_expandedINames;
+ bool m_enabled;
+};
-class TooltipFilterModel : public QSortFilterProxyModel
-{
-public:
- TooltipFilterModel() {}
+QVariant ToolTipWatchItem::data(int column, int role) const
+{
+ switch (role) {
+ case Qt::DisplayRole: {
+ switch (column) {
+ case 0:
+ return name;
+ case 1:
+ return value;
+ case 2:
+ return type;
+ }
+ }
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
- {
- return role == Qt::ToolTipRole
- ? QVariant() : QSortFilterProxyModel::data(index, role);
- }
+ case LocalsINameRole:
+ return iname;
- static bool isSubIname(const QByteArray &haystack, const QByteArray &needle)
- {
- return haystack.size() > needle.size()
- && haystack.startsWith(needle)
- && haystack.at(needle.size()) == '.';
- }
+ case Qt::ForegroundRole:
+ if (model() && static_cast<ToolTipModel *>(model())->m_enabled) {
+ if (column == 1)
+ return color;
+ return QVariant();
+ }
+ return QColor(140, 140, 140);
- bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
- {
- const QModelIndex nameIndex = sourceModel()->index(sourceRow, 0, sourceParent);
- const QByteArray iname = nameIndex.data(LocalsINameRole).toByteArray();
-// DEBUG("ACCEPTING FILTER" << iname
-// << (iname == m_iname || isSubIname(iname, m_iname) || isSubIname(m_iname, iname));
- return iname == m_iname || isSubIname(iname, m_iname) || isSubIname(m_iname, iname);
+ default:
+ break;
}
+ return QVariant();
+}
- QByteArray m_iname;
-};
-
-/////////////////////////////////////////////////////////////////////////
-//
-// TreeModelCopyVisitor builds a QStandardItem from a tree model (copy).
-//
-/////////////////////////////////////////////////////////////////////////
-
-class TreeModelCopyVisitor : public TreeModelVisitor
+void ToolTipModel::restoreTreeModel(QXmlStreamReader &r)
{
-public:
- TreeModelCopyVisitor(const QAbstractItemModel *source, QStandardItemModel *target) :
- TreeModelVisitor(source), m_builder(target)
- {}
-
-protected:
- virtual void rowStarted() { m_builder.startRow(); }
- virtual void handleItem(const QModelIndex &m) { m_builder.addItem(m.data().toString()); }
- virtual void rowEnded() { m_builder.endRow(); }
+ Q_UNUSED(r);
+#if 0
+// Helper for building a QStandardItemModel of a tree form (see TreeModelVisitor).
+// The recursion/building is based on the scheme: \code
+// <row><item1><item2>
+// <row><item11><item12></row>
+// </row>
+// \endcode
-private:
- StandardItemTreeModelBuilder m_builder;
-};
+ bool withinModel = true;
+ while (withinModel && !r.atEnd()) {
+ const QXmlStreamReader::TokenType token = r.readNext();
+ switch (token) {
+ case QXmlStreamReader::StartElement: {
+ const QStringRef element = r.name();
+ // Root model element with column count.
+ if (element == QLatin1String(modelElementC)) {
+ if (const int cc = r.attributes().value(QLatin1String(modelColumnCountAttributeC)).toString().toInt())
+ columnCount = cc;
+ m->setColumnCount(columnCount);
+ } else if (element == QLatin1String(modelRowElementC)) {
+ builder.startRow();
+ } else if (element == QLatin1String(modelItemElementC)) {
+ builder.addItem(r.readElementText());
+ }
+ }
+ break; // StartElement
+ case QXmlStreamReader::EndElement: {
+ const QStringRef element = r.name();
+ // Row closing: pop off parent.
+ if (element == QLatin1String(modelRowElementC))
+ builder.endRow();
+ else if (element == QLatin1String(modelElementC))
+ withinModel = false;
+ }
+ break; // EndElement
+ default:
+ break;
+ } // switch
+ } // while
+#endif
+}
/*!
\class Debugger::Internal::DebuggerToolTipTreeView
@@ -491,16 +369,24 @@ public:
void computeSize();
+ void setEngine(DebuggerEngine *engine);
private:
- void expandNode(const QModelIndex &idx);
- void collapseNode(const QModelIndex &idx);
int computeHeight(const QModelIndex &index) const;
+ WatchHandler *watchHandler() const
+ {
+ return m_model.m_engine->watchHandler();
+ }
+
QSize m_size;
+
+public:
+ ToolTipModel m_model;
+ void reexpand(const QModelIndex &idx);
};
-DebuggerToolTipTreeView::DebuggerToolTipTreeView(QWidget *parent) :
- QTreeView(parent)
+DebuggerToolTipTreeView::DebuggerToolTipTreeView(QWidget *parent)
+ : QTreeView(parent)
{
setHeaderHidden(true);
setEditTriggers(NoEditTriggers);
@@ -509,25 +395,20 @@ DebuggerToolTipTreeView::DebuggerToolTipTreeView(QWidget *parent) :
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setModel(&m_model);
+
connect(this, &QTreeView::collapsed, this, &DebuggerToolTipTreeView::computeSize,
Qt::QueuedConnection);
connect(this, &QTreeView::expanded, this, &DebuggerToolTipTreeView::computeSize,
Qt::QueuedConnection);
- connect(this, &QTreeView::expanded,
- this, &DebuggerToolTipTreeView::expandNode);
- connect(this, &QTreeView::collapsed,
- this, &DebuggerToolTipTreeView::collapseNode);
+ connect(this, &QTreeView::expanded, &m_model, &ToolTipModel::expandNode);
+ connect(this, &QTreeView::collapsed, &m_model, &ToolTipModel::collapseNode);
}
-void DebuggerToolTipTreeView::expandNode(const QModelIndex &idx)
+void DebuggerToolTipTreeView::setEngine(DebuggerEngine *engine)
{
- model()->setData(idx, true, LocalsExpandedRole);
-}
-
-void DebuggerToolTipTreeView::collapseNode(const QModelIndex &idx)
-{
- model()->setData(idx, false, LocalsExpandedRole);
+ m_model.m_engine = engine;
}
int DebuggerToolTipTreeView::computeHeight(const QModelIndex &index) const
@@ -539,6 +420,26 @@ int DebuggerToolTipTreeView::computeHeight(const QModelIndex &index) const
return s;
}
+void DebuggerToolTipTreeView::reexpand(const QModelIndex &idx)
+{
+ TreeItem *item = m_model.itemFromIndex(idx);
+ QTC_ASSERT(item, return);
+ QByteArray iname = item->data(0, LocalsINameRole).toByteArray();
+ bool shouldExpand = m_model.m_expandedINames.contains(iname);
+ if (shouldExpand) {
+ if (!isExpanded(idx)) {
+ expand(idx);
+ for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
+ QModelIndex idx1 = model()->index(i, 0, idx);
+ reexpand(idx1);
+ }
+ }
+ } else {
+ if (isExpanded(idx))
+ collapse(idx);
+ }
+}
+
void DebuggerToolTipTreeView::computeSize()
{
int columns = 30; // Decoration
@@ -546,13 +447,14 @@ void DebuggerToolTipTreeView::computeSize()
bool rootDecorated = false;
if (QAbstractItemModel *m = model()) {
- WatchTreeView::reexpand(this, m->index(0, 0));
+ reexpand(m->index(0, 0));
const int columnCount = m->columnCount();
rootDecorated = m->rowCount() > 0;
- if (rootDecorated)
- for (int i = 0; i < columnCount; ++i) {
- resizeColumnToContents(i);
- columns += sizeHintForColumn(i);
+ if (rootDecorated) {
+ for (int i = 0; i < columnCount; ++i) {
+ resizeColumnToContents(i);
+ columns += sizeHintForColumn(i);
+ }
}
if (columns < 100)
columns = 100; // Prevent toolbar from shrinking when displaying 'Previous'
@@ -592,17 +494,6 @@ void DebuggerToolTipTreeView::computeSize()
setRootIsDecorated(rootDecorated);
}
-QString DebuggerToolTipManager::treeModelClipboardContents(const QAbstractItemModel *model)
-{
- QString rc;
- QTC_ASSERT(model, return rc);
- QTextStream str(&rc);
- DumpTreeModelVisitor v(model, DumpTreeModelVisitor::ClipboardMode, str);
- v.run();
- return rc;
-}
-
-
/////////////////////////////////////////////////////////////////////////
//
// DebuggerToolTipWidget
@@ -612,49 +503,7 @@ QString DebuggerToolTipManager::treeModelClipboardContents(const QAbstractItemMo
class DebuggerToolTipWidget : public QWidget
{
public:
- DebuggerToolTipWidget()
- {
- setAttribute(Qt::WA_DeleteOnClose);
-
- isPinned = false;
- const QIcon pinIcon(QLatin1String(":/debugger/images/pin.xpm"));
-
- pinButton = new QToolButton;
- pinButton->setIcon(pinIcon);
-
- auto copyButton = new QToolButton;
- copyButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_COPY)));
-
- titleLabel = new DraggableLabel(this);
- titleLabel->setMinimumWidth(40); // Ensure a draggable area even if text is empty.
- titleLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
-
- auto toolBar = new QToolBar(this);
- toolBar->setProperty("_q_custom_style_disabled", QVariant(true));
- const QList<QSize> pinIconSizes = pinIcon.availableSizes();
- if (!pinIconSizes.isEmpty())
- toolBar->setIconSize(pinIconSizes.front());
- toolBar->addWidget(pinButton);
- toolBar->addWidget(copyButton);
- toolBar->addWidget(titleLabel);
-
- treeView = new DebuggerToolTipTreeView(this);
- treeView->setFocusPolicy(Qt::NoFocus);
-
- auto mainLayout = new QVBoxLayout(this);
- mainLayout->setSizeConstraint(QLayout::SetFixedSize);
- mainLayout->setContentsMargins(0, 0, 0, 0);
- mainLayout->addWidget(toolBar);
- mainLayout->addWidget(treeView);
-
- connect(copyButton, &QAbstractButton::clicked, [this] {
- QString clipboardText = DebuggerToolTipManager::treeModelClipboardContents(treeView->model());
- QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(clipboardText, QClipboard::Selection);
- clipboard->setText(clipboardText, QClipboard::Clipboard);
- });
- DEBUG("CREATE DEBUGGERTOOLTIP WIDGET");
- }
+ DebuggerToolTipWidget();
~DebuggerToolTipWidget()
{
@@ -688,7 +537,7 @@ public:
if (parentWidget()) {
// We are currently within a text editor tooltip:
// Rip out of parent widget and re-show as a tooltip
- Utils::WidgetContent::pinToolTip(this, ICore::mainWindow());
+ ToolTip::pinToolTip(this, ICore::mainWindow());
} else {
// We have just be restored from session data.
setWindowFlags(Qt::ToolTip);
@@ -703,6 +552,58 @@ public:
DebuggerToolTipTreeView *treeView;
};
+DebuggerToolTipWidget::DebuggerToolTipWidget()
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ isPinned = false;
+ const QIcon pinIcon(QLatin1String(":/debugger/images/pin.xpm"));
+
+ pinButton = new QToolButton;
+ pinButton->setIcon(pinIcon);
+
+ auto copyButton = new QToolButton;
+ copyButton->setToolTip(DebuggerToolTipManager::tr("Copy Contents to Clipboard"));
+ copyButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_COPY)));
+
+ titleLabel = new DraggableLabel(this);
+ titleLabel->setMinimumWidth(40); // Ensure a draggable area even if text is empty.
+ titleLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+
+ auto toolBar = new QToolBar(this);
+ toolBar->setProperty("_q_custom_style_disabled", QVariant(true));
+ const QList<QSize> pinIconSizes = pinIcon.availableSizes();
+ if (!pinIconSizes.isEmpty())
+ toolBar->setIconSize(pinIconSizes.front());
+ toolBar->addWidget(pinButton);
+ toolBar->addWidget(copyButton);
+ toolBar->addWidget(titleLabel);
+
+ treeView = new DebuggerToolTipTreeView(this);
+ treeView->setFocusPolicy(Qt::NoFocus);
+
+ auto mainLayout = new QVBoxLayout(this);
+ mainLayout->setSizeConstraint(QLayout::SetFixedSize);
+ mainLayout->setContentsMargins(0, 0, 0, 0);
+ mainLayout->addWidget(toolBar);
+ mainLayout->addWidget(treeView);
+
+ connect(copyButton, &QAbstractButton::clicked, [this] {
+ QString text;
+ QTextStream str(&text);
+ treeView->m_model.rootItem()->walkTree([&str](TreeItem *item) {
+ auto titem = static_cast<ToolTipWatchItem *>(item);
+ str << QString(item->level(), QLatin1Char('\t'))
+ << titem->name << '\t' << titem->value << '\t' << titem->type << '\n';
+ });
+ QClipboard *clipboard = QApplication::clipboard();
+ clipboard->setText(text, QClipboard::Selection);
+ clipboard->setText(text, QClipboard::Clipboard);
+ });
+ DEBUG("CREATE DEBUGGERTOOLTIP WIDGET");
+}
+
+
/////////////////////////////////////////////////////////////////////////
//
// DebuggerToolTipHolder
@@ -724,7 +625,7 @@ public:
DebuggerToolTipHolder(const DebuggerToolTipContext &context);
~DebuggerToolTipHolder();
- void acquireEngine();
+ void acquireEngine(DebuggerEngine *engine);
void releaseEngine();
void saveSessionData(QXmlStreamWriter &w) const;
@@ -732,19 +633,15 @@ public:
void positionShow(const TextEditorWidget *editorWidget);
- void handleItemIsExpanded(const QModelIndex &sourceIdx);
- void updateTooltip(const StackFrame &frame);
+ void updateTooltip(DebuggerEngine *engine);
void setState(DebuggerTootipState newState);
void destroy();
public:
QPointer<DebuggerToolTipWidget> widget;
- QPointer<DebuggerEngine> engine;
QDate creationDate;
DebuggerToolTipContext context;
- TooltipFilterModel filterModel; //!< Pointing to a valid watchModel
- QStandardItemModel defaultModel;
DebuggerTootipState state;
};
@@ -756,15 +653,6 @@ static void hideAllToolTips()
tooltip->widget->hide();
}
-void DebuggerToolTipHolder::handleItemIsExpanded(const QModelIndex &sourceIdx)
-{
- QTC_ASSERT(filterModel.sourceModel() == sourceIdx.model(), return);
- QModelIndex mappedIdx = filterModel.mapFromSource(sourceIdx);
- QTC_ASSERT(widget.data(), return);
- if (!widget->treeView->isExpanded(mappedIdx))
- widget->treeView->expand(mappedIdx);
-}
-
/*!
\class Debugger::Internal::DebuggerToolTipContext
@@ -803,6 +691,12 @@ bool DebuggerToolTipContext::isSame(const DebuggerToolTipContext &other) const
&& iname == other.iname;
}
+QString DebuggerToolTipContext::toolTip() const
+{
+ return DebuggerToolTipManager::tr("Expression %1 in function %2 from line %3 to %4")
+ .arg(expression).arg(function).arg(scopeFromLine).arg(scopeToLine);
+}
+
QDebug operator<<(QDebug d, const DebuggerToolTipContext &c)
{
QDebug nsp = d.nospace();
@@ -859,14 +753,11 @@ DebuggerToolTipHolder::DebuggerToolTipHolder(const DebuggerToolTipContext &conte
state = New;
- filterModel.m_iname = context.iname;
-
QObject::connect(widget->pinButton, &QAbstractButton::clicked, [this] {
- if (widget->isPinned) {
+ if (widget->isPinned)
widget->close();
- } else {
+ else
widget->pin();
- }
});
DEBUG("CREATE DEBUGGERTOOLTIPHOLDER" << context.iname);
}
@@ -885,39 +776,35 @@ DebuggerToolTipHolder::~DebuggerToolTipHolder()
// If we are in "Acquired" or "Released", this is an update
// after normal WatchModel update.
-void DebuggerToolTipHolder::updateTooltip(const StackFrame &frame)
+void DebuggerToolTipHolder::updateTooltip(DebuggerEngine *engine)
{
+ widget->treeView->setEngine(engine);
+
+ if (!engine) {
+ setState(Released);
+ return;
+ }
+
+ StackFrame frame = engine->stackHandler()->currentFrame();
+
const bool sameFrame = context.matchesFrame(frame);
DEBUG("UPDATE TOOLTIP: STATE " << state << context.iname
<< "PINNED: " << widget->isPinned
<< "SHOW NEEDED: " << widget->isPinned
<< "SAME FRAME: " << sameFrame);
+
if (state == PendingUnshown) {
- const Utils::WidgetContent widgetContent(widget, true);
- Utils::ToolTip::show(context.mousePosition, widgetContent, Internal::mainWindow());
+ ToolTip::show(context.mousePosition, widget, Internal::mainWindow());
setState(PendingShown);
}
- if (state == PendingShown) {
- acquireEngine();
- Utils::ToolTip::move(context.mousePosition, Internal::mainWindow());
- } else if (state == Acquired && !sameFrame) {
+ if (sameFrame) {
+ acquireEngine(engine);
+ } else {
releaseEngine();
- } else if (state == Released && sameFrame) {
- acquireEngine();
- }
-
- if (state == Acquired) {
- // Save data to stream and restore to the backup m_defaultModel.
- // Doing it on releaseEngine() is too later.
- defaultModel.removeRows(0, defaultModel.rowCount());
- TreeModelCopyVisitor v(&filterModel, &defaultModel);
- v.run();
-
- widget->treeView->expand(filterModel.index(0, 0));
- WatchTreeView::reexpand(widget->treeView, filterModel.index(0, 0));
}
+ widget->titleLabel->setToolTip(context.toolTip());
}
void DebuggerToolTipHolder::setState(DebuggerTootipState newState)
@@ -948,29 +835,38 @@ void DebuggerToolTipHolder::destroy()
}
}
-void DebuggerToolTipHolder::acquireEngine()
+void DebuggerToolTipHolder::acquireEngine(DebuggerEngine *engine)
{
DEBUG("ACQUIRE ENGINE: STATE " << state);
setState(Acquired);
QTC_ASSERT(widget, return);
widget->titleLabel->setText(context.expression);
- widget->treeView->setModel(&filterModel);
- widget->treeView->setRootIndex(filterModel.index(0, 0));
- widget->treeView->expand(filterModel.index(0, 0));
- WatchTreeView::reexpand(widget->treeView, filterModel.index(0, 0));
+ //widget->treeView->setEnabled(true);
+ widget->treeView->m_model.m_enabled = true;
+
+ WatchItem *item = engine->watchHandler()->findItem(context.iname);
+ if (item) {
+ auto clone = new ToolTipWatchItem(item);
+ widget->treeView->m_model.rootItem()->removeChildren();
+ widget->treeView->m_model.rootItem()->appendChild(clone);
+ }
+ WatchTreeView::reexpand(widget->treeView, QModelIndex());
+ widget->treeView->computeSize();
}
void DebuggerToolTipHolder::releaseEngine()
{
+ if (state == Released)
+ return;
DEBUG("RELEASE ENGINE: STATE " << state);
setState(Released);
QTC_ASSERT(widget, return);
+ widget->treeView->m_model.m_enabled = false;
+ widget->treeView->m_model.layoutChanged();
widget->titleLabel->setText(DebuggerToolTipManager::tr("%1 (Previous)").arg(context.expression));
- widget->treeView->setModel(&defaultModel);
- widget->treeView->setRootIndex(defaultModel.index(0, 0));
- widget->treeView->expandAll();
+// widget->treeView->setEnabled(false);
}
void DebuggerToolTipHolder::positionShow(const TextEditorWidget *editorWidget)
@@ -1023,44 +919,7 @@ static DebuggerToolTipHolder *findOrCreateTooltip(const DebuggerToolTipContext &
return newTooltip;
}
-static void restoreTreeModel(QXmlStreamReader &r, QStandardItemModel *m)
-{
- StandardItemTreeModelBuilder builder(m);
- int columnCount = 1;
- bool withinModel = true;
- while (withinModel && !r.atEnd()) {
- const QXmlStreamReader::TokenType token = r.readNext();
- switch (token) {
- case QXmlStreamReader::StartElement: {
- const QStringRef element = r.name();
- // Root model element with column count.
- if (element == QLatin1String(modelElementC)) {
- if (const int cc = r.attributes().value(QLatin1String(modelColumnCountAttributeC)).toString().toInt())
- columnCount = cc;
- m->setColumnCount(columnCount);
- } else if (element == QLatin1String(modelRowElementC)) {
- builder.startRow();
- } else if (element == QLatin1String(modelItemElementC)) {
- builder.addItem(r.readElementText());
- }
- }
- break; // StartElement
- case QXmlStreamReader::EndElement: {
- const QStringRef element = r.name();
- // Row closing: pop off parent.
- if (element == QLatin1String(modelRowElementC))
- builder.endRow();
- else if (element == QLatin1String(modelElementC))
- withinModel = false;
- }
- break; // EndElement
- default:
- break;
- } // switch
- } // while
-}
-
-// Parse a 'yyyyMMdd' date
+//// Parse a 'yyyyMMdd' date
static QDate dateFromString(const QString &date)
{
return date.size() == 8 ?
@@ -1068,56 +927,6 @@ static QDate dateFromString(const QString &date)
QDate();
}
-static void loadSessionDataHelper(QXmlStreamReader &r)
-{
- if (!readStartElement(r, toolTipElementC))
- return;
- const QXmlStreamAttributes attributes = r.attributes();
- DebuggerToolTipContext context;
- context.fileName = attributes.value(QLatin1String(fileNameAttributeC)).toString();
- context.position = attributes.value(QLatin1String(textPositionAttributeC)).toString().toInt();
- context.line = attributes.value(QLatin1String(textLineAttributeC)).toString().toInt();
- context.column = attributes.value(QLatin1String(textColumnAttributeC)).toString().toInt();
- context.function = attributes.value(QLatin1String(functionAttributeC)).toString();
- QPoint offset;
- const QString offsetXAttribute = QLatin1String(offsetXAttributeC);
- const QString offsetYAttribute = QLatin1String(offsetYAttributeC);
- if (attributes.hasAttribute(offsetXAttribute))
- offset.setX(attributes.value(offsetXAttribute).toString().toInt());
- if (attributes.hasAttribute(offsetYAttribute))
- offset.setY(attributes.value(offsetYAttribute).toString().toInt());
- context.mousePosition = offset;
-
- context.iname = attributes.value(QLatin1String(treeInameAttributeC)).toString().toLatin1();
- context.expression = attributes.value(QLatin1String(treeExpressionAttributeC)).toString();
-
-// const QStringRef className = attributes.value(QLatin1String(toolTipClassAttributeC));
- context.engineType = attributes.value(QLatin1String(engineTypeAttributeC)).toString();
- context.creationDate = dateFromString(attributes.value(QLatin1String(dateAttributeC)).toString());
- bool readTree = context.isValid();
- if (!context.creationDate.isValid() || context.creationDate.daysTo(QDate::currentDate()) > toolTipsExpiryDays) {
- // DEBUG("Expiring tooltip " << context.fileName << '@' << context.position << " from " << creationDate)
- //readTree = false;
- } else { //if (className != QLatin1String("Debugger::Internal::DebuggerToolTipWidget")) {
- //qWarning("Unable to create debugger tool tip widget of class %s", qPrintable(className.toString()));
- //readTree = false;
- }
-
- if (readTree) {
- DebuggerToolTipHolder *tw = findOrCreateTooltip(context);
- restoreTreeModel(r, &tw->defaultModel);
- tw->widget->pin();
- tw->widget->titleLabel->setText(DebuggerToolTipManager::tr("%1 (Restored").arg(context.expression));
- tw->widget->treeView->setModel(&tw->defaultModel);
- tw->widget->treeView->setRootIndex(tw->defaultModel.index(0, 0));
- tw->widget->treeView->expandAll();
- } else {
- r.readElementText(QXmlStreamReader::SkipChildElements); // Skip
- }
-
- r.readNext(); // Skip </tree>
-}
-
void DebuggerToolTipHolder::saveSessionData(QXmlStreamWriter &w) const
{
w.writeStartElement(QLatin1String(toolTipElementC));
@@ -1140,10 +949,18 @@ void DebuggerToolTipHolder::saveSessionData(QXmlStreamWriter &w) const
attributes.append(QLatin1String(treeInameAttributeC), QLatin1String(context.iname));
w.writeAttributes(attributes);
- w.writeStartElement(QLatin1String(treeElementC));
- XmlWriterTreeModelVisitor v(&filterModel, w);
- v.run();
- w.writeEndElement();
+ w.writeStartElement(QLatin1String(treeElementC));
+ widget->treeView->m_model.rootItem()->walkTree([&w](TreeItem *item) {
+ const QString modelItemElement = QLatin1String(modelItemElementC);
+ for (int i = 0; i < 3; ++i) {
+ const QString value = item->data(i, Qt::DisplayRole).toString();
+ if (value.isEmpty())
+ w.writeEmptyElement(modelItemElement);
+ else
+ w.writeTextElement(modelItemElement, value);
+ }
+ });
+ w.writeEndElement();
w.writeEndElement();
}
@@ -1191,7 +1008,7 @@ void DebuggerToolTipManager::slotUpdateVisibleToolTips()
return;
}
- const QString fileName = toolTipEditor->textDocument()->filePath();
+ const QString fileName = toolTipEditor->textDocument()->filePath().toString();
if (fileName.isEmpty()) {
hideAllToolTips();
return;
@@ -1206,21 +1023,6 @@ void DebuggerToolTipManager::slotUpdateVisibleToolTips()
}
}
-void DebuggerToolTipManager::slotItemIsExpanded(const QModelIndex &idx)
-{
- foreach (DebuggerToolTipHolder *tooltip, m_tooltips)
- tooltip->handleItemIsExpanded(idx);
-}
-
-void DebuggerToolTipManager::slotColumnAdjustmentRequested()
-{
- foreach (DebuggerToolTipHolder *tooltip, m_tooltips) {
- QTC_ASSERT(tooltip, continue);
- QTC_ASSERT(tooltip->widget, continue);
- tooltip->widget->treeView->computeSize();
- }
-}
-
void DebuggerToolTipManager::updateEngine(DebuggerEngine *engine)
{
QTC_ASSERT(engine, return);
@@ -1230,21 +1032,15 @@ void DebuggerToolTipManager::updateEngine(DebuggerEngine *engine)
// Stack frame changed: All tooltips of that file acquire the engine,
// all others release (arguable, this could be more precise?)
- StackFrame frame = engine->stackHandler()->currentFrame();
foreach (DebuggerToolTipHolder *tooltip, m_tooltips)
- tooltip->updateTooltip(frame);
+ tooltip->updateTooltip(engine);
slotUpdateVisibleToolTips(); // Move tooltip when stepping in same file.
}
-
void DebuggerToolTipManager::registerEngine(DebuggerEngine *engine)
{
+ Q_UNUSED(engine)
DEBUG("REGISTER ENGINE");
- WatchModelBase *watchModel = engine->watchHandler()->model();
- connect(watchModel, &WatchModelBase::itemIsExpanded,
- m_instance, &DebuggerToolTipManager::slotItemIsExpanded);
- connect(watchModel, &WatchModelBase::columnAdjustmentRequested,
- m_instance, &DebuggerToolTipManager::slotColumnAdjustmentRequested);
}
void DebuggerToolTipManager::deregisterEngine(DebuggerEngine *engine)
@@ -1252,22 +1048,18 @@ void DebuggerToolTipManager::deregisterEngine(DebuggerEngine *engine)
DEBUG("DEREGISTER ENGINE");
QTC_ASSERT(engine, return);
- // FIXME: For now remove all.
purgeClosedToolTips();
- foreach (DebuggerToolTipHolder *tooltip, m_tooltips)
- tooltip->destroy();
- purgeClosedToolTips();
- return;
- WatchModelBase *watchModel = engine->watchHandler()->model();
- disconnect(watchModel, &WatchModelBase::itemIsExpanded,
- m_instance, &DebuggerToolTipManager::slotItemIsExpanded);
- disconnect(watchModel, &WatchModelBase::columnAdjustmentRequested,
- m_instance, &DebuggerToolTipManager::slotColumnAdjustmentRequested);
foreach (DebuggerToolTipHolder *tooltip, m_tooltips)
if (tooltip->context.engineType == engine->objectName())
tooltip->releaseEngine();
+
saveSessionData();
+
+ // FIXME: For now remove all.
+ foreach (DebuggerToolTipHolder *tooltip, m_tooltips)
+ tooltip->destroy();
+ purgeClosedToolTips();
}
bool DebuggerToolTipManager::hasToolTips()
@@ -1282,20 +1074,61 @@ void DebuggerToolTipManager::sessionAboutToChange()
void DebuggerToolTipManager::loadSessionData()
{
- return; // FIXME
-
const QString data = sessionValue(sessionSettingsKeyC).toString();
QXmlStreamReader r(data);
r.readNextStartElement();
- if (r.tokenType() == QXmlStreamReader::StartElement && r.name() == QLatin1String(sessionDocumentC))
- while (!r.atEnd())
- loadSessionDataHelper(r);
+ if (r.tokenType() == QXmlStreamReader::StartElement && r.name() == QLatin1String(sessionDocumentC)) {
+ while (!r.atEnd()) {
+ if (readStartElement(r, toolTipElementC)) {
+ const QXmlStreamAttributes attributes = r.attributes();
+ DebuggerToolTipContext context;
+ context.fileName = attributes.value(QLatin1String(fileNameAttributeC)).toString();
+ context.position = attributes.value(QLatin1String(textPositionAttributeC)).toString().toInt();
+ context.line = attributes.value(QLatin1String(textLineAttributeC)).toString().toInt();
+ context.column = attributes.value(QLatin1String(textColumnAttributeC)).toString().toInt();
+ context.function = attributes.value(QLatin1String(functionAttributeC)).toString();
+ QPoint offset;
+ const QString offsetXAttribute = QLatin1String(offsetXAttributeC);
+ const QString offsetYAttribute = QLatin1String(offsetYAttributeC);
+ if (attributes.hasAttribute(offsetXAttribute))
+ offset.setX(attributes.value(offsetXAttribute).toString().toInt());
+ if (attributes.hasAttribute(offsetYAttribute))
+ offset.setY(attributes.value(offsetYAttribute).toString().toInt());
+ context.mousePosition = offset;
+
+ context.iname = attributes.value(QLatin1String(treeInameAttributeC)).toString().toLatin1();
+ context.expression = attributes.value(QLatin1String(treeExpressionAttributeC)).toString();
+
+ // const QStringRef className = attributes.value(QLatin1String(toolTipClassAttributeC));
+ context.engineType = attributes.value(QLatin1String(engineTypeAttributeC)).toString();
+ context.creationDate = dateFromString(attributes.value(QLatin1String(dateAttributeC)).toString());
+ bool readTree = context.isValid();
+ if (!context.creationDate.isValid() || context.creationDate.daysTo(QDate::currentDate()) > toolTipsExpiryDays) {
+ // DEBUG("Expiring tooltip " << context.fileName << '@' << context.position << " from " << creationDate)
+ //readTree = false;
+ } else { //if (className != QLatin1String("Debugger::Internal::DebuggerToolTipWidget")) {
+ //qWarning("Unable to create debugger tool tip widget of class %s", qPrintable(className.toString()));
+ //readTree = false;
+ }
+
+ if (readTree) {
+ DebuggerToolTipHolder *tw = findOrCreateTooltip(context);
+ tw->widget->treeView->m_model.restoreTreeModel(r);
+ tw->widget->pin();
+ tw->widget->titleLabel->setText(DebuggerToolTipManager::tr("%1 (Restored)").arg(context.expression));
+ tw->widget->treeView->expandAll();
+ } else {
+ r.readElementText(QXmlStreamReader::SkipChildElements); // Skip
+ }
+
+ r.readNext(); // Skip </tree>
+ }
+ }
+ }
}
void DebuggerToolTipManager::saveSessionData()
{
- return; // FIXME
-
QString data;
purgeClosedToolTips();
@@ -1308,6 +1141,7 @@ void DebuggerToolTipManager::saveSessionData()
tooltip->saveSessionData(w);
w.writeEndDocument();
+ return; // FIXME
setSessionValue(sessionSettingsKeyC, QVariant(data));
}
@@ -1341,7 +1175,7 @@ static void slotTooltipOverrideRequested
DebuggerToolTipContext context;
context.engineType = engine->objectName();
- context.fileName = editorWidget->textDocument()->filePath();
+ context.fileName = editorWidget->textDocument()->filePath().toString();
context.position = pos;
editorWidget->convertPosition(pos, &context.line, &context.column);
QString raw = cppExpressionAt(editorWidget, context.position, &context.line, &context.column,
@@ -1349,8 +1183,8 @@ static void slotTooltipOverrideRequested
context.expression = fixCppExpression(raw);
if (context.expression.isEmpty()) {
- const Utils::TextContent text(DebuggerToolTipManager::tr("No valid expression"));
- Utils::ToolTip::show(point, text, Internal::mainWindow());
+ ToolTip::show(point, DebuggerToolTipManager::tr("No valid expression"),
+ Internal::mainWindow());
*handled = true;
return;
}
@@ -1375,21 +1209,17 @@ static void slotTooltipOverrideRequested
return;
}
- tooltip->filterModel.setSourceModel(engine->watchHandler()->model());
-
if (localVariable) {
DEBUG("SYNC IN STATE" << tooltip->state);
if (tooltip->state == New) {
tooltip->setState(PendingUnshown);
tooltip->setState(PendingShown);
- tooltip->acquireEngine();
- const Utils::WidgetContent widgetContent(tooltip->widget, true);
- Utils::ToolTip::show(point, widgetContent, Internal::mainWindow());
+ ToolTip::show(point, tooltip->widget, Internal::mainWindow());
} else {
- tooltip->acquireEngine();
- Utils::ToolTip::move(point, Internal::mainWindow());
+ ToolTip::move(point, Internal::mainWindow());
}
*handled = true;
+ tooltip->updateTooltip(engine);
} else {
DEBUG("ASYNC TIP IN STATE" << tooltip->state);
if (tooltip->state == New)
@@ -1400,8 +1230,8 @@ static void slotTooltipOverrideRequested
QTC_CHECK(false);
*handled = engine->setToolTipExpression(editorWidget, context);
if (!*handled) {
- const Utils::TextContent text(DebuggerToolTipManager::tr("Expression too complex"));
- Utils::ToolTip::show(point, text, Internal::mainWindow());
+ ToolTip::show(point, DebuggerToolTipManager::tr("Expression too complex"),
+ Internal::mainWindow());
tooltip->destroy();
}
}
@@ -1512,5 +1342,6 @@ static void purgeClosedToolTips()
}
}
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggertooltipmanager.h b/src/plugins/debugger/debuggertooltipmanager.h
index f45df7df0e..0538c8089a 100644
--- a/src/plugins/debugger/debuggertooltipmanager.h
+++ b/src/plugins/debugger/debuggertooltipmanager.h
@@ -42,11 +42,9 @@ class QAbstractItemModel;
QT_END_NAMESPACE
namespace Debugger {
-
-class DebuggerEngine;
-
namespace Internal {
+class DebuggerEngine;
class StackFrame;
class DebuggerToolTipContext
@@ -56,6 +54,7 @@ public:
bool isValid() const { return !expression.isEmpty(); }
bool matchesFrame(const StackFrame &frame) const;
bool isSame(const DebuggerToolTipContext &other) const;
+ QString toolTip() const;
QString fileName;
int position;
@@ -91,8 +90,6 @@ public:
virtual bool eventFilter(QObject *, QEvent *);
- static QString treeModelClipboardContents(const QAbstractItemModel *model);
-
void debugModeEntered();
void leavingDebugMode();
void sessionAboutToChange();
@@ -103,8 +100,6 @@ public:
public slots:
static void slotUpdateVisibleToolTips();
- void slotItemIsExpanded(const QModelIndex &idx);
- void slotColumnAdjustmentRequested();
};
} // namespace Internal
diff --git a/src/plugins/debugger/disassembleragent.cpp b/src/plugins/debugger/disassembleragent.cpp
index eef3a9281b..f7a96c3ca5 100644
--- a/src/plugins/debugger/disassembleragent.cpp
+++ b/src/plugins/debugger/disassembleragent.cpp
@@ -332,25 +332,24 @@ void DisassemblerAgent::updateBreakpointMarkers()
if (!d->document)
return;
- BreakHandler *handler = breakHandler();
- BreakpointModelIds ids = handler->engineBreakpointIds(d->engine);
- if (ids.isEmpty())
+ Breakpoints bps = breakHandler()->engineBreakpoints(d->engine);
+ if (bps.isEmpty())
return;
const DisassemblerLines contents = d->contentsAtCurrentLocation();
- foreach (TextEditor::TextMark *marker, d->breakpointMarks)
+ foreach (TextMark *marker, d->breakpointMarks)
d->document->removeMark(marker);
qDeleteAll(d->breakpointMarks);
d->breakpointMarks.clear();
- foreach (BreakpointModelId id, ids) {
- const quint64 address = handler->response(id).address;
+ foreach (Breakpoint bp, bps) {
+ const quint64 address = bp.response().address;
if (!address)
continue;
const int lineNumber = contents.lineForAddress(address);
if (!lineNumber)
continue;
TextMark *marker = new TextMark(QString(), lineNumber);
- marker->setIcon(handler->icon(id));
+ marker->setIcon(bp.icon());
marker->setPriority(TextMark::NormalPriority);
d->breakpointMarks.append(marker);
d->document->addMark(marker);
diff --git a/src/plugins/debugger/disassembleragent.h b/src/plugins/debugger/disassembleragent.h
index cb6c02f53f..d99714cec0 100644
--- a/src/plugins/debugger/disassembleragent.h
+++ b/src/plugins/debugger/disassembleragent.h
@@ -34,13 +34,12 @@
#include <QObject>
namespace Debugger {
+namespace Internal {
class DebuggerEngine;
-
-namespace Internal {
+class DisassemblerAgentPrivate;
class DisassemblerLines;
class Location;
-class DisassemblerAgentPrivate;
class DisassemblerAgent : public QObject
{
diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp
index 84e5fdfeae..aef3139c49 100644
--- a/src/plugins/debugger/gdb/attachgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp
@@ -36,14 +36,9 @@
#include <utils/qtcassert.h>
-
namespace Debugger {
namespace Internal {
-#define CB(callback) \
- static_cast<GdbEngine::GdbCommandCallback>(&GdbAttachEngine::callback), \
- STRINGIFY(callback)
-
///////////////////////////////////////////////////////////////////////
//
// AttachGdbAdapter
@@ -72,7 +67,8 @@ void GdbAttachEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
const qint64 pid = startParameters().attachPID;
- postCommand("attach " + QByteArray::number(pid), CB(handleAttach));
+ postCommand("attach " + QByteArray::number(pid), NoFlags,
+ [this](const DebuggerResponse &r) { handleAttach(r); });
// Task 254674 does not want to remove them
//qq->breakHandler()->removeAllBreakpoints();
}
@@ -85,17 +81,17 @@ void GdbAttachEngine::runEngine()
handleStop1(GdbMi());
}
-void GdbAttachEngine::handleAttach(const GdbResponse &response)
+void GdbAttachEngine::handleAttach(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
switch (response.resultClass) {
- case GdbResultDone:
- case GdbResultRunning:
+ case ResultDone:
+ case ResultRunning:
showMessage(_("INFERIOR ATTACHED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
handleInferiorPrepared();
break;
- case GdbResultError:
+ case ResultError:
if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
notifyInferiorSetupFailed(msgPtraceError(startParameters().startMode));
break;
diff --git a/src/plugins/debugger/gdb/attachgdbadapter.h b/src/plugins/debugger/gdb/attachgdbadapter.h
index d67d70404e..6d03609ef2 100644
--- a/src/plugins/debugger/gdb/attachgdbadapter.h
+++ b/src/plugins/debugger/gdb/attachgdbadapter.h
@@ -57,7 +57,7 @@ private:
void interruptInferior2();
void shutdownEngine();
- void handleAttach(const GdbResponse &response);
+ void handleAttach(const DebuggerResponse &response);
};
} // namespace Internal
diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp
index cfddb8aff7..aeb404a06a 100644
--- a/src/plugins/debugger/gdb/coregdbadapter.cpp
+++ b/src/plugins/debugger/gdb/coregdbadapter.cpp
@@ -30,6 +30,8 @@
#include "coregdbadapter.h"
+#include <coreplugin/messagebox.h>
+
#include <debugger/debuggercore.h>
#include <debugger/debuggerprotocol.h>
#include <debugger/debuggerstartparameters.h>
@@ -39,7 +41,6 @@
#include <utils/qtcassert.h>
#include <QDir>
-#include <QMessageBox>
#include <QTemporaryFile>
using namespace Utils;
@@ -47,9 +48,7 @@ using namespace Utils;
namespace Debugger {
namespace Internal {
-#define CB(callback) \
- static_cast<GdbEngine::GdbCommandCallback>(&GdbCoreEngine::callback), \
- STRINGIFY(callback)
+#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
///////////////////////////////////////////////////////////////////////
//
@@ -185,7 +184,7 @@ void GdbCoreEngine::continueSetupEngine()
if (cinfo.isCore) {
m_executable = cinfo.foundExecutableName;
if (m_executable.isEmpty()) {
- showMessageBox(QMessageBox::Warning,
+ Core::AsynchronousMessageBox::warning(
tr("Error Loading Symbols"),
tr("No executable to load symbols from specified core."));
notifyEngineSetupFailed();
@@ -196,7 +195,7 @@ void GdbCoreEngine::continueSetupEngine()
if (isCore) {
startGdb();
} else {
- showMessageBox(QMessageBox::Warning,
+ Core::AsynchronousMessageBox::warning(
tr("Error Loading Core File"),
tr("The specified file does not appear to be a core file."));
notifyEngineSetupFailed();
@@ -214,17 +213,17 @@ void GdbCoreEngine::setupInferior()
// Do that first, otherwise no symbols are loaded.
QFileInfo fi(m_executable);
QByteArray path = fi.absoluteFilePath().toLocal8Bit();
- postCommand("-file-exec-and-symbols \"" + path + '"',
+ postCommand("-file-exec-and-symbols \"" + path + '"', NoFlags,
CB(handleFileExecAndSymbols));
}
-void GdbCoreEngine::handleFileExecAndSymbols(const GdbResponse &response)
+void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
QString core = coreFileName();
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
showMessage(tr("Symbols found."), StatusBar);
- postCommand("target core " + core.toLocal8Bit(),
+ postCommand("target core " + core.toLocal8Bit(), NoFlags,
CB(handleTargetCore));
return;
}
@@ -239,17 +238,17 @@ void GdbCoreEngine::handleFileExecAndSymbols(const GdbResponse &response)
notifyInferiorSetupFailed(msg);
}
-void GdbCoreEngine::handleTargetCore(const GdbResponse &response)
+void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
showMessage(tr("Attached to core."), StatusBar);
handleInferiorPrepared();
// Due to the auto-solib-add off setting, we don't have any
// symbols yet. Load them in order of importance.
- reloadStack(true);
+ reloadStack();
reloadModulesInternal();
- postCommand("p 5", CB(handleRoundTrip));
+ postCommand("p 5", NoFlags, CB(handleRoundTrip));
return;
}
QString msg = tr("Attach to core \"%1\" failed:")
@@ -259,7 +258,7 @@ void GdbCoreEngine::handleTargetCore(const GdbResponse &response)
notifyInferiorSetupFailed(msg);
}
-void GdbCoreEngine::handleRoundTrip(const GdbResponse &response)
+void GdbCoreEngine::handleRoundTrip(const DebuggerResponse &response)
{
Q_UNUSED(response);
loadSymbolsForStack();
@@ -303,7 +302,8 @@ void GdbCoreEngine::unpackCoreIfNeeded()
m_coreUnpackProcess = new QProcess(this);
m_coreUnpackProcess->setWorkingDirectory(QDir::tempPath());
m_coreUnpackProcess->start(QLatin1String("lzop"), arguments);
- connect(m_coreUnpackProcess, SIGNAL(finished(int)), SLOT(continueSetupEngine()));
+ connect(m_coreUnpackProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
+ this, &GdbCoreEngine::continueSetupEngine);
} else if (m_coreName.endsWith(QLatin1String(".gz"))) {
m_tempCoreName = tempCoreFilename();
showMessage(msg.arg(m_tempCoreName));
@@ -313,8 +313,9 @@ void GdbCoreEngine::unpackCoreIfNeeded()
m_coreUnpackProcess = new QProcess(this);
m_coreUnpackProcess->setWorkingDirectory(QDir::tempPath());
m_coreUnpackProcess->start(QLatin1String("gzip"), arguments);
- connect(m_coreUnpackProcess, SIGNAL(readyRead()), SLOT(writeCoreChunk()));
- connect(m_coreUnpackProcess, SIGNAL(finished(int)), SLOT(continueSetupEngine()));
+ connect(m_coreUnpackProcess, &QProcess::readyRead, this, &GdbCoreEngine::writeCoreChunk);
+ connect(m_coreUnpackProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
+ this, &GdbCoreEngine::continueSetupEngine);
} else {
continueSetupEngine();
}
diff --git a/src/plugins/debugger/gdb/coregdbadapter.h b/src/plugins/debugger/gdb/coregdbadapter.h
index 4522789c54..965a8bcd1f 100644
--- a/src/plugins/debugger/gdb/coregdbadapter.h
+++ b/src/plugins/debugger/gdb/coregdbadapter.h
@@ -59,6 +59,7 @@ public:
bool isCore;
};
static CoreInfo readExecutableNameFromCore(const QString &debuggerCmd, const QString &coreFile);
+
private:
void setupEngine();
void setupInferior();
@@ -66,9 +67,9 @@ private:
void interruptInferior();
void shutdownEngine();
- void handleFileExecAndSymbols(const GdbResponse &response);
- void handleTargetCore(const GdbResponse &response);
- void handleRoundTrip(const GdbResponse &response);
+ void handleFileExecAndSymbols(const DebuggerResponse &response);
+ void handleTargetCore(const DebuggerResponse &response);
+ void handleRoundTrip(const DebuggerResponse &response);
void unpackCoreIfNeeded();
QString coreFileName() const;
QString coreName() const;
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 8072f737ed..56ae99126c 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -52,6 +52,7 @@
#include <debugger/disassembleragent.h>
#include <debugger/memoryagent.h>
#include <debugger/sourceutils.h>
+#include <debugger/terminal.h>
#include <debugger/breakhandler.h>
#include <debugger/moduleshandler.h>
@@ -65,6 +66,7 @@
#include <debugger/shared/hostutils.h>
#include <coreplugin/icore.h>
+#include <coreplugin/messagebox.h>
#include <projectexplorer/devicesupport/deviceprocess.h>
#include <projectexplorer/itaskhandler.h>
#include <projectexplorer/taskhub.h>
@@ -77,11 +79,11 @@
#include <utils/qtcprocess.h>
#include <utils/savedaction.h>
+#include <QBuffer>
#include <QDirIterator>
-#include <QTemporaryFile>
-
#include <QMessageBox>
#include <QPushButton>
+#include <QTemporaryFile>
using namespace Core;
using namespace ProjectExplorer;
@@ -94,8 +96,7 @@ enum { debugPending = 0 };
#define PENDING_DEBUG(s) do { if (debugPending) qDebug() << s; } while (0)
-#define CB(callback) &GdbEngine::callback, STRINGIFY(callback)
-
+#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
QByteArray GdbEngine::tooltipIName(const QString &exp)
{
@@ -141,7 +142,7 @@ static int &currentToken()
return token;
}
-static QByteArray parsePlainConsoleStream(const GdbResponse &response)
+static QByteArray parsePlainConsoleStream(const DebuggerResponse &response)
{
QByteArray out = response.consoleStreamOutput;
// FIXME: proper decoding needed
@@ -221,7 +222,6 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters)
m_pendingBreakpointRequests = 0;
m_commandsDoneCallback = 0;
m_stackNeeded = false;
- m_preparedForQmlBreak = false;
m_terminalTrap = startParameters.useTerminal;
m_fullStartDone = false;
m_systemDumpersLoaded = false;
@@ -231,16 +231,17 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters)
//ExtensionSystem::PluginManager::addObject(m_debugInfoTaskHandler);
m_commandTimer.setSingleShot(true);
- connect(&m_commandTimer, SIGNAL(timeout()), SLOT(commandTimeout()));
+ connect(&m_commandTimer, &QTimer::timeout,
+ this, &GdbEngine::commandTimeout);
- connect(action(AutoDerefPointers), SIGNAL(valueChanged(QVariant)),
- SLOT(reloadLocals()));
- connect(action(CreateFullBacktrace), SIGNAL(triggered()),
- SLOT(createFullBacktrace()));
- connect(action(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)),
- SLOT(reloadLocals()));
- connect(action(UseDynamicType), SIGNAL(valueChanged(QVariant)),
- SLOT(reloadLocals()));
+ connect(action(AutoDerefPointers), &SavedAction::valueChanged,
+ this, &GdbEngine::reloadLocals);
+ connect(action(CreateFullBacktrace), &QAction::triggered,
+ this, &GdbEngine::createFullBacktrace);
+ connect(action(UseDebuggingHelpers), &SavedAction::valueChanged,
+ this, &GdbEngine::reloadLocals);
+ connect(action(UseDynamicType), &SavedAction::valueChanged,
+ this, &GdbEngine::reloadLocals);
}
GdbEngine::~GdbEngine()
@@ -534,7 +535,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
result = GdbMi();
result.fromString(ba);
BreakHandler *handler = breakHandler();
- BreakpointModelId id;
+ Breakpoint bp;
BreakpointResponse br;
foreach (const GdbMi &bkpt, result.children()) {
const QByteArray nr = bkpt["number"].data();
@@ -546,17 +547,15 @@ void GdbEngine::handleResponse(const QByteArray &buff)
updateResponse(sub, bkpt);
sub.id = rid;
sub.type = br.type;
- handler->insertSubBreakpoint(id, sub);
+ bp.insertSubBreakpoint(sub);
} else {
// A primary breakpoint.
- id = handler->findBreakpointByResponseId(rid);
+ bp = handler->findBreakpointByResponseId(rid);
//qDebug() << "NR: " << nr << "RID: " << rid
- // << "ID: " << id;
- //BreakpointModelId id =
- // handler->findBreakpointByResponseId(rid);
- br = handler->response(id);
+ // << "ID: " << bp.id();
+ br = bp.response();
updateResponse(br, bkpt);
- handler->setResponse(id, br);
+ bp.setResponse(br);
}
}
}
@@ -576,16 +575,14 @@ void GdbEngine::handleResponse(const QByteArray &buff)
} else if (asyncClass == "breakpoint-deleted") {
// "breakpoint-deleted" "{id="1"}"
// New in FSF gdb since 2011-04-27.
- BreakHandler *handler = breakHandler();
QByteArray nr = result["id"].data();
BreakpointResponseId rid(nr);
- BreakpointModelId id = handler->findBreakpointByResponseId(rid);
- if (id.isValid()) {
+ if (Breakpoint bp = breakHandler()->findBreakpointByResponseId(rid)) {
// This also triggers when a temporary breakpoint is hit.
// We do not really want that, as this loses all information.
// FIXME: Use a special marker for this case?
- if (!handler->isOneShot(id))
- handler->removeAlienBreakpoint(id);
+ if (!bp.isOneShot())
+ bp.removeAlienBreakpoint();
}
} else if (asyncClass == "cmd-param-changed") {
// New since 2012-08-09
@@ -641,15 +638,6 @@ void GdbEngine::handleResponse(const QByteArray &buff)
const Task::TaskType type = isFatalWinException(exCode) ? Task::Error : Task::Warning;
TaskHub::addTask(type, m_lastWinException, Constants::TASK_CATEGORY_DEBUGGER_RUNTIME);
}
-
- if (data.startsWith("QMLBP:")) {
- int pos1 = 6;
- int pos2 = data.indexOf(' ', pos1);
- m_qmlBreakpointResponseId2 = BreakpointResponseId(data.mid(pos1, pos2 - pos1));
- //qDebug() << "FOUND QMLBP: " << m_qmlBreakpointNumbers[2];
- //qDebug() << "CURRENT: " << m_qmlBreakpointNumbers;
- }
-
break;
}
@@ -696,7 +684,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
}
case '^': {
- GdbResponse response;
+ DebuggerResponse response;
response.token = token;
@@ -706,17 +694,17 @@ void GdbEngine::handleResponse(const QByteArray &buff)
QByteArray resultClass = QByteArray::fromRawData(from, inner - from);
if (resultClass == "done")
- response.resultClass = GdbResultDone;
+ response.resultClass = ResultDone;
else if (resultClass == "running")
- response.resultClass = GdbResultRunning;
+ response.resultClass = ResultRunning;
else if (resultClass == "connected")
- response.resultClass = GdbResultConnected;
+ response.resultClass = ResultConnected;
else if (resultClass == "error")
- response.resultClass = GdbResultError;
+ response.resultClass = ResultError;
else if (resultClass == "exit")
- response.resultClass = GdbResultExit;
+ response.resultClass = ResultExit;
else
- response.resultClass = GdbResultUnknown;
+ response.resultClass = ResultUnknown;
from = inner;
if (from != to) {
@@ -803,6 +791,9 @@ void GdbEngine::interruptInferior()
QTC_ASSERT(state() == InferiorStopRequested,
qDebug() << "INTERRUPT INFERIOR: " << state(); return);
+ if (terminal()->sendInterrupt())
+ return;
+
if (usesExecInterrupt()) {
postCommand("-exec-interrupt", Immediate);
} else {
@@ -839,7 +830,7 @@ void GdbEngine::handleInterruptDeviceInferior(const QString &error)
void GdbEngine::interruptInferiorTemporarily()
{
- foreach (const GdbCommand &cmd, m_commandsToRunOnTemporaryBreak) {
+ foreach (const DebuggerCommand &cmd, m_commandsToRunOnTemporaryBreak) {
if (cmd.flags & LosesChild) {
notifyInferiorIll();
return;
@@ -862,40 +853,33 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
notifyInferiorPid(pid);
}
-void GdbEngine::postCommand(const QByteArray &command, GdbCommandCallback callback,
- const char *callbackName, const QVariant &cookie)
+void GdbEngine::runCommand(const DebuggerCommand &command)
{
- postCommand(command, NoFlags, callback, callbackName, cookie);
+ QByteArray cmd = command.function + "({" + command.args + "})";
+ postCommand("python theDumper." + cmd, command.flags, command.callback);
}
-void GdbEngine::postCommand(const QByteArray &command, GdbCommandFlags flags,
- GdbCommandCallback callback, const char *callbackName,
- const QVariant &cookie)
+void GdbEngine::postCommand(const QByteArray &command, int flags,
+ DebuggerCommand::Callback callback)
{
- GdbCommand cmd;
- cmd.command = command;
+ DebuggerCommand cmd;
+ cmd.function = command;
cmd.flags = flags;
cmd.callback = callback;
- cmd.callbackName = callbackName;
- cmd.cookie = cookie;
- postCommandHelper(cmd);
-}
-void GdbEngine::postCommandHelper(const GdbCommand &cmd)
-{
if (!stateAcceptsGdbCommands(state())) {
- PENDING_DEBUG(_("NO GDB PROCESS RUNNING, CMD IGNORED: " + cmd.command));
+ PENDING_DEBUG(_("NO GDB PROCESS RUNNING, CMD IGNORED: " + cmd.function));
showMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: %1 %2")
- .arg(_(cmd.command)).arg(state()));
+ .arg(_(cmd.function)).arg(state()));
return;
}
if (cmd.flags & RebuildBreakpointModel) {
++m_pendingBreakpointRequests;
- PENDING_DEBUG(" BRWAKPOINT MODEL:" << cmd.command << "=>" << cmd.callbackName
+ PENDING_DEBUG(" BRWAKPOINT MODEL:" << cmd.function
<< "INCREMENTS PENDING TO" << m_pendingBreakpointRequests);
} else {
- PENDING_DEBUG(" OTHER (IN):" << cmd.command << "=>" << cmd.callbackName
+ PENDING_DEBUG(" OTHER (IN):" << cmd.function
<< "LEAVES PENDING WATCH AT" << m_uncompleted.size()
<< "LEAVES PENDING BREAKPOINT AT" << m_pendingBreakpointRequests);
}
@@ -916,7 +900,7 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
flushCommand(cmd);
} else {
// Queue the commands that we cannot send at once.
- showMessage(_("QUEUING COMMAND " + cmd.command));
+ showMessage(_("QUEUING COMMAND " + cmd.function));
m_commandsToRunOnTemporaryBreak.append(cmd);
if (state() == InferiorStopRequested) {
if (cmd.flags & LosesChild)
@@ -929,10 +913,10 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
interruptInferiorTemporarily();
} else {
qDebug() << "ATTEMPTING TO QUEUE COMMAND "
- << cmd.command << "IN INAPPROPRIATE STATE" << state();
+ << cmd.function << "IN INAPPROPRIATE STATE" << state();
}
}
- } else if (!cmd.command.isEmpty()) {
+ } else if (!cmd.function.isEmpty()) {
flushCommand(cmd);
}
}
@@ -941,17 +925,16 @@ void GdbEngine::flushQueuedCommands()
{
showStatusMessage(tr("Processing queued commands"), 1000);
while (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
- GdbCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst();
- showMessage(_("RUNNING QUEUED COMMAND " + cmd.command + ' '
- + (cmd.callbackName ? cmd.callbackName : "<unnamed callback>")));
+ DebuggerCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst();
+ showMessage(_("RUNNING QUEUED COMMAND " + cmd.function));
flushCommand(cmd);
}
}
-void GdbEngine::flushCommand(const GdbCommand &cmd0)
+void GdbEngine::flushCommand(const DebuggerCommand &cmd0)
{
if (!stateAcceptsGdbCommands(state())) {
- showMessage(_(cmd0.command), LogInput);
+ showMessage(_(cmd0.function), LogInput);
showMessage(_("GDB PROCESS ACCEPTS NO CMD IN STATE %1 ").arg(state()));
return;
}
@@ -960,13 +943,13 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
const int token = ++currentToken();
- GdbCommand cmd = cmd0;
+ DebuggerCommand cmd = cmd0;
cmd.postTime = QTime::currentTime();
- m_cookieForToken[token] = cmd;
+ m_commandForToken[token] = cmd;
if (cmd.flags & ConsoleCommand)
- cmd.command = "-interpreter-exec console \"" + cmd.command + '"';
- cmd.command = QByteArray::number(token) + cmd.command;
- showMessage(_(cmd.command), LogInput);
+ cmd.function = "-interpreter-exec console \"" + cmd.function + '"';
+ cmd.function = QByteArray::number(token) + cmd.function;
+ showMessage(_(cmd.function), LogInput);
if (m_scheduledTestResponses.contains(token)) {
// Fake response for test cases.
@@ -978,7 +961,7 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
QMetaObject::invokeMethod(this, "handleResponse",
Q_ARG(QByteArray, buffer));
} else {
- write(cmd.command + "\r\n");
+ write(cmd.function + "\r\n");
// Start Watchdog.
if (m_commandTimer.interval() <= 20000)
@@ -987,7 +970,7 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
// sent and a response could be retrieved. We don't want the watchdog
// to bark in that case since the only possible outcome is a dead
// process anyway.
- if (!cmd.command.endsWith("-gdb-exit"))
+ if (!cmd.function.endsWith("-gdb-exit"))
m_commandTimer.start();
//if (cmd.flags & LosesChild)
@@ -1003,23 +986,20 @@ int GdbEngine::commandTimeoutTime() const
void GdbEngine::commandTimeout()
{
- QList<int> keys = m_cookieForToken.keys();
+ QList<int> keys = m_commandForToken.keys();
Utils::sort(keys);
bool killIt = false;
foreach (int key, keys) {
- const GdbCommand &cmd = m_cookieForToken.value(key);
+ const DebuggerCommand &cmd = m_commandForToken.value(key);
if (!(cmd.flags & NonCriticalResponse))
killIt = true;
- QByteArray msg = QByteArray::number(key);
- msg += ": " + cmd.command + " => ";
- msg += cmd.callbackName ? cmd.callbackName : "<unnamed callback>";
- showMessage(_(msg));
+ showMessage(_(QByteArray::number(key) + ": " + cmd.function));
}
if (killIt) {
QStringList commands;
- foreach (const GdbCommand &cookie, m_cookieForToken)
+ foreach (const DebuggerCommand &cmd, m_commandForToken)
commands << QString(_("\"%1\"")).arg(
- QString::fromLatin1(cookie.command));
+ QString::fromLatin1(cmd.function));
showMessage(_("TIMED OUT WAITING FOR GDB REPLY. "
"COMMANDS STILL IN PROGRESS: ") + commands.join(_(", ")));
int timeOut = m_commandTimer.interval();
@@ -1047,7 +1027,7 @@ void GdbEngine::commandTimeout()
}
}
-void GdbEngine::handleResultRecord(GdbResponse *response)
+void GdbEngine::handleResultRecord(DebuggerResponse *response)
{
//qDebug() << "TOKEN:" << response->token
// << " ACCEPTABLE:" << m_oldestAcceptableToken;
@@ -1057,7 +1037,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
if (token == -1)
return;
- if (!m_cookieForToken.contains(token)) {
+ if (!m_commandForToken.contains(token)) {
// In theory this should not happen (rather the error should be
// reported in the "first" response to the command) in practice it
// does. We try to handle a few situations we are aware of gracefully.
@@ -1065,14 +1045,14 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
showMessage(_("COOKIE FOR TOKEN %1 ALREADY EATEN (%2). "
"TWO RESPONSES FOR ONE COMMAND?").arg(token).
arg(QString::fromLatin1(stateName(state()))));
- if (response->resultClass == GdbResultError) {
+ if (response->resultClass == ResultError) {
QByteArray msg = response->data["msg"].data();
if (msg == "Cannot find new threads: generic error") {
// Handle a case known to occur on Linux/gdb 6.8 when debugging moc
// with helpers enabled. In this case we get a second response with
// msg="Cannot find new threads: generic error"
showMessage(_("APPLYING WORKAROUND #1"));
- showMessageBox(QMessageBox::Critical,
+ AsynchronousMessageBox::critical(
tr("Executable failed"), QString::fromLocal8Bit(msg));
showStatusMessage(tr("Process failed to start"));
//shutdown();
@@ -1098,7 +1078,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
//showStatusMessage(tr("Executable failed: %1")
// .arg(QString::fromLocal8Bit(msg)));
//shutdown();
- //showMessageBox(QMessageBox::Critical,
+ //Core::AsynchronousMessageBox::critical(
// tr("Executable failed"), QString::fromLocal8Bit(msg));
} else if (msg.contains("Cannot insert breakpoint")) {
// For breakpoints set by address to non-existent addresses we
@@ -1112,7 +1092,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
// long as the breakpoints are enabled.
// FIXME: Should we silently disable the offending breakpoints?
showMessage(_("APPLYING WORKAROUND #5"));
- showMessageBox(QMessageBox::Critical,
+ AsynchronousMessageBox::critical(
tr("Setting breakpoints failed"), QString::fromLocal8Bit(msg));
QTC_CHECK(state() == InferiorRunOk);
notifyInferiorSpontaneousStop();
@@ -1128,17 +1108,17 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
if (!m_lastWinException.isEmpty())
logMsg = m_lastWinException + QLatin1Char('\n');
logMsg += QString::fromLocal8Bit(msg);
- showMessageBox(QMessageBox::Critical, tr("Executable Failed"), logMsg);
+ AsynchronousMessageBox::critical(tr("Executable Failed"), logMsg);
showStatusMessage(tr("Executable failed: %1").arg(logMsg));
}
}
return;
}
- GdbCommand cmd = m_cookieForToken.take(token);
+ DebuggerCommand cmd = m_commandForToken.take(token);
if (boolSetting(LogTimeStamps)) {
showMessage(_("Response time: %1: %2 s")
- .arg(_(cmd.command))
+ .arg(_(cmd.function))
.arg(cmd.postTime.msecsTo(QTime::currentTime()) / 1000.),
LogTime);
}
@@ -1148,33 +1128,31 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
return;
}
- response->cookie = cmd.cookie;
-
bool isExpectedResult =
- (response->resultClass == GdbResultError) // Can always happen.
- || (response->resultClass == GdbResultRunning && (cmd.flags & RunRequest))
- || (response->resultClass == GdbResultExit && (cmd.flags & ExitRequest))
- || (response->resultClass == GdbResultDone);
- // GdbResultDone can almost "always" happen. Known examples are:
- // (response->resultClass == GdbResultDone && cmd.command == "continue")
+ (response->resultClass == ResultError) // Can always happen.
+ || (response->resultClass == ResultRunning && (cmd.flags & RunRequest))
+ || (response->resultClass == ResultExit && (cmd.flags & ExitRequest))
+ || (response->resultClass == ResultDone);
+ // ResultDone can almost "always" happen. Known examples are:
+ // (response->resultClass == ResultDone && cmd.function == "continue")
// Happens with some incarnations of gdb 6.8 for "jump to line"
- // (response->resultClass == GdbResultDone && cmd.command.startsWith("jump"))
- // (response->resultClass == GdbResultDone && cmd.command.startsWith("detach"))
+ // (response->resultClass == ResultDone && cmd.function.startsWith("jump"))
+ // (response->resultClass == ResultDone && cmd.function.startsWith("detach"))
// Happens when stepping finishes very quickly and issues *stopped and ^done
// instead of ^running and *stopped
- // (response->resultClass == GdbResultDone && (cmd.flags & RunRequest));
+ // (response->resultClass == ResultDone && (cmd.flags & RunRequest));
if (!isExpectedResult) {
const DebuggerStartParameters &sp = startParameters();
Abi abi = sp.toolChainAbi;
if (abi.os() == Abi::WindowsOS
- && cmd.command.startsWith("attach")
+ && cmd.function.startsWith("attach")
&& (sp.startMode == AttachExternal || sp.useTerminal))
{
// Ignore spurious 'running' responses to 'attach'.
} else {
- QByteArray rsp = GdbResponse::stringFromResultClass(response->resultClass);
- rsp = "UNEXPECTED RESPONSE '" + rsp + "' TO COMMAND '" + cmd.command + "'";
+ QByteArray rsp = DebuggerResponse::stringFromResultClass(response->resultClass);
+ rsp = "UNEXPECTED RESPONSE '" + rsp + "' TO COMMAND '" + cmd.function + "'";
qWarning() << rsp << " AT " __FILE__ ":" STRINGIFY(__LINE__);
showMessage(_(rsp));
}
@@ -1184,18 +1162,18 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
--m_nonDiscardableCount;
if (cmd.callback)
- (this->*cmd.callback)(*response);
+ cmd.callback(*response);
if (cmd.flags & RebuildBreakpointModel) {
--m_pendingBreakpointRequests;
- PENDING_DEBUG(" BREAKPOINT" << cmd.command << "=>" << cmd.callbackName
+ PENDING_DEBUG(" BREAKPOINT" << cmd.function
<< "DECREMENTS PENDING TO" << m_uncompleted.size());
if (m_pendingBreakpointRequests <= 0) {
PENDING_DEBUG("\n\n ... AND TRIGGERS BREAKPOINT MODEL UPDATE\n");
attemptBreakpointSynchronization();
}
} else {
- PENDING_DEBUG(" OTHER (OUT):" << cmd.command << "=>" << cmd.callbackName
+ PENDING_DEBUG(" OTHER (OUT):" << cmd.function
<< "LEAVES PENDING WATCH AT" << m_uncompleted.size()
<< "LEAVES PENDING BREAKPOINT AT" << m_pendingBreakpointRequests);
}
@@ -1213,17 +1191,17 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
// An optimization would be requesting the continue immediately when the
// event loop is entered, and let individual commands have a flag to suppress
// that behavior.
- if (m_commandsDoneCallback && m_cookieForToken.isEmpty()) {
+ if (m_commandsDoneCallback && m_commandForToken.isEmpty()) {
showMessage(_("ALL COMMANDS DONE; INVOKING CALLBACK"));
CommandsDoneCallback cont = m_commandsDoneCallback;
m_commandsDoneCallback = 0;
- if (response->resultClass != GdbResultRunning) //only start if the thing is not already running
+ if (response->resultClass != ResultRunning) //only start if the thing is not already running
(this->*cont)();
} else {
- PENDING_DEBUG("MISSING TOKENS: " << m_cookieForToken.keys());
+ PENDING_DEBUG("MISSING TOKENS: " << m_commandForToken.keys());
}
- if (m_cookieForToken.isEmpty())
+ if (m_commandForToken.isEmpty())
m_commandTimer.stop();
}
@@ -1239,8 +1217,8 @@ void GdbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages
if (!(languages & CppLanguage))
return;
QTC_CHECK(acceptsDebuggerCommands());
- GdbCommand cmd;
- cmd.command = command.toLatin1();
+ DebuggerCommand cmd;
+ cmd.function = command.toLatin1();
flushCommand(cmd);
}
@@ -1250,18 +1228,20 @@ void GdbEngine::updateAll()
//PENDING_DEBUG("UPDATING ALL\n");
QTC_CHECK(state() == InferiorUnrunnable || state() == InferiorStopOk);
reloadModulesInternal();
- postCommand("-stack-list-frames", CB(handleStackListFrames),
- QVariant::fromValue<StackCookie>(StackCookie(false, true)));
+ DebuggerCommand cmd = stackCommand(action(MaximalStackDepth)->value().toInt());
+ cmd.flags = NoFlags;
+ cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, false); };
+ runCommand(cmd);
stackHandler()->setCurrentIndex(0);
- postCommand("-thread-info", CB(handleThreadInfo), 0);
+ postCommand("-thread-info", NoFlags, CB(handleThreadInfo));
reloadRegisters();
updateLocals();
}
-void GdbEngine::handleQuerySources(const GdbResponse &response)
+void GdbEngine::handleQuerySources(const DebuggerResponse &response)
{
m_sourcesListUpdating = false;
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
QMap<QString, QString> oldShortToFull = m_shortToFullName;
m_shortToFullName.clear();
m_fullToShortName.clear();
@@ -1286,13 +1266,13 @@ void GdbEngine::handleQuerySources(const GdbResponse &response)
}
}
-void GdbEngine::handleExecuteJumpToLine(const GdbResponse &response)
+void GdbEngine::handleExecuteJumpToLine(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultRunning) {
+ if (response.resultClass == ResultRunning) {
// All is fine. Waiting for a *running
// and the temporary breakpoint to be hit.
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
- } else if (response.resultClass == GdbResultError) {
+ } else if (response.resultClass == ResultError) {
// Could be "Unreasonable jump request" or similar.
QString out = tr("Cannot jump. Stopped");
QByteArray msg = response.data["msg"].data();
@@ -1300,20 +1280,20 @@ void GdbEngine::handleExecuteJumpToLine(const GdbResponse &response)
out += QString::fromLatin1(". " + msg);
showStatusMessage(out);
notifyInferiorRunFailed();
- } else if (response.resultClass == GdbResultDone) {
+ } else if (response.resultClass == ResultDone) {
// This happens on old gdb. Trigger the effect of a '*stopped'.
showStatusMessage(tr("Jumped. Stopped"));
notifyInferiorSpontaneousStop();
- handleStop2(response);
+ handleStop2(response.data);
}
}
-void GdbEngine::handleExecuteRunToLine(const GdbResponse &response)
+void GdbEngine::handleExecuteRunToLine(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultRunning) {
+ if (response.resultClass == ResultRunning) {
// All is fine. Waiting for a *running
// and the temporary breakpoint to be hit.
- } else if (response.resultClass == GdbResultDone) {
+ } else if (response.resultClass == ResultDone) {
// This happens on old gdb (Mac). gdb is not stopped yet,
// but merely accepted the continue.
// >&"continue\n"
@@ -1382,7 +1362,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
if (!m_fullStartDone) {
m_fullStartDone = true;
postCommand("sharedlibrary .*");
- postCommand("p 3", CB(handleStop1));
+ postCommand("p 3", NoFlags, [this, data](const DebuggerResponse &) { handleStop1(data); });
gotoHandleStop1 = false;
}
@@ -1391,8 +1371,10 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
int lineNumber = 0;
QString fullName;
+ QByteArray function;
if (frame.isValid()) {
const GdbMi lineNumberG = frame["line"];
+ function = frame["func"].data();
if (lineNumberG.isValid()) {
lineNumber = lineNumberG.toInt();
fullName = cleanupFullName(QString::fromLocal8Bit(frame["fullname"].data()));
@@ -1403,31 +1385,28 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
showMessage(_("INVALID STOPPED REASON"), LogWarning);
}
- if (rid.isValid() && frame.isValid()
- && !isQmlStepBreakpoint(rid)
- && !isQFatalBreakpoint(rid)) {
+ if (rid.isValid() && frame.isValid() && !isQFatalBreakpoint(rid)) {
// Use opportunity to update the breakpoint marker position.
- BreakHandler *handler = breakHandler();
//qDebug() << " PROBLEM: " << m_qmlBreakpointNumbers << rid
// << isQmlStepBreakpoint1(rid)
// << isQmlStepBreakpoint2(rid)
- BreakpointModelId id = handler->findBreakpointByResponseId(rid);
- const BreakpointResponse &response = handler->response(id);
+ Breakpoint bp = breakHandler()->findBreakpointByResponseId(rid);
+ const BreakpointResponse &response = bp.response();
QString fileName = response.fileName;
if (fileName.isEmpty())
- fileName = handler->fileName(id);
+ fileName = bp.fileName();
if (fileName.isEmpty())
fileName = fullName;
if (!fileName.isEmpty())
- handler->setMarkerFileAndLine(id, fileName, lineNumber);
+ bp.setMarkerFileAndLine(fileName, lineNumber);
}
//qDebug() << "BP " << rid << data.toString();
// Quickly set the location marker.
if (lineNumber && !boolSetting(OperateByInstruction)
&& QFileInfo::exists(fullName)
- && !isQmlStepBreakpoint(rid)
- && !isQFatalBreakpoint(rid))
+ && !isQFatalBreakpoint(rid)
+ && function != "qt_v4TriggeredBreakpointHook")
gotoLocation(Location(fullName, lineNumber));
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
@@ -1469,9 +1448,6 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
- if (isQmlStepBreakpoint1(rid))
- return;
-
if (gotoHandleStop1)
handleStop1(data);
}
@@ -1481,11 +1457,6 @@ static QByteArray stopSignal(const Abi &abi)
return (abi.os() == Abi::WindowsOS) ? QByteArray("SIGTRAP") : QByteArray("SIGINT");
}
-void GdbEngine::handleStop1(const GdbResponse &response)
-{
- handleStop1(response.cookie.value<GdbMi>());
-}
-
void GdbEngine::handleStop1(const GdbMi &data)
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
@@ -1550,17 +1521,14 @@ void GdbEngine::handleStop1(const GdbMi &data)
if (!m_systemDumpersLoaded) {
m_systemDumpersLoaded = true;
if (m_gdbVersion >= 70400 && boolSetting(LoadGdbDumpers))
- postCommand("importPlainDumpers");
+ postCommand("importPlainDumpers on");
+ else
+ postCommand("importPlainDumpers off");
}
handleStop2(data);
}
-void GdbEngine::handleStop2(const GdbResponse &response)
-{
- handleStop2(response.cookie.value<GdbMi>());
-}
-
void GdbEngine::handleStop2(const GdbMi &data)
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
@@ -1628,14 +1596,13 @@ void GdbEngine::handleStop2(const GdbMi &data)
// thread-id="1",stopped-threads="all",core="2"
const GdbMi wpt = data["wpt"];
const BreakpointResponseId rid(wpt["number"].data());
- const BreakpointModelId id = breakHandler()->findBreakpointByResponseId(rid);
+ const Breakpoint bp = breakHandler()->findBreakpointByResponseId(rid);
const quint64 bpAddress = wpt["exp"].data().mid(1).toULongLong(0, 0);
QString msg;
- if (id && breakHandler()->type(id) == WatchpointAtExpression)
- msg = msgWatchpointByExpressionTriggered(id, rid.majorPart(),
- breakHandler()->expression(id));
- if (id && breakHandler()->type(id) == WatchpointAtAddress)
- msg = msgWatchpointByAddressTriggered(id, rid.majorPart(), bpAddress);
+ if (bp.type() == WatchpointAtExpression)
+ msg = bp.msgWatchpointByExpressionTriggered(rid.majorPart(), bp.expression());
+ if (bp.type() == WatchpointAtAddress)
+ msg = bp.msgWatchpointByAddressTriggered(rid.majorPart(), bpAddress);
GdbMi value = data["value"];
GdbMi oldValue = value["old"];
GdbMi newValue = value["new"];
@@ -1651,8 +1618,8 @@ void GdbEngine::handleStop2(const GdbMi &data)
gNumber = data["number"];
const BreakpointResponseId rid(gNumber.data());
const QByteArray threadId = data["thread-id"].data();
- const BreakpointModelId id = breakHandler()->findBreakpointByResponseId(rid);
- showStatusMessage(msgBreakpointTriggered(id, rid.majorPart(), _(threadId)));
+ const Breakpoint bp = breakHandler()->findBreakpointByResponseId(rid);
+ showStatusMessage(bp.msgBreakpointTriggered(rid.majorPart(), _(threadId)));
m_currentThread = threadId;
} else {
QString reasontr = msgStopped(_(reason));
@@ -1661,7 +1628,7 @@ void GdbEngine::handleStop2(const GdbMi &data)
QByteArray meaning = data["signal-meaning"].data();
// Ignore these as they are showing up regularly when
// stopping debugging.
- if (name == stopSignal(sp.toolChainAbi)) {
+ if (name == stopSignal(sp.toolChainAbi) || sp.expectedSignals.contains(name)) {
showMessage(_(name + " CONSIDERED HARMLESS. CONTINUING."));
} else {
showMessage(_("HANDLING SIGNAL " + name));
@@ -1692,9 +1659,9 @@ void GdbEngine::handleStop2()
postCommand("-thread-info", Discardable, CB(handleThreadInfo));
}
-void GdbEngine::handleInfoProc(const GdbResponse &response)
+void GdbEngine::handleInfoProc(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
static QRegExp re(_("\\bprocess ([0-9]+)\n"));
QTC_ASSERT(re.isValid(), return);
if (re.indexIn(_(response.consoleStreamOutput)) != -1)
@@ -1702,10 +1669,10 @@ void GdbEngine::handleInfoProc(const GdbResponse &response)
}
}
-void GdbEngine::handleShowVersion(const GdbResponse &response)
+void GdbEngine::handleShowVersion(const DebuggerResponse &response)
{
showMessage(_("PARSING VERSION: " + response.toString()));
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
bool isMacGdb = false;
int gdbBuildVersion = -1;
m_gdbVersion = 100;
@@ -1737,52 +1704,18 @@ void GdbEngine::handleShowVersion(const GdbResponse &response)
}
}
-void GdbEngine::handleListFeatures(const GdbResponse &response)
+void GdbEngine::handleListFeatures(const DebuggerResponse &response)
{
showMessage(_("FEATURES: " + response.toString()));
}
-void GdbEngine::handlePythonSetup(const GdbResponse &response)
+void GdbEngine::handlePythonSetup(const DebuggerResponse &response)
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
- bool needSetup = false;
-
- const QString path = stringSetting(ExtraDumperFile);
- if (!path.isEmpty()) {
- QFileInfo fi(path);
- postCommand("python sys.path.insert(1, '" + fi.absolutePath().toUtf8() + "')");
- postCommand("python from " + fi.baseName().toUtf8() + " import *");
- needSetup = true;
- }
-
- const QString commands = stringSetting(ExtraDumperCommands);
- if (!commands.isEmpty()) {
- postCommand(commands.toLocal8Bit());
- needSetup = true;
- }
-
- if (needSetup)
- postCommand("bbsetup");
-
+ if (response.resultClass == ResultDone) {
GdbMi data;
data.fromStringMultiple(response.consoleStreamOutput);
- const GdbMi dumpers = data["dumpers"];
- foreach (const GdbMi &dumper, dumpers.children()) {
- QByteArray type = dumper["type"].data();
- QStringList formats(tr("Raw structure"));
- foreach (const QByteArray &format,
- dumper["formats"].data().split(',')) {
- if (format == "Normal")
- formats.append(tr("Normal"));
- else if (format == "Displayed")
- formats.append(tr("Displayed"));
- else if (!format.isEmpty())
- formats.append(_(format));
- }
- watchHandler()->addTypeFormats(type, formats);
- }
-
+ watchHandler()->addDumpers(data["dumpers"]);
loadInitScript();
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("ENGINE SUCCESSFULLY STARTED"));
@@ -1793,7 +1726,7 @@ void GdbEngine::handlePythonSetup(const GdbResponse &response)
QString out1 = _("The selected build of GDB does not support Python scripting.");
QString out2 = _("It cannot be used in Qt Creator.");
showStatusMessage(out1 + QLatin1Char(' ') + out2);
- showMessageBox(QMessageBox::Critical, tr("Execution Error"), out1 + _("<br>") + out2);
+ AsynchronousMessageBox::critical(tr("Execution Error"), out1 + _("<br>") + out2);
}
notifyEngineSetupFailed();
}
@@ -1801,14 +1734,14 @@ void GdbEngine::handlePythonSetup(const GdbResponse &response)
void GdbEngine::showExecutionError(const QString &message)
{
- showMessageBox(QMessageBox::Critical, tr("Execution Error"),
+ AsynchronousMessageBox::critical(tr("Execution Error"),
tr("Cannot continue debugged process:") + QLatin1Char('\n') + message);
}
-void GdbEngine::handleExecuteContinue(const GdbResponse &response)
+void GdbEngine::handleExecuteContinue(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
- if (response.resultClass == GdbResultRunning) {
+ if (response.resultClass == ResultRunning) {
// All is fine. Waiting for a *running.
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
return;
@@ -1822,7 +1755,7 @@ void GdbEngine::handleExecuteContinue(const GdbResponse &response)
flushQueuedCommands();
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
showStatusMessage(tr("Stopped."), 5000);
- reloadStack(true);
+ reloadStack();
} else if (msg.startsWith("Cannot access memory at address")) {
// Happens on single step on ARM prolog and epilogs.
} else if (msg.startsWith("\"finish\" not meaningful in the outermost frame")) {
@@ -1890,7 +1823,7 @@ QString GdbEngine::cleanupFullName(const QString &fileName)
}
cleanFilePath.clear();
- const QString base = QFileInfo(fileName).fileName();
+ const QString base = FileName::fromString(fileName).fileName();
QMap<QString, QString>::const_iterator jt = m_baseNameToFullName.find(base);
while (jt != m_baseNameToFullName.end() && jt.key() == base) {
@@ -1918,10 +1851,10 @@ void GdbEngine::shutdownInferior()
QTC_ASSERT(false, notifyInferiorShutdownFailed());
}
-void GdbEngine::handleInferiorShutdown(const GdbResponse &response)
+void GdbEngine::handleInferiorShutdown(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
notifyInferiorShutdownOk();
return;
}
@@ -1933,7 +1866,7 @@ void GdbEngine::handleInferiorShutdown(const GdbResponse &response)
notifyInferiorShutdownOk();
return;
}
- showMessageBox(QMessageBox::Critical,
+ AsynchronousMessageBox::critical(
tr("Failed to shut down application"),
msgInferiorStopFailed(QString::fromLocal8Bit(ba)));
notifyInferiorShutdownFailed();
@@ -1953,11 +1886,15 @@ void GdbEngine::notifyAdapterShutdownOk()
.arg(lastGoodState()).arg(m_gdbProc->state()));
m_commandsDoneCallback = 0;
switch (m_gdbProc->state()) {
- case QProcess::Running:
+ case QProcess::Running: {
if (startParameters().closeMode == KillAndExitMonitorAtClose)
postCommand("monitor exit");
- postCommand("-gdb-exit", GdbEngine::ExitRequest, CB(handleGdbExit));
+ DebuggerCommand cmd("exitGdb");
+ cmd.flags = GdbEngine::ExitRequest;
+ cmd.callback = CB(handleGdbExit);
+ runCommand(cmd);
break;
+ }
case QProcess::NotRunning:
// Cannot find executable.
notifyEngineShutdownOk();
@@ -1970,9 +1907,9 @@ void GdbEngine::notifyAdapterShutdownOk()
}
}
-void GdbEngine::handleGdbExit(const GdbResponse &response)
+void GdbEngine::handleGdbExit(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultExit) {
+ if (response.resultClass == ResultExit) {
showMessage(_("GDB CLAIMS EXIT; WAITING"));
// Don't set state here, this will be handled in handleGdbFinished()
//notifyEngineShutdownOk();
@@ -1993,7 +1930,7 @@ void GdbEngine::detachDebugger()
postCommand("detach", GdbEngine::ExitRequest, CB(handleDetach));
}
-void GdbEngine::handleDetach(const GdbResponse &response)
+void GdbEngine::handleDetach(const DebuggerResponse &response)
{
Q_UNUSED(response);
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
@@ -2054,6 +1991,7 @@ bool GdbEngine::hasCapability(unsigned cap) const
| WatchComplexExpressionsCapability
| MemoryAddressCapability
| AdditionalQmlStackCapability
+ | NativeMixedCapability
| ResetInferiorCapability))
return true;
@@ -2097,22 +2035,27 @@ void GdbEngine::executeStep()
setTokenBarrier();
notifyInferiorRunRequested();
showStatusMessage(tr("Step requested..."), 5000);
+ if (isNativeMixedActive()) {
+ runCommand("prepareQmlStep");
+ postCommand("-exec-continue", RunRequest, CB(handleExecuteContinue));
+ return;
+ }
if (isReverseDebugging())
postCommand("reverse-step", RunRequest, CB(handleExecuteStep));
else
postCommand("-exec-step", RunRequest, CB(handleExecuteStep));
}
-void GdbEngine::handleExecuteStep(const GdbResponse &response)
+void GdbEngine::handleExecuteStep(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
// Step was finishing too quick, and a '*stopped' messages should
// have preceded it, so just ignore this result.
QTC_CHECK(state() == InferiorStopOk);
return;
}
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
- if (response.resultClass == GdbResultRunning) {
+ if (response.resultClass == ResultRunning) {
// All is fine. Waiting for a *running.
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
return;
@@ -2169,6 +2112,11 @@ void GdbEngine::executeNext()
setTokenBarrier();
notifyInferiorRunRequested();
showStatusMessage(tr("Step next requested..."), 5000);
+ if (isNativeMixedActive()) {
+ runCommand("prepareQmlStep");
+ postCommand("-exec-continue", RunRequest, CB(handleExecuteContinue));
+ return;
+ }
if (isReverseDebugging()) {
postCommand("reverse-next", RunRequest, CB(handleExecuteNext));
} else {
@@ -2179,16 +2127,16 @@ void GdbEngine::executeNext()
}
}
-void GdbEngine::handleExecuteNext(const GdbResponse &response)
+void GdbEngine::handleExecuteNext(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
// Step was finishing too quick, and a '*stopped' messages should
// have preceded it, so just ignore this result.
QTC_CHECK(state() == InferiorStopOk);
return;
}
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
- if (response.resultClass == GdbResultRunning) {
+ if (response.resultClass == ResultRunning) {
// All is fine. Waiting for a *running.
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
return;
@@ -2206,7 +2154,7 @@ void GdbEngine::handleExecuteNext(const GdbResponse &response)
showExecutionError(QString::fromLocal8Bit(msg));
notifyInferiorRunFailed();
} else {
- showMessageBox(QMessageBox::Critical, tr("Execution Error"),
+ AsynchronousMessageBox::critical(tr("Execution Error"),
tr("Cannot continue debugged process:") + QLatin1Char('\n') + QString::fromLocal8Bit(msg));
notifyInferiorIll();
}
@@ -2293,9 +2241,9 @@ void GdbEngine::executeReturn()
postCommand("-exec-finish", RunRequest, CB(handleExecuteReturn));
}
-void GdbEngine::handleExecuteReturn(const GdbResponse &response)
+void GdbEngine::handleExecuteReturn(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
notifyInferiorStopOk();
updateAll();
return;
@@ -2315,14 +2263,12 @@ void GdbEngine::setTokenBarrier()
{
//QTC_ASSERT(m_nonDiscardableCount == 0, /**/);
bool good = true;
- QHashIterator<int, GdbCommand> it(m_cookieForToken);
+ QHashIterator<int, DebuggerCommand> it(m_commandForToken);
while (it.hasNext()) {
it.next();
if (!(it.value().flags & Discardable)) {
- qDebug() << "TOKEN: " << it.key()
- << "CMD:" << it.value().command
- << " FLAGS:" << it.value().flags
- << " CALLBACK:" << it.value().callbackName;
+ qDebug() << "TOKEN: " << it.key() << "CMD:" << it.value().function
+ << " FLAGS:" << it.value().flags;
good = false;
}
}
@@ -2457,14 +2403,12 @@ QString GdbEngine::breakLocation(const QString &file) const
{
QString where = m_fullToShortName.value(file);
if (where.isEmpty())
- return QFileInfo(file).fileName();
+ return FileName::fromString(file).fileName();
return where;
}
-QByteArray GdbEngine::breakpointLocation(BreakpointModelId id)
+QByteArray GdbEngine::breakpointLocation(const BreakpointParameters &data)
{
- BreakHandler *handler = breakHandler();
- const BreakpointParameters &data = handler->breakpointData(id);
QTC_ASSERT(data.type != UnknownBreakpointType, return QByteArray());
// FIXME: Non-GCC-runtime
if (data.type == BreakpointAtThrow)
@@ -2492,12 +2436,8 @@ QByteArray GdbEngine::breakpointLocation(BreakpointModelId id)
+ QByteArray::number(data.lineNumber) + '"';
}
-QByteArray GdbEngine::breakpointLocation2(BreakpointModelId id)
+QByteArray GdbEngine::breakpointLocation2(const BreakpointParameters &data)
{
- BreakHandler *handler = breakHandler();
-
- const BreakpointParameters &data = handler->breakpointData(id);
-
BreakpointPathUsage usage = data.pathUsage;
if (usage == BreakpointPathUsageEngineDefault)
usage = BreakpointUseShortPath;
@@ -2508,12 +2448,10 @@ QByteArray GdbEngine::breakpointLocation2(BreakpointModelId id)
+ QByteArray::number(data.lineNumber);
}
-void GdbEngine::handleWatchInsert(const GdbResponse &response)
+void GdbEngine::handleWatchInsert(const DebuggerResponse &response, Breakpoint bp)
{
- BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- if (response.resultClass == GdbResultDone) {
- BreakHandler *handler = breakHandler();
- BreakpointResponse br = handler->response(id);
+ if (bp && response.resultClass == ResultDone) {
+ BreakpointResponse br = bp.response();
// "Hardware watchpoint 2: *0xbfffed40\n"
QByteArray ba = response.consoleStreamOutput;
GdbMi wpt = response.data["wpt"];
@@ -2524,9 +2462,9 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response)
QByteArray exp = wpt["exp"].data();
if (exp.startsWith('*'))
br.address = exp.mid(1).toULongLong(0, 0);
- handler->setResponse(id, br);
- QTC_CHECK(!handler->needsChange(id));
- handler->notifyBreakpointInsertOk(id);
+ bp.setResponse(br);
+ QTC_CHECK(!bp.needsChange());
+ bp.notifyBreakpointInsertOk();
} else if (ba.startsWith("Hardware watchpoint ")
|| ba.startsWith("Watchpoint ")) {
// Non-Mac: "Hardware watchpoint 2: *0xbfffed40\n"
@@ -2536,27 +2474,25 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response)
br.id = BreakpointResponseId(ba.mid(begin, end - begin));
if (address.startsWith('*'))
br.address = address.mid(1).toULongLong(0, 0);
- handler->setResponse(id, br);
- QTC_CHECK(!handler->needsChange(id));
- handler->notifyBreakpointInsertOk(id);
+ bp.setResponse(br);
+ QTC_CHECK(!bp.needsChange());
+ bp.notifyBreakpointInsertOk();
} else {
showMessage(_("CANNOT PARSE WATCHPOINT FROM " + ba));
}
}
}
-void GdbEngine::handleCatchInsert(const GdbResponse &response)
+void GdbEngine::handleCatchInsert(const DebuggerResponse &response, Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
- BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- if (response.resultClass == GdbResultDone)
- handler->notifyBreakpointInsertOk(id);
+ if (bp && response.resultClass == ResultDone)
+ bp.notifyBreakpointInsertOk();
}
-void GdbEngine::handleBkpt(const GdbMi &bkpt, const BreakpointModelId &id)
+void GdbEngine::handleBkpt(const GdbMi &bkpt, Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
- BreakpointResponse br = handler->response(id);
+ BreakpointResponse br = bp.response();
+ QTC_ASSERT(bp, return);
const QByteArray nr = bkpt["number"].data();
const BreakpointResponseId rid(nr);
QTC_ASSERT(rid.isValid(), return);
@@ -2565,8 +2501,8 @@ void GdbEngine::handleBkpt(const GdbMi &bkpt, const BreakpointModelId &id)
BreakpointResponse sub;
updateResponse(sub, bkpt);
sub.id = rid;
- sub.type = br.type;
- handler->insertSubBreakpoint(id, sub);
+ sub.type = bp.type();
+ bp.insertSubBreakpoint(sub);
return;
}
@@ -2582,33 +2518,31 @@ void GdbEngine::handleBkpt(const GdbMi &bkpt, const BreakpointModelId &id)
updateResponse(sub, loc);
sub.id = subrid;
sub.type = br.type;
- handler->insertSubBreakpoint(id, sub);
+ bp.insertSubBreakpoint(sub);
}
}
// A (the?) primary breakpoint.
updateResponse(br, bkpt);
br.id = rid;
- handler->setResponse(id, br);
+ bp.setResponse(br);
}
-void GdbEngine::handleBreakInsert1(const GdbResponse &response)
+void GdbEngine::handleBreakInsert1(const DebuggerResponse &response, Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
- const BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- if (handler->state(id) == BreakpointRemoveRequested) {
- if (response.resultClass == GdbResultDone) {
+ if (bp.state() == BreakpointRemoveRequested) {
+ if (response.resultClass == ResultDone) {
// This delete was deferred. Act now.
const GdbMi mainbkpt = response.data["bkpt"];
- handler->notifyBreakpointRemoveProceeding(id);
+ bp.notifyBreakpointRemoveProceeding();
QByteArray nr = mainbkpt["number"].data();
postCommand("-break-delete " + nr,
NeedsStop | RebuildBreakpointModel);
- handler->notifyBreakpointRemoveOk(id);
+ bp.notifyBreakpointRemoveOk();
return;
}
}
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
// The result is a list with the first entry marked "bkpt"
// and "unmarked" rest. The "bkpt" one seems to always be
// the "main" entry. Use the "main" entry to retrieve the
@@ -2619,19 +2553,19 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response)
const BreakpointResponseId mainrid(mainnr);
if (!isHiddenBreakpoint(mainrid)) {
foreach (const GdbMi &bkpt, response.data.children())
- handleBkpt(bkpt, id);
- if (handler->needsChange(id)) {
- handler->notifyBreakpointChangeAfterInsertNeeded(id);
- changeBreakpoint(id);
+ handleBkpt(bkpt, bp);
+ if (bp.needsChange()) {
+ bp.notifyBreakpointChangeAfterInsertNeeded();
+ changeBreakpoint(bp);
} else {
- handler->notifyBreakpointInsertOk(id);
+ bp.notifyBreakpointInsertOk();
}
}
} else if (response.data["msg"].data().contains("Unknown option")) {
// Older version of gdb don't know the -a option to set tracepoints
// ^error,msg="mi_cmd_break_insert: Unknown option ``a''"
- const QString fileName = handler->fileName(id);
- const int lineNumber = handler->lineNumber(id);
+ const QString fileName = bp.fileName();
+ const int lineNumber = bp.lineNumber();
QByteArray cmd = "trace "
"\"" + GdbMi::escapeCString(fileName.toLocal8Bit()) + "\":"
+ QByteArray::number(lineNumber);
@@ -2640,18 +2574,17 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response)
// Some versions of gdb like "GNU gdb (GDB) SUSE (6.8.91.20090930-2.4)"
// know how to do pending breakpoints using CLI but not MI. So try
// again with MI.
- QByteArray cmd = "break " + breakpointLocation2(id);
- QVariant vid = QVariant::fromValue(id);
+ QByteArray cmd = "break " + breakpointLocation2(bp.parameters());
postCommand(cmd, NeedsStop | RebuildBreakpointModel,
- CB(handleBreakInsert2), vid);
+ [this, bp](const DebuggerResponse &r) { handleBreakInsert2(r, bp); });
}
}
-void GdbEngine::handleBreakInsert2(const GdbResponse &response)
+void GdbEngine::handleBreakInsert2(const DebuggerResponse &response, Breakpoint bp)
{
- if (response.resultClass == GdbResultDone) {
- BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- breakHandler()->notifyBreakpointInsertOk(id);
+ if (response.resultClass == ResultDone) {
+ QTC_ASSERT(bp, return);
+ bp.notifyBreakpointInsertOk();
} else {
// Note: gdb < 60800 doesn't "do" pending breakpoints.
// Not much we can do about it except implementing the
@@ -2660,57 +2593,57 @@ void GdbEngine::handleBreakInsert2(const GdbResponse &response)
}
}
-void GdbEngine::handleBreakDisable(const GdbResponse &response)
+void GdbEngine::handleBreakDelete(const DebuggerResponse &response, Breakpoint bp)
{
- QTC_CHECK(response.resultClass == GdbResultDone);
- const BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- BreakHandler *handler = breakHandler();
+ if (response.resultClass == ResultDone)
+ bp.notifyBreakpointRemoveOk();
+ else
+ bp.notifyBreakpointRemoveFailed();
+}
+
+void GdbEngine::handleBreakDisable(const DebuggerResponse &response, Breakpoint bp)
+{
+ QTC_CHECK(response.resultClass == ResultDone);
// This should only be the requested state.
- QTC_ASSERT(!handler->isEnabled(id), /* Prevent later recursion */);
- BreakpointResponse br = handler->response(id);
+ QTC_ASSERT(!bp.isEnabled(), /* Prevent later recursion */);
+ BreakpointResponse br = bp.response();
br.enabled = false;
- handler->setResponse(id, br);
- changeBreakpoint(id); // Maybe there's more to do.
+ bp.setResponse(br);
+ changeBreakpoint(bp); // Maybe there's more to do.
}
-void GdbEngine::handleBreakEnable(const GdbResponse &response)
+void GdbEngine::handleBreakEnable(const DebuggerResponse &response, Breakpoint bp)
{
- QTC_CHECK(response.resultClass == GdbResultDone);
- const BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- BreakHandler *handler = breakHandler();
+ QTC_CHECK(response.resultClass == ResultDone);
// This should only be the requested state.
- QTC_ASSERT(handler->isEnabled(id), /* Prevent later recursion */);
- BreakpointResponse br = handler->response(id);
+ QTC_ASSERT(bp.isEnabled(), /* Prevent later recursion */);
+ BreakpointResponse br = bp.response();
br.enabled = true;
- handler->setResponse(id, br);
- changeBreakpoint(id); // Maybe there's more to do.
+ bp.setResponse(br);
+ changeBreakpoint(bp); // Maybe there's more to do.
}
-void GdbEngine::handleBreakThreadSpec(const GdbResponse &response)
+void GdbEngine::handleBreakThreadSpec(const DebuggerResponse &response, Breakpoint bp)
{
- QTC_CHECK(response.resultClass == GdbResultDone);
- const BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- BreakHandler *handler = breakHandler();
- BreakpointResponse br = handler->response(id);
- br.threadSpec = handler->threadSpec(id);
- handler->setResponse(id, br);
- handler->notifyBreakpointNeedsReinsertion(id);
- insertBreakpoint(id);
+ QTC_CHECK(response.resultClass == ResultDone);
+ BreakpointResponse br = bp.response();
+ br.threadSpec = bp.threadSpec();
+ bp.setResponse(br);
+ bp.notifyBreakpointNeedsReinsertion();
+ insertBreakpoint(bp);
}
-void GdbEngine::handleBreakLineNumber(const GdbResponse &response)
+void GdbEngine::handleBreakLineNumber(const DebuggerResponse &response, Breakpoint bp)
{
- QTC_CHECK(response.resultClass == GdbResultDone);
- const BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- BreakHandler *handler = breakHandler();
- BreakpointResponse br = handler->response(id);
- br.lineNumber = handler->lineNumber(id);
- handler->setResponse(id, br);
- handler->notifyBreakpointNeedsReinsertion(id);
- insertBreakpoint(id);
+ QTC_CHECK(response.resultClass == ResultDone);
+ BreakpointResponse br = bp.response();
+ br.lineNumber = bp.lineNumber();
+ bp.setResponse(br);
+ bp.notifyBreakpointNeedsReinsertion();
+ insertBreakpoint(bp);
}
-void GdbEngine::handleBreakIgnore(const GdbResponse &response)
+void GdbEngine::handleBreakIgnore(const DebuggerResponse &response, Breakpoint bp)
{
// gdb 6.8:
// ignore 2 0:
@@ -2722,39 +2655,35 @@ void GdbEngine::handleBreakIgnore(const GdbResponse &response)
// 29^done
//
// gdb 6.3 does not produce any console output
- QTC_CHECK(response.resultClass == GdbResultDone);
+ QTC_CHECK(response.resultClass == ResultDone);
//QString msg = _(response.consoleStreamOutput);
- BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- BreakHandler *handler = breakHandler();
- BreakpointResponse br = handler->response(id);
+ BreakpointResponse br = bp.response();
//if (msg.contains(__("Will stop next time breakpoint")))
// response.ignoreCount = _("0");
//else if (msg.contains(__("Will ignore next")))
// response.ignoreCount = data->ignoreCount;
// FIXME: this assumes it is doing the right thing...
- const BreakpointParameters &parameters = handler->breakpointData(id);
+ const BreakpointParameters &parameters = bp.parameters();
br.ignoreCount = parameters.ignoreCount;
br.command = parameters.command;
- handler->setResponse(id, br);
- changeBreakpoint(id); // Maybe there's more to do.
+ bp.setResponse(br);
+ changeBreakpoint(bp); // Maybe there's more to do.
}
-void GdbEngine::handleBreakCondition(const GdbResponse &response)
+void GdbEngine::handleBreakCondition(const DebuggerResponse &, Breakpoint bp)
{
// Can happen at invalid condition strings.
- //QTC_CHECK(response.resultClass == GdbResultDone)
- const BreakpointModelId id = response.cookie.value<BreakpointModelId>();
- BreakHandler *handler = breakHandler();
+ //QTC_CHECK(response.resultClass == ResultDone)
// We just assume it was successful. Otherwise we had to parse
// the output stream data.
// The following happens on Mac:
// QByteArray msg = response.data.findChild("msg").data();
// if (msg.startsWith("Error parsing breakpoint condition. "
// " Will try again when we hit the breakpoint."))
- BreakpointResponse br = handler->response(id);
- br.condition = handler->condition(id);
- handler->setResponse(id, br);
- changeBreakpoint(id); // Maybe there's more to do.
+ BreakpointResponse br = bp.response();
+ br.condition = bp.condition();
+ bp.setResponse(br);
+ changeBreakpoint(bp); // Maybe there's more to do.
}
bool GdbEngine::stateAcceptsBreakpointChanges() const
@@ -2771,40 +2700,53 @@ bool GdbEngine::stateAcceptsBreakpointChanges() const
}
}
-bool GdbEngine::acceptsBreakpoint(BreakpointModelId id) const
+bool GdbEngine::acceptsBreakpoint(Breakpoint bp) const
{
- return breakHandler()->breakpointData(id).isCppBreakpoint()
- && startParameters().startMode != AttachCore;
+ if (startParameters().startMode == AttachCore)
+ return false;
+ // We handle QML breakpoint unless specifically
+ if (isNativeMixedEnabled() && !(startParameters().languages & QmlLanguage))
+ return true;
+ return bp.parameters().isCppBreakpoint();
}
-void GdbEngine::insertBreakpoint(BreakpointModelId id)
+void GdbEngine::insertBreakpoint(Breakpoint bp)
{
// Set up fallback in case of pending breakpoints which aren't handled
// by the MI interface.
- BreakHandler *handler = breakHandler();
- QTC_CHECK(handler->state(id) == BreakpointInsertRequested);
- handler->notifyBreakpointInsertProceeding(id);
- BreakpointType type = handler->type(id);
- QVariant vid = QVariant::fromValue(id);
+ QTC_CHECK(bp.state() == BreakpointInsertRequested);
+ bp.notifyBreakpointInsertProceeding();
+
+ const BreakpointParameters &data = bp.parameters();
+
+ if (!data.isCppBreakpoint()) {
+ DebuggerCommand cmd("insertQmlBreakpoint");
+ bp.addToCommand(&cmd);
+ runCommand(cmd);
+ bp.notifyBreakpointInsertOk();
+ return;
+ }
+
+ BreakpointType type = bp.type();
if (type == WatchpointAtAddress) {
- postCommand("watch " + addressSpec(handler->address(id)),
+ postCommand("watch " + addressSpec(bp.address()),
NeedsStop | RebuildBreakpointModel | ConsoleCommand,
- CB(handleWatchInsert), vid);
+ [this, bp](const DebuggerResponse &r) { handleWatchInsert(r, bp); });
return;
}
if (type == WatchpointAtExpression) {
- postCommand("watch " + handler->expression(id).toLocal8Bit(),
+ postCommand("watch " + bp.expression().toLocal8Bit(),
NeedsStop | RebuildBreakpointModel | ConsoleCommand,
- CB(handleWatchInsert), vid);
+ [this, bp](const DebuggerResponse &r) { handleWatchInsert(r, bp); });
return;
}
if (type == BreakpointAtFork) {
postCommand("catch fork",
NeedsStop | RebuildBreakpointModel | ConsoleCommand,
- CB(handleCatchInsert), vid);
+ [this, bp](const DebuggerResponse &r) { handleCatchInsert(r, bp); });
postCommand("catch vfork",
NeedsStop | RebuildBreakpointModel | ConsoleCommand,
- CB(handleCatchInsert), vid);
+ [this, bp](const DebuggerResponse &r) { handleCatchInsert(r, bp); });
return;
}
//if (type == BreakpointAtVFork) {
@@ -2815,72 +2757,70 @@ void GdbEngine::insertBreakpoint(BreakpointModelId id)
if (type == BreakpointAtExec) {
postCommand("catch exec",
NeedsStop | RebuildBreakpointModel | ConsoleCommand,
- CB(handleCatchInsert), vid);
+ [this, bp](const DebuggerResponse &r) { handleCatchInsert(r, bp); });
return;
}
if (type == BreakpointAtSysCall) {
postCommand("catch syscall",
NeedsStop | RebuildBreakpointModel | ConsoleCommand,
- CB(handleCatchInsert), vid);
+ [this, bp](const DebuggerResponse &r) { handleCatchInsert(r, bp); });
return;
}
QByteArray cmd;
- if (handler->isTracepoint(id)) {
+ if (bp.isTracepoint()) {
cmd = "-break-insert -a -f ";
} else {
- int spec = handler->threadSpec(id);
+ int spec = bp.threadSpec();
cmd = "-break-insert ";
if (spec >= 0)
cmd += "-p " + QByteArray::number(spec);
cmd += " -f ";
}
- if (handler->isOneShot(id))
+ if (bp.isOneShot())
cmd += "-t ";
- if (!handler->isEnabled(id))
+ if (!bp.isEnabled())
cmd += "-d ";
- if (int ignoreCount = handler->ignoreCount(id))
+ if (int ignoreCount = bp.ignoreCount())
cmd += "-i " + QByteArray::number(ignoreCount) + ' ';
- QByteArray condition = handler->condition(id);
+ QByteArray condition = bp.condition();
if (!condition.isEmpty())
cmd += " -c \"" + condition + "\" ";
- cmd += breakpointLocation(id);
+ cmd += breakpointLocation(bp.parameters());
postCommand(cmd, NeedsStop | RebuildBreakpointModel,
- CB(handleBreakInsert1), vid);
+ [this, bp](const DebuggerResponse &r) { handleBreakInsert1(r, bp); });
}
-void GdbEngine::changeBreakpoint(BreakpointModelId id)
+void GdbEngine::changeBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
- const BreakpointParameters &data = handler->breakpointData(id);
+ const BreakpointParameters &data = bp.parameters();
QTC_ASSERT(data.type != UnknownBreakpointType, return);
- const BreakpointResponse &response = handler->response(id);
+ const BreakpointResponse &response = bp.response();
QTC_ASSERT(response.id.isValid(), return);
const QByteArray bpnr = response.id.toByteArray();
- const BreakpointState state = handler->state(id);
+ const BreakpointState state = bp.state();
if (state == BreakpointChangeRequested)
- handler->notifyBreakpointChangeProceeding(id);
- const BreakpointState state2 = handler->state(id);
+ bp.notifyBreakpointChangeProceeding();
+ const BreakpointState state2 = bp.state();
QTC_ASSERT(state2 == BreakpointChangeProceeding, qDebug() << state2);
- QVariant vid = QVariant::fromValue(id);
if (!response.pending && data.threadSpec != response.threadSpec) {
// The only way to change this seems to be to re-set the bp completely.
postCommand("-break-delete " + bpnr,
NeedsStop | RebuildBreakpointModel,
- CB(handleBreakThreadSpec), vid);
+ [this, bp](const DebuggerResponse &r) { handleBreakThreadSpec(r, bp); });
return;
}
if (!response.pending && data.lineNumber != response.lineNumber) {
// The only way to change this seems to be to re-set the bp completely.
postCommand("-break-delete " + bpnr,
NeedsStop | RebuildBreakpointModel,
- CB(handleBreakLineNumber), vid);
+ [this, bp](const DebuggerResponse &r) { handleBreakLineNumber(r, bp); });
return;
}
if (data.command != response.command) {
@@ -2893,51 +2833,57 @@ void GdbEngine::changeBreakpoint(BreakpointModelId id)
}
}
postCommand(breakCommand, NeedsStop | RebuildBreakpointModel,
- CB(handleBreakIgnore), vid);
+ [this, bp](const DebuggerResponse &r) { handleBreakIgnore(r, bp); });
return;
}
if (!data.conditionsMatch(response.condition)) {
postCommand("condition " + bpnr + ' ' + data.condition,
NeedsStop | RebuildBreakpointModel,
- CB(handleBreakCondition), vid);
+ [this, bp](const DebuggerResponse &r) { handleBreakCondition(r, bp); });
return;
}
if (data.ignoreCount != response.ignoreCount) {
postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount),
NeedsStop | RebuildBreakpointModel,
- CB(handleBreakIgnore), vid);
+ [this, bp](const DebuggerResponse &r) { handleBreakIgnore(r, bp); });
return;
}
if (!data.enabled && response.enabled) {
postCommand("-break-disable " + bpnr,
NeedsStop | RebuildBreakpointModel,
- CB(handleBreakDisable), vid);
+ [this, bp](const DebuggerResponse &r) { handleBreakDisable(r, bp); });
return;
}
if (data.enabled && !response.enabled) {
postCommand("-break-enable " + bpnr,
NeedsStop | RebuildBreakpointModel,
- CB(handleBreakEnable), vid);
+ [this, bp](const DebuggerResponse &r) { handleBreakEnable(r, bp); });
return;
}
- handler->notifyBreakpointChangeOk(id);
+ bp.notifyBreakpointChangeOk();
}
-void GdbEngine::removeBreakpoint(BreakpointModelId id)
+void GdbEngine::removeBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
- QTC_CHECK(handler->state(id) == BreakpointRemoveRequested);
- BreakpointResponse br = handler->response(id);
+ QTC_CHECK(bp.state() == BreakpointRemoveRequested);
+ BreakpointResponse br = bp.response();
+
+ const BreakpointParameters &data = bp.parameters();
+ if (!data.isCppBreakpoint()) {
+ DebuggerCommand cmd("removeQmlBreakpoint");
+ bp.addToCommand(&cmd);
+ runCommand(cmd);
+ bp.notifyBreakpointRemoveOk();
+ return;
+ }
+
if (br.id.isValid()) {
// We already have a fully inserted breakpoint.
- handler->notifyBreakpointRemoveProceeding(id);
- showMessage(_("DELETING BP %1 IN %2").arg(br.id.toString())
- .arg(handler->fileName(id)));
+ bp.notifyBreakpointRemoveProceeding();
+ showMessage(_("DELETING BP %1 IN %2").arg(br.id.toString()).arg(bp.fileName()));
postCommand("-break-delete " + br.id.toByteArray(),
- NeedsStop | RebuildBreakpointModel);
- // Pretend it succeeds without waiting for response. Feels better.
- // FIXME: Really?
- handler->notifyBreakpointRemoveOk(id);
+ NeedsStop | RebuildBreakpointModel,
+ [this, bp](const DebuggerResponse &r) { handleBreakDelete(r, bp); });
} else {
// Breakpoint was scheduled to be inserted, but we haven't had
// an answer so far. Postpone activity by doing nothing.
@@ -2956,7 +2902,7 @@ void GdbEngine::loadSymbols(const QString &modulePath)
// FIXME: gdb does not understand quoted names here (tested with 6.8)
postCommand("sharedlibrary " + dotEscape(modulePath.toLocal8Bit()));
reloadModulesInternal();
- reloadStack(true);
+ reloadStack();
updateLocals();
}
@@ -2964,7 +2910,7 @@ void GdbEngine::loadAllSymbols()
{
postCommand("sharedlibrary .*");
reloadModulesInternal();
- reloadStack(true);
+ reloadStack();
updateLocals();
}
@@ -2987,30 +2933,15 @@ void GdbEngine::loadSymbolsForStack()
}
if (needUpdate) {
//reloadModulesInternal();
- reloadStack(true);
+ reloadStack();
updateLocals();
}
}
-void GdbEngine::requestModuleSymbols(const QString &modulePath)
+static void handleShowModuleSymbols(const DebuggerResponse &response,
+ const QString &modulePath, const QString &fileName)
{
- QTemporaryFile tf(QDir::tempPath() + _("/gdbsymbols"));
- if (!tf.open())
- return;
- QString fileName = tf.fileName();
- tf.close();
- postCommand("maint print msymbols \"" + fileName.toLocal8Bit()
- + "\" " + modulePath.toLocal8Bit(),
- NeedsStop, CB(handleShowModuleSymbols),
- QVariant(modulePath + QLatin1Char('@') + fileName));
-}
-
-void GdbEngine::handleShowModuleSymbols(const GdbResponse &response)
-{
- const QString cookie = response.cookie.toString();
- const QString modulePath = cookie.section(QLatin1Char('@'), 0, 0);
- const QString fileName = cookie.section(QLatin1Char('@'), 1, 1);
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
Symbols symbols;
QFile file(fileName);
file.open(QIODevice::ReadOnly);
@@ -3061,24 +2992,38 @@ void GdbEngine::handleShowModuleSymbols(const GdbResponse &response)
file.remove();
Internal::showModuleSymbols(modulePath, symbols);
} else {
- showMessageBox(QMessageBox::Critical, tr("Cannot Read Symbols"),
- tr("Cannot read symbols for module \"%1\".").arg(fileName));
+ AsynchronousMessageBox::critical(GdbEngine::tr("Cannot Read Symbols"),
+ GdbEngine::tr("Cannot read symbols for module \"%1\".").arg(fileName));
}
}
+void GdbEngine::requestModuleSymbols(const QString &modulePath)
+{
+ QTemporaryFile tf(QDir::tempPath() + _("/gdbsymbols"));
+ if (!tf.open())
+ return;
+ QString fileName = tf.fileName();
+ tf.close();
+ postCommand("maint print msymbols \"" + fileName.toLocal8Bit()
+ + "\" " + modulePath.toLocal8Bit(), NeedsStop,
+ [modulePath, fileName](const DebuggerResponse &r) {
+ handleShowModuleSymbols(r, modulePath, fileName); });
+}
+
void GdbEngine::requestModuleSections(const QString &moduleName)
{
// There seems to be no way to get the symbols from a single .so.
- postCommand("maint info section ALLOBJ",
- NeedsStop, CB(handleShowModuleSections), moduleName);
+ postCommand("maint info section ALLOBJ", NeedsStop,
+ [this, moduleName](const DebuggerResponse &r) {
+ handleShowModuleSections(r, moduleName); });
}
-void GdbEngine::handleShowModuleSections(const GdbResponse &response)
+void GdbEngine::handleShowModuleSections(const DebuggerResponse &response,
+ const QString &moduleName)
{
// ~" Object file: /usr/lib/i386-linux-gnu/libffi.so.6\n"
// ~" 0xb44a6114->0xb44a6138 at 0x00000114: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS\n"
- if (response.resultClass == GdbResultDone) {
- const QString moduleName = response.cookie.toString();
+ if (response.resultClass == ResultDone) {
const QStringList lines = QString::fromLocal8Bit(response.consoleStreamOutput).split(QLatin1Char('\n'));
const QString prefix = QLatin1String(" Object file: ");
const QString needle = prefix + moduleName;
@@ -3127,9 +3072,9 @@ static QString nameFromPath(const QString &path)
return QFileInfo(path).baseName();
}
-void GdbEngine::handleModulesList(const GdbResponse &response)
+void GdbEngine::handleModulesList(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
ModulesHandler *handler = modulesHandler();
Module module;
// That's console-based output, likely Linux or Windows,
@@ -3227,11 +3172,11 @@ void GdbEngine::selectThread(ThreadId threadId)
CB(handleStackSelectThread));
}
-void GdbEngine::handleStackSelectThread(const GdbResponse &)
+void GdbEngine::handleStackSelectThread(const DebuggerResponse &)
{
QTC_CHECK(state() == InferiorUnrunnable || state() == InferiorStopOk);
showStatusMessage(tr("Retrieving data for stack view..."), 3000);
- reloadStack(true); // Will reload registers.
+ reloadStack(); // Will reload registers.
updateLocals();
}
@@ -3239,8 +3184,10 @@ void GdbEngine::reloadFullStack()
{
PENDING_DEBUG("RELOAD FULL STACK");
resetLocation();
- postCommand("-stack-list-frames", Discardable, CB(handleStackListFrames),
- QVariant::fromValue<StackCookie>(StackCookie(true, true)));
+ DebuggerCommand cmd = stackCommand(-1);
+ cmd.flags = Discardable;
+ cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, true); };
+ runCommand(cmd);
}
void GdbEngine::loadAdditionalQmlStack()
@@ -3277,7 +3224,7 @@ static QString msgCannotLoadQmlStack(const QString &why)
return _("Unable to load QML stack: ") + why;
}
-void GdbEngine::handleQmlStackFrameArguments(const GdbResponse &response)
+void GdbEngine::handleQmlStackFrameArguments(const DebuggerResponse &response)
{
if (!response.data.isValid()) {
showMessage(msgCannotLoadQmlStack(_("No stack obtained.")), LogError);
@@ -3292,10 +3239,10 @@ void GdbEngine::handleQmlStackFrameArguments(const GdbResponse &response)
QByteArray command = "-data-evaluate-expression \"qt_v4StackTrace((QV4::ExecutionContext *)0x";
command += QByteArray::number(contextAddress, 16);
command += ")\"";
- postCommand(command, CB(handleQmlStackTrace));
+ postCommand(command, NoFlags, CB(handleQmlStackTrace));
}
-void GdbEngine::handleQmlStackTrace(const GdbResponse &response)
+void GdbEngine::handleQmlStackTrace(const DebuggerResponse &response)
{
if (!response.data.isValid()) {
showMessage(msgCannotLoadQmlStack(_("No result obtained.")), LogError);
@@ -3327,15 +3274,21 @@ void GdbEngine::handleQmlStackTrace(const GdbResponse &response)
stackHandler()->prependFrames(qmlFrames);
}
-void GdbEngine::reloadStack(bool forceGotoLocation)
+DebuggerCommand GdbEngine::stackCommand(int depth)
+{
+ DebuggerCommand cmd("stackListFrames");
+ cmd.arg("limit", depth);
+ cmd.arg("options", isNativeMixedActive() ? "nativemixed" : "");
+ return cmd;
+}
+
+void GdbEngine::reloadStack()
{
PENDING_DEBUG("RELOAD STACK");
- QByteArray cmd = "-stack-list-frames";
- int stackDepth = action(MaximalStackDepth)->value().toInt();
- if (stackDepth)
- cmd += " 0 " + QByteArray::number(stackDepth);
- postCommand(cmd, Discardable, CB(handleStackListFrames),
- QVariant::fromValue<StackCookie>(StackCookie(false, forceGotoLocation)));
+ DebuggerCommand cmd = stackCommand(action(MaximalStackDepth)->value().toInt());
+ cmd.flags = Discardable;
+ cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, false); };
+ runCommand(cmd);
}
StackFrame GdbEngine::parseStackFrame(const GdbMi &frameMi, int level)
@@ -3352,15 +3305,24 @@ StackFrame GdbEngine::parseStackFrame(const GdbMi &frameMi, int level)
frame.from = _(frameMi["from"].data());
frame.line = frameMi["line"].toInt();
frame.address = frameMi["addr"].toAddress();
- frame.usable = QFileInfo(frame.file).isReadable();
- if (frameMi["language"].data() == "js")
+ GdbMi usable = frameMi["usable"];
+ if (usable.isValid())
+ frame.usable = usable.data().toInt();
+ else
+ frame.usable = QFileInfo(frame.file).isReadable();
+ if (frameMi["language"].data() == "js"
+ || frame.file.endsWith(QLatin1String(".js"))
+ || frame.file.endsWith(QLatin1String(".qml"))) {
+ frame.file = QFile::decodeName(frameMi["file"].data());
frame.language = QmlLanguage;
+ frame.fixQmlFrame(startParameters());
+ }
return frame;
}
-void GdbEngine::handleStackListFrames(const GdbResponse &response)
+void GdbEngine::handleStackListFrames(const DebuggerResponse &response, bool isFull)
{
- if (response.resultClass != GdbResultDone) {
+ if (response.resultClass != ResultDone) {
// That always happens on symbian gdb with
// ^error,data={msg="Previous frame identical to this frame (corrupt stack?)"
// logStreamOutput: "Previous frame identical to this frame (corrupt stack?)\n"
@@ -3369,10 +3331,12 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response)
return;
}
- StackCookie cookie = response.cookie.value<StackCookie>();
QList<StackFrame> stackFrames;
- GdbMi stack = response.data["stack"];
+ GdbMi stack = response.data["stack"]; // C++
+ if (!stack.isValid() || stack.childCount() == 0) // Mixed.
+ stack.fromStringMultiple(response.consoleStreamOutput);
+
if (!stack.isValid()) {
qDebug() << "FIXME: stack:" << stack.toString();
return;
@@ -3391,8 +3355,7 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response)
targetFrame = i;
}
- bool canExpand = !cookie.isFull
- && (n >= action(MaximalStackDepth)->value().toInt());
+ bool canExpand = !isFull && (n >= action(MaximalStackDepth)->value().toInt());
action(ExpandStack)->setEnabled(canExpand);
stackHandler()->setFrames(stackFrames, canExpand);
@@ -3429,34 +3392,28 @@ void GdbEngine::activateFrame(int frameIndex)
}
QTC_ASSERT(frameIndex < handler->stackSize(), return);
-
- if (handler->frameAt(frameIndex).language == QmlLanguage) {
- gotoLocation(handler->frameAt(frameIndex));
- return;
- }
- // Assuming the command always succeeds this saves a roundtrip.
- // Otherwise the lines below would need to get triggered
- // after a response to this -stack-select-frame here.
handler->setCurrentIndex(frameIndex);
- QByteArray cmd = "-stack-select-frame";
- //if (!m_currentThread.isEmpty())
- // cmd += " --thread " + m_currentThread;
- cmd += ' ';
- cmd += QByteArray::number(frameIndex);
- postCommand(cmd, Discardable, CB(handleStackSelectFrame));
gotoLocation(stackHandler()->currentFrame());
+
+ if (handler->frameAt(frameIndex).language != QmlLanguage) {
+ // Assuming the command always succeeds this saves a roundtrip.
+ // Otherwise the lines below would need to get triggered
+ // after a response to this -stack-select-frame here.
+ QByteArray cmd = "-stack-select-frame";
+ //if (!m_currentThread.isEmpty())
+ // cmd += " --thread " + m_currentThread;
+ cmd += ' ';
+ cmd += QByteArray::number(frameIndex);
+ postCommand(cmd, Discardable);
+ }
+
updateLocals();
reloadRegisters();
}
-void GdbEngine::handleStackSelectFrame(const GdbResponse &response)
+void GdbEngine::handleThreadInfo(const DebuggerResponse &response)
{
- Q_UNUSED(response);
-}
-
-void GdbEngine::handleThreadInfo(const GdbResponse &response)
-{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
ThreadsHandler *handler = threadsHandler();
handler->updateThreads(response.data);
// This is necessary as the current thread might not be in the list.
@@ -3471,7 +3428,7 @@ void GdbEngine::handleThreadInfo(const GdbResponse &response)
action(MaximalStackDepth)->value().toByteArray(),
Discardable, CB(handleThreadNames));
}
- reloadStack(false); // Will trigger register reload.
+ reloadStack(); // Will trigger register reload.
} else {
// Fall back for older versions: Try to get at least a list
// of running threads.
@@ -3479,7 +3436,7 @@ void GdbEngine::handleThreadInfo(const GdbResponse &response)
}
}
-void GdbEngine::handleThreadListIds(const GdbResponse &response)
+void GdbEngine::handleThreadListIds(const DebuggerResponse &response)
{
// "72^done,{thread-ids={thread-id="2",thread-id="1"},number-of-threads="2"}
// In gdb 7.1+ additionally: current-thread-id="1"
@@ -3490,12 +3447,12 @@ void GdbEngine::handleThreadListIds(const GdbResponse &response)
thread.id = ThreadId(items.at(index).toInt());
handler->updateThread(thread);
}
- reloadStack(false); // Will trigger register reload.
+ reloadStack(); // Will trigger register reload.
}
-void GdbEngine::handleThreadNames(const GdbResponse &response)
+void GdbEngine::handleThreadNames(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
ThreadsHandler *handler = threadsHandler();
GdbMi names;
names.fromString(response.consoleStreamOutput);
@@ -3525,20 +3482,20 @@ void GdbEngine::createSnapshot()
fileName = tf.fileName();
tf.close();
// This must not be quoted, it doesn't work otherwise.
- postCommand("gcore " + fileName.toLocal8Bit(),
- NeedsStop|ConsoleCommand, CB(handleMakeSnapshot), fileName);
+ postCommand("gcore " + fileName.toLocal8Bit(), NeedsStop|ConsoleCommand,
+ [this, fileName](const DebuggerResponse &r) { handleMakeSnapshot(r, fileName); });
} else {
- showMessageBox(QMessageBox::Critical, tr("Snapshot Creation Error"),
+ AsynchronousMessageBox::critical(tr("Snapshot Creation Error"),
tr("Cannot create snapshot file."));
}
}
-void GdbEngine::handleMakeSnapshot(const GdbResponse &response)
+void GdbEngine::handleMakeSnapshot(const DebuggerResponse &response, const QString &coreFile)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
DebuggerStartParameters sp = startParameters();
sp.startMode = AttachCore;
- sp.coreFile = response.cookie.toString();
+ sp.coreFile = coreFile;
//snapshot.setDate(QDateTime::currentDateTime());
StackFrames frames = stackHandler()->frames();
QString function = _("<unknown>");
@@ -3551,7 +3508,7 @@ void GdbEngine::handleMakeSnapshot(const GdbResponse &response)
DebuggerRunControlFactory::createAndScheduleRun(sp);
} else {
QByteArray msg = response.data["msg"].data();
- showMessageBox(QMessageBox::Critical, tr("Snapshot Creation Error"),
+ AsynchronousMessageBox::critical(tr("Snapshot Creation Error"),
tr("Cannot create snapshot:") + QLatin1Char('\n') + QString::fromLocal8Bit(msg));
}
}
@@ -3570,69 +3527,144 @@ void GdbEngine::reloadRegisters()
if (state() != InferiorStopOk && state() != InferiorUnrunnable)
return;
- if (!m_registerNamesListed) {
- postCommand("-data-list-register-names", CB(handleRegisterListNames));
- m_registerNamesListed = true;
+
+ if (true) {
+ if (!m_registerNamesListed) {
+ postCommand("-data-list-register-names", NoFlags, CB(handleRegisterListNames));
+ m_registerNamesListed = true;
+ }
+ // Can cause i386-linux-nat.c:571: internal-error: Got request
+ // for bad register number 41.\nA problem internal to GDB has been detected.
+ postCommand("-data-list-register-values r",
+ Discardable, CB(handleRegisterListValues));
+ } else {
+ postCommand("maintenance print cooked-registers", NoFlags, CB(handleMaintPrintRegisters));
}
+}
- postCommand("-data-list-register-values r",
- Discardable, CB(handleRegisterListValues));
+static QByteArray readWord(const QByteArray &ba, int *pos)
+{
+ const int n = ba.size();
+ while (*pos < n && ba.at(*pos) == ' ')
+ ++*pos;
+ const int start = *pos;
+ while (*pos < n && ba.at(*pos) != ' ' && ba.at(*pos) != '\n')
+ ++*pos;
+ return ba.mid(start, *pos - start);
}
-void GdbEngine::setRegisterValue(int nr, const QString &value)
+void GdbEngine::handleMaintPrintRegisters(const DebuggerResponse &response)
{
- Register reg = registerHandler()->registers().at(nr);
- postCommand("set $" + reg.name + "=" + value.toLatin1());
+ if (response.resultClass != ResultDone)
+ return;
+
+ const QByteArray &ba = response.consoleStreamOutput;
+ RegisterHandler *handler = registerHandler();
+ //0 1 2 3 4 5 6
+ //0123456789012345678901234567890123456789012345678901234567890
+ // Name Nr Rel Offset Size Type Raw value
+ // rax 0 0 0 8 int64_t 0x0000000000000000
+ // rip 16 16 128 8 *1 0x0000000000400dc9
+ // eflags 17 17 136 4 i386_eflags 0x00000246
+ // cs 18 18 140 4 int32_t 0x00000033
+ // xmm15 55 55 516 16 vec128 0x00000000000000000000000000000000
+ // mxcsr 56 56 532 4 i386_mxcsr 0x00001fa0
+ // ''
+ // st6 30 30 224 10 _i387_ext 0x00000000000000000000
+ // st7 31 31 234 10 _i387_ext 0x00000000000000000000
+ // fctrl 32 32 244 4 int 0x0000037f
+
+ const int n = ba.size();
+ int pos = 0;
+ while (true) {
+ // Skip first line, and until '\n' after each line finished.
+ while (pos < n && ba.at(pos) != '\n')
+ ++pos;
+ if (pos >= n)
+ break;
+ ++pos; // skip \n
+ Register reg;
+ reg.name = readWord(ba, &pos);
+ if (reg.name == "''" || reg.name == "*1:" || reg.name.isEmpty())
+ continue;
+ readWord(ba, &pos); // Nr
+ readWord(ba, &pos); // Rel
+ readWord(ba, &pos); // Offset
+ reg.size = readWord(ba, &pos).toInt();
+ reg.reportedType = readWord(ba, &pos);
+ reg.value = readWord(ba, &pos);
+ handler->updateRegister(reg);
+ }
+ handler->commitUpdates();
+}
+void GdbEngine::setRegisterValue(const QByteArray &name, const QString &value)
+{
+ postCommand("set $" + name + "=" + value.toLatin1());
reloadRegisters();
}
-void GdbEngine::handleRegisterListNames(const GdbResponse &response)
+void GdbEngine::handleRegisterListNames(const DebuggerResponse &response)
{
- if (response.resultClass != GdbResultDone) {
+ if (response.resultClass != ResultDone) {
m_registerNamesListed = false;
return;
}
- Registers registers;
- int gdbRegisterNumber = 0, internalIndex = 0;
-
- // This both handles explicitly having space for all the registers and
- // initializes all indices to 0, giving missing registers a sane default
- // in the event of something wacky.
GdbMi names = response.data["register-names"];
- m_registerNumbers.resize(names.childCount());
+ m_registerNames.clear();
+ int gdbRegisterNumber = 0;
foreach (const GdbMi &item, names.children()) {
- // Since we throw away missing registers to eliminate empty rows
- // we need to maintain a mapping of GDB register numbers to their
- // respective indices in the register list.
- if (!item.data().isEmpty()) {
- m_registerNumbers[gdbRegisterNumber] = internalIndex++;
- registers.append(Register(item.data()));
- }
- gdbRegisterNumber++;
+ if (!item.data().isEmpty())
+ m_registerNames[gdbRegisterNumber] = item.data();
+ ++gdbRegisterNumber;
}
-
- registerHandler()->setRegisters(registers);
}
-void GdbEngine::handleRegisterListValues(const GdbResponse &response)
+void GdbEngine::handleRegisterListValues(const DebuggerResponse &response)
{
- if (response.resultClass != GdbResultDone)
+ if (response.resultClass != ResultDone)
return;
- Registers registers = registerHandler()->registers();
- const int registerCount = registers.size();
- const int gdbRegisterCount = m_registerNumbers.size();
-
+ RegisterHandler *handler = registerHandler();
// 24^done,register-values=[{number="0",value="0xf423f"},...]
const GdbMi values = response.data["register-values"];
- QTC_ASSERT(registerCount == values.children().size(), return);
foreach (const GdbMi &item, values.children()) {
+ Register reg;
const int number = item["number"].toInt();
- if (number >= 0 && number < gdbRegisterCount)
- registers[m_registerNumbers[number]].value = item["value"].data();
+ reg.name = m_registerNames[number];
+ QByteArray data = item["value"].data();
+ if (data.startsWith("0x")) {
+ reg.value = data;
+ } else {
+ // This is what GDB considers machine readable output:
+ // value="{v4_float = {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ // v2_double = {0x0000000000000000, 0x0000000000000000},
+ // v16_int8 = {0x00 <repeats 16 times>},
+ // v8_int16 = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+ // v4_int32 = {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ // v2_int64 = {0x0000000000000000, 0x0000000000000000},
+ // uint128 = <error reading variable>}"}
+ // Try to make sense of it using the int32 chunks:
+ QByteArray result = "0x";
+ const int pos1 = data.indexOf("_int32");
+ const int pos2 = data.indexOf('{', pos1) + 1;
+ const int pos3 = data.indexOf('}', pos2);
+ QByteArray inner = data.mid(pos2, pos3 - pos2);
+ QList<QByteArray> list = inner.split(',');
+ for (int i = list.size(); --i >= 0; ) {
+ QByteArray chunk = list.at(i);
+ if (chunk.startsWith(' '))
+ chunk.remove(0, 1);
+ if (chunk.startsWith("0x"))
+ chunk.remove(0, 2);
+ QTC_ASSERT(chunk.size() == 8, continue);
+ result.append(chunk);
+ }
+ reg.value = result;
+ }
+ handler->updateRegister(reg);
}
- registerHandler()->setAndMarkRegisters(registers);
+ handler->commitUpdates();
}
@@ -3650,8 +3682,6 @@ bool GdbEngine::setToolTipExpression(TextEditor::TextEditorWidget *editor,
UpdateParameters params;
params.tryPartial = true;
- params.tooltipOnly = true;
- params.tooltipExpression = context.expression;
params.varList = context.iname;
updateLocalsPython(params);
return true;
@@ -3699,9 +3729,7 @@ void GdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &f
// << (m_pendingBreakpointRequests == 0);
UpdateParameters params;
- params.tooltipOnly = data.iname.startsWith("tooltip");
- params.tryPartial = flags.tryIncremental
- && m_pendingBreakpointRequests == 0;
+ params.tryPartial = flags.tryIncremental && m_pendingBreakpointRequests == 0;
params.varList = data.iname;
updateLocalsPython(params);
@@ -3722,7 +3750,7 @@ void GdbEngine::rebuildWatchModel()
DebuggerToolTipManager::updateEngine(this);
}
-void GdbEngine::handleVarAssign(const GdbResponse &)
+void GdbEngine::handleVarAssign(const DebuggerResponse &)
{
// Everything might have changed, force re-evaluation.
setTokenBarrier();
@@ -3757,17 +3785,13 @@ void GdbEngine::insertData(const WatchData &data)
void GdbEngine::assignValueInDebugger(const WatchData *data,
const QString &expression, const QVariant &value)
{
- if (!isIntOrFloatType(data->type)) {
- QByteArray cmd = "bbedit "
- + data->type.toHex() + ','
- + expression.toUtf8().toHex() + ','
- + value.toString().toUtf8().toHex();
- postCommand(cmd, Discardable, CB(handleVarAssign));
- } else {
- postCommand("set variable (" + expression.toLatin1() + ")="
- + GdbMi::escapeCString(value.toString().toLatin1()),
- Discardable, CB(handleVarAssign));
- }
+ DebuggerCommand cmd("assignValue");
+ cmd.arg("type", data->type.toHex());
+ cmd.arg("expr", expression.toLatin1().toHex());
+ cmd.arg("value", value.toString().toLatin1().toHex());
+ cmd.arg("simpleType", isIntOrFloatType(data->type));
+ cmd.callback = CB(handleVarAssign);
+ runCommand(cmd);
}
void GdbEngine::watchPoint(const QPoint &pnt)
@@ -3779,9 +3803,9 @@ void GdbEngine::watchPoint(const QPoint &pnt)
NeedsStop, CB(handleWatchPoint));
}
-void GdbEngine::handleWatchPoint(const GdbResponse &response)
+void GdbEngine::handleWatchPoint(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
// "$5 = (void *) 0xbfa7ebfc\n"
const QByteArray ba = parsePlainConsoleStream(response);
const int pos0x = ba.indexOf("0x");
@@ -3832,10 +3856,10 @@ void GdbEngine::changeMemory(MemoryAgent *agent, QObject *token,
ac.token = token;
ac.base = addr;
ac.length = data.size();
- postCommand(cmd, NeedsStop, CB(handleChangeMemory), QVariant::fromValue(ac));
+ postCommand(cmd, NeedsStop, CB(handleChangeMemory));
}
-void GdbEngine::handleChangeMemory(const GdbResponse &response)
+void GdbEngine::handleChangeMemory(const DebuggerResponse &response)
{
Q_UNUSED(response);
}
@@ -3856,21 +3880,20 @@ void GdbEngine::fetchMemory(MemoryAgent *agent, QObject *token, quint64 addr,
void GdbEngine::fetchMemoryHelper(const MemoryAgentCookie &ac)
{
postCommand("-data-read-memory 0x" + QByteArray::number(ac.base + ac.offset, 16) + " x 1 1 "
- + QByteArray::number(ac.length),
- NeedsStop, CB(handleFetchMemory), QVariant::fromValue(ac));
+ + QByteArray::number(ac.length), NeedsStop,
+ [this, ac](const DebuggerResponse &r) { handleFetchMemory(r, ac); });
}
-void GdbEngine::handleFetchMemory(const GdbResponse &response)
+void GdbEngine::handleFetchMemory(const DebuggerResponse &response, MemoryAgentCookie ac)
{
// ^done,addr="0x08910c88",nr-bytes="16",total-bytes="16",
// next-row="0x08910c98",prev-row="0x08910c78",next-page="0x08910c98",
// prev-page="0x08910c78",memory=[{addr="0x08910c88",
// data=["1","0","0","0","5","0","0","0","0","0","0","0","0","0","0","0"]}]
- MemoryAgentCookie ac = response.cookie.value<MemoryAgentCookie>();
--*ac.pendingRequests;
showMessage(QString::fromLatin1("PENDING: %1").arg(*ac.pendingRequests));
QTC_ASSERT(ac.agent, return);
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
GdbMi memory = response.data["memory"];
QTC_ASSERT(memory.children().size() <= 1, return);
if (memory.children().isEmpty())
@@ -3946,25 +3969,34 @@ static inline QByteArray disassemblerCommand(const Location &location, bool mixe
return command;
}
-void GdbEngine::fetchDisassemblerByCliPointMixed(const DisassemblerAgentCookie &ac0)
+void GdbEngine::fetchDisassemblerByCliPointMixed(const DisassemblerAgentCookie &ac)
{
- DisassemblerAgentCookie ac = ac0;
QTC_ASSERT(ac.agent, return);
postCommand(disassemblerCommand(ac.agent->location(), true), Discardable|ConsoleCommand,
- CB(handleFetchDisassemblerByCliPointMixed),
- QVariant::fromValue(ac));
+ [this, ac](const DebuggerResponse &response) {
+ if (response.resultClass == ResultDone)
+ if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
+ return;
+ // 'point, plain' can take far too long.
+ // Skip this feature and immediately fall back to the 'range' version:
+ fetchDisassemblerByCliRangeMixed(ac);
+ });
}
-void GdbEngine::fetchDisassemblerByCliRangeMixed(const DisassemblerAgentCookie &ac0)
+void GdbEngine::fetchDisassemblerByCliRangeMixed(const DisassemblerAgentCookie &ac)
{
- DisassemblerAgentCookie ac = ac0;
QTC_ASSERT(ac.agent, return);
const quint64 address = ac.agent->address();
QByteArray start = QByteArray::number(address - 20, 16);
QByteArray end = QByteArray::number(address + 100, 16);
QByteArray cmd = "disassemble /rm 0x" + start + ",0x" + end;
postCommand(cmd, Discardable|ConsoleCommand,
- CB(handleFetchDisassemblerByCliRangeMixed), QVariant::fromValue(ac));
+ [this, ac](const DebuggerResponse &response) {
+ if (response.resultClass == ResultDone)
+ if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
+ return;
+ fetchDisassemblerByCliRangePlain(ac);
+ });
}
@@ -3977,7 +4009,18 @@ void GdbEngine::fetchDisassemblerByCliRangePlain(const DisassemblerAgentCookie &
QByteArray end = QByteArray::number(address + 100, 16);
QByteArray cmd = "disassemble /r 0x" + start + ",0x" + end;
postCommand(cmd, Discardable,
- CB(handleFetchDisassemblerByCliRangePlain), QVariant::fromValue(ac));
+ [this, ac](const DebuggerResponse &response) {
+ if (response.resultClass == ResultDone)
+ if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
+ return;
+ // Finally, give up.
+ //76^error,msg="No function contains program counter for selected..."
+ //76^error,msg="No function contains specified address."
+ //>568^error,msg="Line number 0 out of range;
+ QByteArray msg = response.data["msg"].data();
+ showStatusMessage(tr("Disassembler failed: %1")
+ .arg(QString::fromLocal8Bit(msg)), 5000);
+ });
}
struct LineData
@@ -3990,6 +4033,7 @@ struct LineData
bool GdbEngine::handleCliDisassemblerResult(const QByteArray &output, DisassemblerAgent *agent)
{
+ QTC_ASSERT(agent, return true);
// First line is something like
// "Dump of assembler code from 0xb7ff598f to 0xb7ff5a07:"
DisassemblerLines dlines;
@@ -4033,50 +4077,6 @@ bool GdbEngine::handleCliDisassemblerResult(const QByteArray &output, Disassembl
return false;
}
-void GdbEngine::handleFetchDisassemblerByCliPointMixed(const GdbResponse &response)
-{
- DisassemblerAgentCookie ac = response.cookie.value<DisassemblerAgentCookie>();
- QTC_ASSERT(ac.agent, return);
-
- if (response.resultClass == GdbResultDone)
- if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
- return;
-
- // 'point, plain' can take far too long.
- // Skip this feature and immediately fall back to the 'range' version:
- fetchDisassemblerByCliRangeMixed(ac);
-}
-
-void GdbEngine::handleFetchDisassemblerByCliRangeMixed(const GdbResponse &response)
-{
- DisassemblerAgentCookie ac = response.cookie.value<DisassemblerAgentCookie>();
- QTC_ASSERT(ac.agent, return);
-
- if (response.resultClass == GdbResultDone)
- if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
- return;
-
- fetchDisassemblerByCliRangePlain(ac);
-}
-
-void GdbEngine::handleFetchDisassemblerByCliRangePlain(const GdbResponse &response)
-{
- DisassemblerAgentCookie ac = response.cookie.value<DisassemblerAgentCookie>();
- QTC_ASSERT(ac.agent, return);
-
- if (response.resultClass == GdbResultDone)
- if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
- return;
-
- // Finally, give up.
- //76^error,msg="No function contains program counter for selected..."
- //76^error,msg="No function contains specified address."
- //>568^error,msg="Line number 0 out of range;
- QByteArray msg = response.data["msg"].data();
- showStatusMessage(tr("Disassembler failed: %1")
- .arg(QString::fromLocal8Bit(msg)), 5000);
-}
-
// Binary/configuration check logic.
static QString gdbBinary(const DebuggerStartParameters &sp)
@@ -4129,14 +4129,10 @@ void GdbEngine::startGdb(const QStringList &args)
gdbArgs << _("-n");
gdbArgs += args;
- connect(m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
- SLOT(handleGdbError(QProcess::ProcessError)));
- connect(m_gdbProc, SIGNAL(finished(int,QProcess::ExitStatus)),
- SLOT(handleGdbFinished(int,QProcess::ExitStatus)));
- connect(m_gdbProc, SIGNAL(readyReadStandardOutput()),
- SLOT(readGdbStandardOutput()));
- connect(m_gdbProc, SIGNAL(readyReadStandardError()),
- SLOT(readGdbStandardError()));
+ connect(m_gdbProc, &GdbProcess::error, this, &GdbEngine::handleGdbError);
+ connect(m_gdbProc, &GdbProcess::finished, this, &GdbEngine::handleGdbFinished);
+ connect(m_gdbProc, &GdbProcess::readyReadStandardOutput, this, &GdbEngine::readGdbStandardOutput);
+ connect(m_gdbProc, &GdbProcess::readyReadStandardError, this, &GdbEngine::readGdbStandardError);
showMessage(_("STARTING ") + m_gdb + _(" ") + gdbArgs.join(QLatin1Char(' ')));
m_gdbProc->start(m_gdb, gdbArgs);
@@ -4149,9 +4145,9 @@ void GdbEngine::startGdb(const QStringList &args)
}
showMessage(_("GDB STARTED, INITIALIZING IT"));
- postCommand("show version", CB(handleShowVersion));
+ postCommand("show version", NoFlags, CB(handleShowVersion));
//postCommand("-list-features", CB(handleListFeatures));
- postCommand("show debug-file-directory", CB(handleDebugInfoLocation));
+ postCommand("show debug-file-directory", NoFlags, CB(handleDebugInfoLocation));
//postCommand("-enable-timings");
//postCommand("set print static-members off"); // Seemingly doesn't work.
@@ -4277,6 +4273,9 @@ void GdbEngine::startGdb(const QStringList &args)
const QByteArray dumperSourcePath =
ICore::resourcePath().toLocal8Bit() + "/debugger/";
+ if (terminal()->isUsable())
+ postCommand("set inferior-tty " + terminal()->slaveDevice());
+
const QFileInfo gdbBinaryFile(m_gdb);
const QByteArray uninstalledData = gdbBinaryFile.absolutePath().toLocal8Bit()
+ "/data-directory/python";
@@ -4284,14 +4283,26 @@ void GdbEngine::startGdb(const QStringList &args)
const GdbCommandFlags flags = ConsoleCommand | Immediate;
postCommand("python sys.path.insert(1, '" + dumperSourcePath + "')", flags);
postCommand("python sys.path.append('" + uninstalledData + "')", flags);
- postCommand("python from gdbbridge import *", flags, CB(handlePythonSetup));
+ postCommand("python from gdbbridge import *", flags);
+
+ const QString path = stringSetting(ExtraDumperFile);
+ if (!path.isEmpty()) {
+ DebuggerCommand cmd("addDumperModule");
+ cmd.arg("path", path.toUtf8());
+ runCommand(cmd);
+ }
+
+ const QString commands = stringSetting(ExtraDumperCommands);
+ if (!commands.isEmpty())
+ postCommand(commands.toLocal8Bit(), flags);
+
+ runCommand(DebuggerCommand("setupDumper", flags, CB(handlePythonSetup)));
}
void GdbEngine::handleGdbStartFailed()
{
}
-
void GdbEngine::loadInitScript()
{
const QString script = startParameters().overrideStartScript;
@@ -4299,7 +4310,7 @@ void GdbEngine::loadInitScript()
if (QFileInfo(script).isReadable()) {
postCommand("source " + script.toLocal8Bit());
} else {
- showMessageBox(QMessageBox::Warning,
+ AsynchronousMessageBox::warning(
tr("Cannot find debugger initialization script"),
tr("The debugger settings point to a script file at \"%1\" "
"which is not accessible. If a script file is not needed, "
@@ -4315,7 +4326,8 @@ void GdbEngine::loadInitScript()
void GdbEngine::reloadDebuggingHelpers()
{
- postCommand("bbsetup");
+ runCommand("reloadDumper");
+ reloadLocals();
}
void GdbEngine::handleGdbError(QProcess::ProcessError error)
@@ -4336,7 +4348,7 @@ void GdbEngine::handleGdbError(QProcess::ProcessError error)
default:
//m_gdbProc->kill();
//notifyEngineIll();
- showMessageBox(QMessageBox::Critical, tr("GDB I/O Error"), msg);
+ AsynchronousMessageBox::critical(tr("GDB I/O Error"), msg);
break;
}
}
@@ -4364,7 +4376,7 @@ void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type)
const QString msg = type == QProcess::CrashExit ?
tr("The gdb process terminated.") :
tr("The gdb process terminated unexpectedly (code %1)").arg(code);
- showMessageBox(QMessageBox::Critical, tr("Unexpected GDB Exit"), msg);
+ AsynchronousMessageBox::critical(tr("Unexpected GDB Exit"), msg);
break;
}
}
@@ -4394,10 +4406,9 @@ void GdbEngine::resetInferior()
if (state() == InferiorStopOk) {
postCommand(command, ConsoleCommand|Immediate);
} else {
- GdbCommand gdbCmd;
- gdbCmd.command = command;
- gdbCmd.flags = ConsoleCommand;
- m_commandsToRunOnTemporaryBreak.append(gdbCmd);
+ DebuggerCommand cmd(command);
+ cmd.flags = ConsoleCommand;
+ m_commandsToRunOnTemporaryBreak.append(cmd);
}
}
}
@@ -4457,7 +4468,7 @@ void GdbEngine::handleInferiorPrepared()
attemptBreakpointSynchronization();
}
- if (m_cookieForToken.isEmpty()) {
+ if (m_commandForToken.isEmpty()) {
finishInferiorSetup();
} else {
QTC_CHECK(m_commandsDoneCallback == 0);
@@ -4479,19 +4490,19 @@ void GdbEngine::finishInferiorSetup()
postCommand("-break-insert -f '" + qtNamespace() + "QMessageLogger::warning'");
}
if (boolSetting(BreakOnFatal)) {
- postCommand("-break-insert -f '" + qtNamespace() + "qFatal'",
- CB(handleBreakOnQFatal), QVariant(false));
- postCommand("-break-insert -f '" + qtNamespace() + "QMessageLogger::fatal'",
- CB(handleBreakOnQFatal), QVariant(true));
+ postCommand("-break-insert -f '" + qtNamespace() + "qFatal'", NoFlags,
+ [this](const DebuggerResponse &r) { handleBreakOnQFatal(r, false); });
+ postCommand("-break-insert -f '" + qtNamespace() + "QMessageLogger::fatal'", NoFlags,
+ [this](const DebuggerResponse &r) { handleBreakOnQFatal(r, true); });
} else {
notifyInferiorSetupOk();
}
}
}
-void GdbEngine::handleDebugInfoLocation(const GdbResponse &response)
+void GdbEngine::handleDebugInfoLocation(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
const QByteArray debugInfoLocation = startParameters().debugInfoLocation.toLocal8Bit();
if (QFile::exists(QString::fromLocal8Bit(debugInfoLocation))) {
const QByteArray curDebugInfoLocations = response.consoleStreamOutput.split('"').value(1);
@@ -4506,9 +4517,9 @@ void GdbEngine::handleDebugInfoLocation(const GdbResponse &response)
}
}
-void GdbEngine::handleBreakOnQFatal(const GdbResponse &response)
+void GdbEngine::handleBreakOnQFatal(const DebuggerResponse &response, bool continueSetup)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
GdbMi bkpt = response.data["bkpt"];
GdbMi number = bkpt["number"];
BreakpointResponseId rid(number.data());
@@ -4519,7 +4530,7 @@ void GdbEngine::handleBreakOnQFatal(const GdbResponse &response)
}
// Continue setup.
- if (response.cookie.toBool())
+ if (continueSetup)
notifyInferiorSetupOk();
}
@@ -4531,7 +4542,7 @@ void GdbEngine::notifyInferiorSetupFailed(const QString &msg)
return; // Adapter crashed meanwhile, so this notification is meaningless.
}
showMessage(_("INFERIOR START FAILED"));
- showMessageBox(QMessageBox::Critical, tr("Failed to start application"), msg);
+ AsynchronousMessageBox::critical(tr("Failed to start application"), msg);
DebuggerEngine::notifyInferiorSetupFailed();
}
@@ -4553,7 +4564,7 @@ void GdbEngine::handleAdapterCrashed(const QString &msg)
m_gdbProc->kill();
if (!msg.isEmpty())
- showMessageBox(QMessageBox::Critical, tr("Adapter crashed"), msg);
+ AsynchronousMessageBox::critical(tr("Adapter crashed"), msg);
}
void GdbEngine::createFullBacktrace()
@@ -4562,9 +4573,9 @@ void GdbEngine::createFullBacktrace()
NeedsStop|ConsoleCommand, CB(handleCreateFullBacktrace));
}
-void GdbEngine::handleCreateFullBacktrace(const GdbResponse &response)
+void GdbEngine::handleCreateFullBacktrace(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
Internal::openTextEditor(_("Backtrace $"),
_(response.consoleStreamOutput + response.logStreamOutput));
}
@@ -4573,65 +4584,17 @@ void GdbEngine::handleCreateFullBacktrace(const GdbResponse &response)
void GdbEngine::resetCommandQueue()
{
m_commandTimer.stop();
- if (!m_cookieForToken.isEmpty()) {
+ if (!m_commandForToken.isEmpty()) {
QString msg;
QTextStream ts(&msg);
ts << "RESETING COMMAND QUEUE. LEFT OVER TOKENS: ";
- foreach (const GdbCommand &cookie, m_cookieForToken)
- ts << "CMD:" << cookie.command << cookie.callbackName;
- m_cookieForToken.clear();
+ foreach (const DebuggerCommand &cmd, m_commandForToken)
+ ts << "CMD:" << cmd.function;
+ m_commandForToken.clear();
showMessage(msg);
}
}
-bool GdbEngine::setupQmlStep(bool on)
-{
- QTC_ASSERT(isSlaveEngine(), return false);
- m_qmlBreakpointResponseId1 = BreakpointResponseId();
- m_qmlBreakpointResponseId2 = BreakpointResponseId();
- //qDebug() << "CLEAR: " << m_qmlBreakpointNumbers;
- postCommand("tbreak '" + qtNamespace() + "QScript::FunctionWrapper::proxyCall'\n"
- "commands\n"
- "set $d=(void*)((FunctionWrapper*)callee)->data->function\n"
- "tbreak *$d\nprintf \"QMLBP:%d \\n\",$bpnum\ncontinue\nend",
- NeedsStop, CB(handleSetQmlStepBreakpoint));
- m_preparedForQmlBreak = on;
- return true;
-}
-
-void GdbEngine::handleSetQmlStepBreakpoint(const GdbResponse &response)
-{
- //QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
- // logStreamOutput: "tbreak 'myns::QScript::FunctionWrapper::proxyCall'\n"
- // consoleStreamOutput: "Temporary breakpoint 1 at 0xf166e7:
- // file bridge/qscriptfunction.cpp, line 75.\n"}
- QByteArray ba = parsePlainConsoleStream(response);
- const int pos2 = ba.indexOf(" at 0x");
- const int pos1 = ba.lastIndexOf(" ", pos2 - 1) + 1;
- QByteArray mid = ba.mid(pos1, pos2 - pos1);
- m_qmlBreakpointResponseId1 = BreakpointResponseId(mid);
- //qDebug() << "SET: " << m_qmlBreakpointResponseId1;
- }
- QTC_ASSERT(masterEngine(), return);
- masterEngine()->readyToExecuteQmlStep();
-}
-
-bool GdbEngine::isQmlStepBreakpoint(const BreakpointResponseId &id) const
-{
- return isQmlStepBreakpoint1(id) || isQmlStepBreakpoint2(id);
-}
-
-bool GdbEngine::isQmlStepBreakpoint1(const BreakpointResponseId &id) const
-{
- return id.isValid() && m_qmlBreakpointResponseId1 == id;
-}
-
-bool GdbEngine::isQmlStepBreakpoint2(const BreakpointResponseId &id) const
-{
- return id.isValid() && m_qmlBreakpointResponseId2 == id;
-}
-
bool GdbEngine::isQFatalBreakpoint(const BreakpointResponseId &id) const
{
return id.isValid() && m_qFatalBreakpointResponseId == id;
@@ -4639,7 +4602,7 @@ bool GdbEngine::isQFatalBreakpoint(const BreakpointResponseId &id) const
bool GdbEngine::isHiddenBreakpoint(const BreakpointResponseId &id) const
{
- return isQFatalBreakpoint(id) || isQmlStepBreakpoint(id);
+ return isQFatalBreakpoint(id);
}
bool GdbEngine::usesExecInterrupt() const
@@ -4673,8 +4636,8 @@ bool GdbEngine::attemptQuickStart() const
// Don't try if there are breakpoints we might be able to handle.
BreakHandler *handler = breakHandler();
- foreach (BreakpointModelId id, handler->unclaimedBreakpointIds()) {
- if (acceptsBreakpoint(id))
+ foreach (Breakpoint bp, handler->unclaimedBreakpoints()) {
+ if (acceptsBreakpoint(bp))
return false;
}
@@ -4761,7 +4724,7 @@ QByteArray GdbEngine::dotEscape(QByteArray str)
void GdbEngine::debugLastCommand()
{
- postCommand(m_lastDebuggableCommand, Discardable);
+ runCommand(m_lastDebuggableCommand);
}
//
@@ -4791,79 +4754,67 @@ void addGdbOptionPages(QList<IOptionsPage *> *opts)
opts->push_back(new GdbOptionsPage2());
}
-
void GdbEngine::updateLocalsPython(const UpdateParameters &params)
{
//m_pendingWatchRequests = 0;
m_pendingBreakpointRequests = 0;
m_processedNames.clear();
- WatchHandler *handler = watchHandler();
- QByteArray expanded = "expanded:" + handler->expansionRequests() + ' ';
- expanded += "typeformats:" + handler->typeFormatRequests() + ' ';
- expanded += "formats:" + handler->individualFormatRequests();
+ DebuggerCommand cmd("showData");
+ watchHandler()->appendFormatRequests(&cmd);
- QByteArray cutOff = " stringcutoff:"
- + action(MaximalStringLength)->value().toByteArray()
- + " displaystringlimit:"
- + action(DisplayStringLimit)->value().toByteArray();
+ cmd.arg("stringcutoff", action(MaximalStringLength)->value().toByteArray());
+ cmd.arg("displaystringlimit", action(DisplayStringLimit)->value().toByteArray());
// Re-create tooltip items that are not filters on existing local variables in
// the tooltip model.
- QByteArray watchers;
+ cmd.beginList("watchers");
DebuggerToolTipContexts toolTips = DebuggerToolTipManager::pendingTooltips(this);
foreach (const DebuggerToolTipContext &p, toolTips) {
- if (!watchers.isEmpty())
- watchers += "##";
- watchers += p.expression.toLatin1();
- watchers += '#';
- watchers += p.iname;
+ cmd.beginGroup();
+ cmd.arg("iname", p.iname);
+ cmd.arg("exp", p.expression.toLatin1().toHex());
+ cmd.endGroup();
}
- QHash<QByteArray, int> watcherNames = handler->watcherNames();
- QHashIterator<QByteArray, int> it(watcherNames);
+ QHashIterator<QByteArray, int> it(WatchHandler::watcherNames());
while (it.hasNext()) {
it.next();
- if (!watchers.isEmpty())
- watchers += "##";
- watchers += it.key() + "#watch." + QByteArray::number(it.value());
+ cmd.beginGroup();
+ cmd.arg("iname", "watch." + QByteArray::number(it.value()));
+ cmd.arg("exp", it.key().toHex());
+ cmd.endGroup();
}
+ cmd.endList();
const static bool alwaysVerbose = !qgetenv("QTC_DEBUGGER_PYTHON_VERBOSE").isEmpty();
- QByteArray options;
- if (alwaysVerbose)
- options += "pe,";
- if (boolSetting(UseDebuggingHelpers))
- options += "fancy,";
- if (boolSetting(AutoDerefPointers))
- options += "autoderef,";
- if (boolSetting(UseDynamicType))
- options += "dyntype,";
- if (options.isEmpty())
- options += "defaults,";
- if (params.tryPartial)
- options += "partial,";
- if (params.tooltipOnly)
- options += "tooltiponly,";
- options.chop(1);
-
- QByteArray resultVar;
- if (!m_resultVarName.isEmpty())
- resultVar = "resultvarname:" + m_resultVarName + ' ';
-
- m_lastDebuggableCommand =
- "bb options:pe," + options + " vars:" + params.varList + ' '
- + expanded + " watchers:" + watchers.toHex() + cutOff;
-
- postCommand("bb options:" + options + " vars:" + params.varList + ' '
- + resultVar + expanded + " watchers:" + watchers.toHex() + cutOff,
- Discardable, CB(handleStackFramePython), QVariant(params.tryPartial));
-}
-
-void GdbEngine::handleStackFramePython(const GdbResponse &response)
-{
- if (response.resultClass == GdbResultDone) {
- const bool partial = response.cookie.toBool();
+
+ cmd.arg("passExceptions", alwaysVerbose);
+ cmd.arg("fancy", boolSetting(UseDebuggingHelpers));
+ cmd.arg("autoderef", boolSetting(AutoDerefPointers));
+ cmd.arg("dyntype", boolSetting(UseDynamicType));
+ cmd.arg("nativemixed", isNativeMixedActive());
+ cmd.arg("partial", params.tryPartial);
+
+ if (isNativeMixedActive()) {
+ StackFrame frame = stackHandler()->currentFrame();
+ if (frame.language == QmlLanguage)
+ cmd.arg("qmlcontext", "0x" + QByteArray::number(frame.address, 16));
+ }
+
+ cmd.arg("resultvarname", m_resultVarName);
+ cmd.arg("vars", params.varList);
+ cmd.flags = Discardable;
+ cmd.callback = [this, params](const DebuggerResponse &r) { handleStackFramePython(r, params.tryPartial); };
+ runCommand(cmd);
+
+ cmd.arg("passExceptions", true);
+ m_lastDebuggableCommand = cmd;
+}
+
+void GdbEngine::handleStackFramePython(const DebuggerResponse &response, bool partial)
+{
+ if (response.resultClass == ResultDone) {
QByteArray out = response.consoleStreamOutput;
while (out.endsWith(' ') || out.endsWith('\n'))
out.chop(1);
@@ -4884,27 +4835,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
}
WatchHandler *handler = watchHandler();
- QList<WatchData> list;
-
- if (!partial) {
- list.append(*handler->findData("local"));
- list.append(*handler->findData("watch"));
- list.append(*handler->findData("return"));
- }
- foreach (const GdbMi &child, data.children()) {
- WatchData dummy;
- dummy.iname = child["iname"].data();
- GdbMi wname = child["wname"];
- if (wname.isValid()) {
- // Happens (only) for watched expressions.
- dummy.name = QString::fromUtf8(QByteArray::fromHex(wname.data()));
- dummy.exp = dummy.name.toUtf8();
- } else {
- dummy.name = _(child["name"].data());
- }
- parseWatchData(handler->expandedINames(), dummy, child, &list);
- }
const GdbMi typeInfo = all["typeinfo"];
if (typeInfo.type() == GdbMi::List) {
foreach (const GdbMi &s, typeInfo.children()) {
@@ -4915,13 +4846,24 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
TypeInfo(size.data().toUInt()));
}
}
- for (int i = 0; i != list.size(); ++i) {
- const TypeInfo ti = m_typeInfoCache.value(list.at(i).type);
+
+ QSet<QByteArray> toDelete;
+ if (!partial) {
+ foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(2))
+ toDelete.insert(item->d.iname);
+ }
+
+ foreach (const GdbMi &child, data.children()) {
+ WatchItem *item = new WatchItem(child);
+ const TypeInfo ti = m_typeInfoCache.value(item->d.type);
if (ti.size)
- list[i].size = ti.size;
+ item->d.size = ti.size;
+
+ handler->insertItem(item);
+ toDelete.remove(item->d.iname);
}
- handler->insertData(list);
+ handler->purgeOutdatedItems(toDelete);
//PENDING_DEBUG("AFTER handleStackFrame()");
// FIXME: This should only be used when updateLocals() was
@@ -4960,10 +4902,7 @@ QString GdbEngine::msgPtraceError(DebuggerStartMode sm)
"For more details, see /etc/sysctl.d/10-ptrace.conf\n");
}
-
} // namespace Internal
} // namespace Debugger
-Q_DECLARE_METATYPE(Debugger::Internal::MemoryAgentCookie)
-Q_DECLARE_METATYPE(Debugger::Internal::DisassemblerAgentCookie)
Q_DECLARE_METATYPE(Debugger::Internal::GdbMi)
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index f443ed68e3..eb48e45dfc 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -33,6 +33,7 @@
#include <debugger/debuggerengine.h>
+#include <debugger/breakhandler.h>
#include <debugger/watchhandler.h>
#include <debugger/watchutils.h>
#include <debugger/debuggertooltipmanager.h>
@@ -52,15 +53,17 @@ namespace Internal {
class GdbProcess;
class DebugInfoTask;
class DebugInfoTaskHandler;
-class GdbResponse;
+class DebuggerResponse;
class GdbMi;
class MemoryAgentCookie;
+class BreakpointParameters;
+class BreakpointResponse;
class WatchData;
class DisassemblerAgentCookie;
class DisassemblerLines;
-class GdbEngine : public Debugger::DebuggerEngine
+class GdbEngine : public DebuggerEngine
{
Q_OBJECT
@@ -97,8 +100,8 @@ private: ////////// General State //////////
protected: ////////// Gdb Process Management //////////
void startGdb(const QStringList &args = QStringList());
- void handleInferiorShutdown(const GdbResponse &response);
- void handleGdbExit(const GdbResponse &response);
+ void handleInferiorShutdown(const DebuggerResponse &response);
+ void handleGdbExit(const DebuggerResponse &response);
void loadInitScript();
@@ -113,7 +116,7 @@ protected: ////////// Gdb Process Management //////////
// This notifies the base of a successful inferior setup.
void finishInferiorSetup();
- void handleDebugInfoLocation(const GdbResponse &response);
+ void handleDebugInfoLocation(const DebuggerResponse &response);
// The adapter is still running just fine, but it failed to acquire a debuggee.
void notifyInferiorSetupFailed(const QString &msg);
@@ -126,12 +129,13 @@ protected: ////////// Gdb Process Management //////////
void handleAdapterCrashed(const QString &msg);
private slots:
+ friend class GdbPlainEngine;
void handleInterruptDeviceInferior(const QString &error);
void handleGdbFinished(int, QProcess::ExitStatus status);
void handleGdbError(QProcess::ProcessError error);
+ void readDebugeeOutput(const QByteArray &data);
void readGdbStandardOutput();
void readGdbStandardError();
- void readDebugeeOutput(const QByteArray &data);
private:
QTextCodec *m_outputCodec;
@@ -155,9 +159,9 @@ private: ////////// Gdb Command Management //////////
Discardable = 2,
// We can live without receiving an answer.
NonCriticalResponse = 8,
- // Callback expects GdbResultRunning instead of GdbResultDone.
+ // Callback expects ResultRunning instead of ResultDone.
RunRequest = 16,
- // Callback expects GdbResultExit instead of GdbResultDone.
+ // Callback expects ResultExit instead of ResultDone.
ExitRequest = 32,
// Auto-set inferior shutdown related states.
LosesChild = 64,
@@ -170,40 +174,17 @@ private: ////////// Gdb Command Management //////////
};
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
- protected:
- typedef void (GdbEngine::*GdbCommandCallback)(const GdbResponse &response);
-
- struct GdbCommand
- {
- GdbCommand()
- : flags(0), callback(0), callbackName(0)
- {}
-
- int flags;
- GdbCommandCallback callback;
- const char *callbackName;
- QByteArray command;
- QVariant cookie;
- QTime postTime;
- };
-
// Type and cookie are sender-internal data, opaque for the "event
// queue". resultNeeded == true increments m_pendingResults on
// send and decrements on receipt, effectively preventing
// watch model updates before everything is finished.
- void flushCommand(const GdbCommand &cmd);
+ void flushCommand(const DebuggerCommand &cmd);
protected:
+ void runCommand(const DebuggerCommand &command);
void postCommand(const QByteArray &command,
- GdbCommandFlags flags,
- GdbCommandCallback callback = 0,
- const char *callbackName = 0,
- const QVariant &cookie = QVariant());
- void postCommand(const QByteArray &command,
- GdbCommandCallback callback = 0,
- const char *callbackName = 0,
- const QVariant &cookie = QVariant());
+ int flags = NoFlags,
+ DebuggerCommand::Callback callback = DebuggerCommand::Callback());
private:
- void postCommandHelper(const GdbCommand &cmd);
void flushQueuedCommands();
Q_SLOT void commandTimeout();
void setTokenBarrier();
@@ -211,7 +192,7 @@ private:
// Sets up an "unexpected result" for the following commeand.
void scheduleTestResponse(int testCase, const QByteArray &response);
- QHash<int, GdbCommand> m_cookieForToken;
+ QHash<int, DebuggerCommand> m_commandForToken;
int commandTimeoutTime() const;
QTimer m_commandTimer;
@@ -230,16 +211,14 @@ private:
// This function is called after all previous responses have been received.
CommandsDoneCallback m_commandsDoneCallback;
- QList<GdbCommand> m_commandsToRunOnTemporaryBreak;
+ QList<DebuggerCommand> m_commandsToRunOnTemporaryBreak;
private: ////////// Gdb Output, State & Capability Handling //////////
protected:
Q_SLOT void handleResponse(const QByteArray &buff);
void handleStopResponse(const GdbMi &data);
- void handleResultRecord(GdbResponse *response);
- void handleStop1(const GdbResponse &response);
+ void handleResultRecord(DebuggerResponse *response);
void handleStop1(const GdbMi &data);
- void handleStop2(const GdbResponse &response);
void handleStop2(const GdbMi &data);
Q_SLOT void handleStop2();
StackFrame parseStackFrame(const GdbMi &mi, int level);
@@ -248,9 +227,9 @@ protected:
bool isSynchronous() const { return true; }
// Gdb initialization sequence
- void handleShowVersion(const GdbResponse &response);
- void handleListFeatures(const GdbResponse &response);
- void handlePythonSetup(const GdbResponse &response);
+ void handleShowVersion(const DebuggerResponse &response);
+ void handleListFeatures(const DebuggerResponse &response);
+ void handlePythonSetup(const DebuggerResponse &response);
int m_gdbVersion; // 7.6.1 is 70601
bool m_isQnxGdb;
@@ -259,10 +238,10 @@ private: ////////// Inferior Management //////////
// This should be always the last call in a function.
bool stateAcceptsBreakpointChanges() const;
- bool acceptsBreakpoint(BreakpointModelId id) const;
- void insertBreakpoint(BreakpointModelId id);
- void removeBreakpoint(BreakpointModelId id);
- void changeBreakpoint(BreakpointModelId id);
+ bool acceptsBreakpoint(Breakpoint bp) const;
+ void insertBreakpoint(Breakpoint bp);
+ void removeBreakpoint(Breakpoint bp);
+ void changeBreakpoint(Breakpoint bp);
void executeStep();
void executeStepOut();
@@ -283,15 +262,15 @@ private: ////////// Inferior Management //////////
void executeJumpToLine(const ContextData &data);
void executeReturn();
- void handleExecuteContinue(const GdbResponse &response);
- void handleExecuteStep(const GdbResponse &response);
- void handleExecuteNext(const GdbResponse &response);
- void handleExecuteReturn(const GdbResponse &response);
- void handleExecuteJumpToLine(const GdbResponse &response);
- void handleExecuteRunToLine(const GdbResponse &response);
+ void handleExecuteContinue(const DebuggerResponse &response);
+ void handleExecuteStep(const DebuggerResponse &response);
+ void handleExecuteNext(const DebuggerResponse &response);
+ void handleExecuteReturn(const DebuggerResponse &response);
+ void handleExecuteJumpToLine(const DebuggerResponse &response);
+ void handleExecuteRunToLine(const DebuggerResponse &response);
void maybeHandleInferiorPidChanged(const QString &pid);
- void handleInfoProc(const GdbResponse &response);
+ void handleInfoProc(const DebuggerResponse &response);
QString msgPtraceError(DebuggerStartMode sm);
private: ////////// View & Data Stuff //////////
@@ -303,21 +282,21 @@ private: ////////// View & Data Stuff //////////
// Breakpoint specific stuff
//
void handleBreakModifications(const GdbMi &bkpts);
- void handleBreakIgnore(const GdbResponse &response);
- void handleBreakDisable(const GdbResponse &response);
- void handleBreakEnable(const GdbResponse &response);
- void handleBreakInsert1(const GdbResponse &response);
- void handleBreakInsert2(const GdbResponse &response);
- void handleTraceInsert2(const GdbResponse &response);
- void handleBreakCondition(const GdbResponse &response);
- void handleBreakThreadSpec(const GdbResponse &response);
- void handleBreakLineNumber(const GdbResponse &response);
- void handleWatchInsert(const GdbResponse &response);
- void handleCatchInsert(const GdbResponse &response);
- void handleBkpt(const GdbMi &bkpt, const BreakpointModelId &id);
+ void handleBreakIgnore(const DebuggerResponse &response, Breakpoint bp);
+ void handleBreakDisable(const DebuggerResponse &response, Breakpoint bp);
+ void handleBreakEnable(const DebuggerResponse &response, Breakpoint bp);
+ void handleBreakInsert1(const DebuggerResponse &response, Breakpoint bp);
+ void handleBreakInsert2(const DebuggerResponse &response, Breakpoint bp);
+ void handleBreakDelete(const DebuggerResponse &response, Breakpoint bp);
+ void handleBreakCondition(const DebuggerResponse &response, Breakpoint bp);
+ void handleBreakThreadSpec(const DebuggerResponse &response, Breakpoint bp);
+ void handleBreakLineNumber(const DebuggerResponse &response, Breakpoint bp);
+ void handleWatchInsert(const DebuggerResponse &response, Breakpoint bp);
+ void handleCatchInsert(const DebuggerResponse &response, Breakpoint bp);
+ void handleBkpt(const GdbMi &bkpt, Breakpoint bp);
void updateResponse(BreakpointResponse &response, const GdbMi &bkpt);
- QByteArray breakpointLocation(BreakpointModelId id); // For gdb/MI.
- QByteArray breakpointLocation2(BreakpointModelId id); // For gdb/CLI fallback.
+ QByteArray breakpointLocation(const BreakpointParameters &data); // For gdb/MI.
+ QByteArray breakpointLocation2(const BreakpointParameters &data); // For gdb/CLI fallback.
QString breakLocation(const QString &file) const;
//
@@ -333,24 +312,24 @@ private: ////////// View & Data Stuff //////////
void examineModules();
void reloadModulesInternal();
- void handleModulesList(const GdbResponse &response);
- void handleShowModuleSymbols(const GdbResponse &response);
- void handleShowModuleSections(const GdbResponse &response);
+ void handleModulesList(const DebuggerResponse &response);
+ void handleShowModuleSections(const DebuggerResponse &response, const QString &moduleName);
//
// Snapshot specific stuff
//
virtual void createSnapshot();
- void handleMakeSnapshot(const GdbResponse &response);
+ void handleMakeSnapshot(const DebuggerResponse &response, const QString &coreFile);
//
// Register specific stuff
//
Q_SLOT void reloadRegisters();
- void setRegisterValue(int nr, const QString &value);
- void handleRegisterListNames(const GdbResponse &response);
- void handleRegisterListValues(const GdbResponse &response);
- QVector<int> m_registerNumbers; // Map GDB register numbers to indices
+ void setRegisterValue(const QByteArray &name, const QString &value);
+ void handleRegisterListNames(const DebuggerResponse &response);
+ void handleRegisterListValues(const DebuggerResponse &response);
+ void handleMaintPrintRegisters(const DebuggerResponse &response);
+ QHash<int, QByteArray> m_registerNames; // Map GDB register numbers to indices
//
// Disassembler specific stuff
@@ -360,19 +339,16 @@ private: ////////// View & Data Stuff //////////
void fetchDisassemblerByCliPointMixed(const DisassemblerAgentCookie &ac);
void fetchDisassemblerByCliRangeMixed(const DisassemblerAgentCookie &ac);
void fetchDisassemblerByCliRangePlain(const DisassemblerAgentCookie &ac);
- void handleFetchDisassemblerByCliPointMixed(const GdbResponse &response);
- void handleFetchDisassemblerByCliRangeMixed(const GdbResponse &response);
- void handleFetchDisassemblerByCliRangePlain(const GdbResponse &response);
bool handleCliDisassemblerResult(const QByteArray &response, DisassemblerAgent *agent);
- void handleBreakOnQFatal(const GdbResponse &response);
+ void handleBreakOnQFatal(const DebuggerResponse &response, bool continueSetup);
//
// Source file specific stuff
//
void reloadSourceFiles();
void reloadSourceFilesInternal();
- void handleQuerySources(const GdbResponse &response);
+ void handleQuerySources(const DebuggerResponse &response);
QString fullName(const QString &fileName);
QString cleanupFullName(const QString &fileName);
@@ -389,17 +365,17 @@ private: ////////// View & Data Stuff //////////
//
protected:
void updateAll();
- void handleStackListFrames(const GdbResponse &response);
- void handleStackSelectThread(const GdbResponse &response);
- void handleStackSelectFrame(const GdbResponse &response);
- void handleThreadListIds(const GdbResponse &response);
- void handleThreadInfo(const GdbResponse &response);
- void handleThreadNames(const GdbResponse &response);
- Q_SLOT void reloadStack(bool forceGotoLocation);
+ void handleStackListFrames(const DebuggerResponse &response, bool isFull);
+ void handleStackSelectThread(const DebuggerResponse &response);
+ void handleThreadListIds(const DebuggerResponse &response);
+ void handleThreadInfo(const DebuggerResponse &response);
+ void handleThreadNames(const DebuggerResponse &response);
+ DebuggerCommand stackCommand(int depth);
+ Q_SLOT void reloadStack();
Q_SLOT virtual void reloadFullStack();
virtual void loadAdditionalQmlStack();
- void handleQmlStackFrameArguments(const GdbResponse &response);
- void handleQmlStackTrace(const GdbResponse &response);
+ void handleQmlStackFrameArguments(const DebuggerResponse &response);
+ void handleQmlStackTrace(const DebuggerResponse &response);
int currentFrame() const;
QList<GdbMi> m_currentFunctionArgs;
@@ -415,13 +391,13 @@ protected:
virtual void fetchMemory(MemoryAgent *agent, QObject *token,
quint64 addr, quint64 length);
void fetchMemoryHelper(const MemoryAgentCookie &cookie);
- void handleChangeMemory(const GdbResponse &response);
+ void handleChangeMemory(const DebuggerResponse &response);
virtual void changeMemory(MemoryAgent *agent, QObject *token,
quint64 addr, const QByteArray &data);
- void handleFetchMemory(const GdbResponse &response);
+ void handleFetchMemory(const DebuggerResponse &response, MemoryAgentCookie ac);
virtual void watchPoint(const QPoint &);
- void handleWatchPoint(const GdbResponse &response);
+ void handleWatchPoint(const DebuggerResponse &response);
void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
void rebuildWatchModel();
@@ -429,17 +405,17 @@ protected:
void insertData(const WatchData &data);
- void handleVarAssign(const GdbResponse &response);
- void handleDetach(const GdbResponse &response);
+ void handleVarAssign(const DebuggerResponse &response);
+ void handleDetach(const DebuggerResponse &response);
void handleThreadGroupCreated(const GdbMi &result);
void handleThreadGroupExited(const GdbMi &result);
Q_SLOT void createFullBacktrace();
- void handleCreateFullBacktrace(const GdbResponse &response);
+ void handleCreateFullBacktrace(const DebuggerResponse &response);
void updateLocals();
void updateLocalsPython(const UpdateParameters &parameters);
- void handleStackFramePython(const GdbResponse &response);
+ void handleStackFramePython(const DebuggerResponse &response, bool partial);
void setLocals(const QList<GdbMi> &locals);
@@ -472,17 +448,6 @@ protected:
// For short-circuiting stack and thread list evaluation.
bool m_stackNeeded;
- //
- // Qml
- //
- BreakpointResponseId m_qmlBreakpointResponseId1;
- BreakpointResponseId m_qmlBreakpointResponseId2;
- bool m_preparedForQmlBreak;
- bool setupQmlStep(bool on);
- void handleSetQmlStepBreakpoint(const GdbResponse &response);
- bool isQmlStepBreakpoint(const BreakpointResponseId &id) const;
- bool isQmlStepBreakpoint1(const BreakpointResponseId &id) const;
- bool isQmlStepBreakpoint2(const BreakpointResponseId &id) const;
bool isQFatalBreakpoint(const BreakpointResponseId &id) const;
bool isHiddenBreakpoint(const BreakpointResponseId &id) const;
@@ -522,7 +487,7 @@ protected:
static QByteArray dotEscape(QByteArray str);
void debugLastCommand();
- QByteArray m_lastDebuggableCommand;
+ DebuggerCommand m_lastDebuggableCommand;
protected:
virtual void write(const QByteArray &data);
diff --git a/src/plugins/debugger/gdb/gdboptionspage.cpp b/src/plugins/debugger/gdb/gdboptionspage.cpp
index 545c0e8e05..259f7acefe 100644
--- a/src/plugins/debugger/gdb/gdboptionspage.cpp
+++ b/src/plugins/debugger/gdb/gdboptionspage.cpp
@@ -311,7 +311,7 @@ QWidget *GdbOptionsPage::widget()
void GdbOptionsPage::apply()
{
if (m_widget)
- m_widget->group.apply(Core::ICore::settings());
+ m_widget->group.apply(ICore::settings());
}
void GdbOptionsPage::finish()
@@ -457,7 +457,7 @@ QWidget *GdbOptionsPage2::widget()
void GdbOptionsPage2::apply()
{
if (m_widget)
- m_widget->group.apply(Core::ICore::settings());
+ m_widget->group.apply(ICore::settings());
}
void GdbOptionsPage2::finish()
diff --git a/src/plugins/debugger/gdb/gdbplainengine.cpp b/src/plugins/debugger/gdb/gdbplainengine.cpp
index 4b955e60d9..c19bdde3a8 100644
--- a/src/plugins/debugger/gdb/gdbplainengine.cpp
+++ b/src/plugins/debugger/gdb/gdbplainengine.cpp
@@ -45,19 +45,16 @@
namespace Debugger {
namespace Internal {
-#define CB(callback) \
- static_cast<GdbEngine::GdbCommandCallback>(&GdbPlainEngine::callback), \
- STRINGIFY(callback)
+#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
GdbPlainEngine::GdbPlainEngine(const DebuggerStartParameters &startParameters)
: GdbEngine(startParameters)
{
// Output
- connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
- this, SLOT(readDebugeeOutput(QByteArray)));
+ connect(&m_outputCollector, &OutputCollector::byteDelivery,
+ this, &GdbEngine::readDebugeeOutput);
}
-
void GdbPlainEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
@@ -66,13 +63,13 @@ void GdbPlainEngine::setupInferior()
postCommand("-exec-arguments " + toLocalEncoding(args));
}
postCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
- CB(handleFileExecAndSymbols));
+ NoFlags, CB(handleFileExecAndSymbols));
}
-void GdbPlainEngine::handleFileExecAndSymbols(const GdbResponse &response)
+void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
handleInferiorPrepared();
} else {
QByteArray ba = response.data["msg"].data();
@@ -92,10 +89,10 @@ void GdbPlainEngine::runEngine()
postCommand("-exec-run", GdbEngine::RunRequest, CB(handleExecRun));
}
-void GdbPlainEngine::handleExecRun(const GdbResponse &response)
+void GdbPlainEngine::handleExecRun(const DebuggerResponse &response)
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
- if (response.resultClass == GdbResultRunning) {
+ if (response.resultClass == ResultRunning) {
//notifyEngineRunOkAndInferiorRunRequested();
notifyEngineRunAndInferiorRunOk(); // For gdb < 7.0
//showStatusMessage(tr("Running..."));
diff --git a/src/plugins/debugger/gdb/gdbplainengine.h b/src/plugins/debugger/gdb/gdbplainengine.h
index 1cf33e9263..fc889c9d28 100644
--- a/src/plugins/debugger/gdb/gdbplainengine.h
+++ b/src/plugins/debugger/gdb/gdbplainengine.h
@@ -46,8 +46,8 @@ public:
explicit GdbPlainEngine(const DebuggerStartParameters &startParameters);
private:
- void handleExecRun(const GdbResponse &response);
- void handleFileExecAndSymbols(const GdbResponse &response);
+ void handleExecRun(const DebuggerResponse &response);
+ void handleFileExecAndSymbols(const DebuggerResponse &response);
void setupInferior();
void runEngine();
diff --git a/src/plugins/debugger/gdb/gdbprocess.cpp b/src/plugins/debugger/gdb/gdbprocess.cpp
index 4987fa0d75..7115923b6a 100644
--- a/src/plugins/debugger/gdb/gdbprocess.cpp
+++ b/src/plugins/debugger/gdb/gdbprocess.cpp
@@ -31,6 +31,7 @@
#include "gdbprocess.h"
#include <debugger/debuggerconstants.h>
+#include <debugger/debuggercore.h>
#include <debugger/procinterrupt.h>
namespace Debugger {
@@ -115,8 +116,11 @@ void GdbProcess::setProcessEnvironment(const QProcessEnvironment &env)
m_gdbProc.setProcessEnvironment(env);
}
-void GdbProcess::setEnvironment(const QStringList &env)
+void GdbProcess::setEnvironment(const QStringList &env_)
{
+ QStringList env = env_;
+ if (isNativeMixedActive())
+ env.append(QLatin1String("QV4_FORCE_INTERPRETER=1")); // FIXME: REMOVE!
m_gdbProc.setEnvironment(Utils::Environment(env));
}
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
index b5c7b72d88..137a41ed2d 100644
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
+++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
@@ -38,19 +38,20 @@
#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggerstringutils.h>
+#include <coreplugin/messagebox.h>
+
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QFileInfo>
-#include <QMessageBox>
+
+using namespace Utils;
namespace Debugger {
namespace Internal {
-#define CB(callback) \
- static_cast<GdbEngine::GdbCommandCallback>(&GdbRemoteServerEngine::callback), \
- STRINGIFY(callback)
+#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
///////////////////////////////////////////////////////////////////////
//
@@ -61,16 +62,17 @@ namespace Internal {
GdbRemoteServerEngine::GdbRemoteServerEngine(const DebuggerStartParameters &startParameters)
: GdbEngine(startParameters), m_startAttempted(false)
{
- if (Utils::HostOsInfo::isWindowsHost())
+ if (HostOsInfo::isWindowsHost())
m_gdbProc->setUseCtrlCStub(startParameters.useCtrlCStub); // This is only set for QNX/BlackBerry
- connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
- SLOT(uploadProcError(QProcess::ProcessError)));
- connect(&m_uploadProc, SIGNAL(readyReadStandardOutput()),
- SLOT(readUploadStandardOutput()));
- connect(&m_uploadProc, SIGNAL(readyReadStandardError()),
- SLOT(readUploadStandardError()));
- connect(&m_uploadProc, SIGNAL(finished(int)),
- SLOT(uploadProcFinished()));
+
+ connect(&m_uploadProc, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error),
+ this, &GdbRemoteServerEngine::uploadProcError);
+ connect(&m_uploadProc, &QProcess::readyReadStandardOutput,
+ this, &GdbRemoteServerEngine::readUploadStandardOutput);
+ connect(&m_uploadProc, &QProcess::readyReadStandardError,
+ this, &GdbRemoteServerEngine::readUploadStandardError);
+ connect(&m_uploadProc, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
+ this, &GdbRemoteServerEngine::uploadProcFinished);
}
void GdbRemoteServerEngine::setupEngine()
@@ -81,9 +83,9 @@ void GdbRemoteServerEngine::setupEngine()
// Provide script information about the environment
QString arglist;
- Utils::QtcProcess::addArg(&arglist, startParameters().serverStartScript);
- Utils::QtcProcess::addArg(&arglist, startParameters().executable);
- Utils::QtcProcess::addArg(&arglist, startParameters().remoteChannel);
+ QtcProcess::addArg(&arglist, startParameters().serverStartScript);
+ QtcProcess::addArg(&arglist, startParameters().executable);
+ QtcProcess::addArg(&arglist, startParameters().remoteChannel);
m_uploadProc.start(_("/bin/sh ") + arglist);
m_uploadProc.waitForStarted();
@@ -130,7 +132,7 @@ void GdbRemoteServerEngine::uploadProcError(QProcess::ProcessError error)
}
showMessage(msg, StatusBar);
- showMessageBox(QMessageBox::Critical, tr("Error"), msg);
+ Core::AsynchronousMessageBox::critical(tr("Error"), msg);
}
void GdbRemoteServerEngine::readUploadStandardOutput()
@@ -173,12 +175,12 @@ void GdbRemoteServerEngine::setupInferior()
//const QByteArray sysroot = sp.sysroot.toLocal8Bit();
//const QByteArray remoteArch = sp.remoteArchitecture.toLatin1();
- const QString args = isMasterEngine() ? startParameters().processArgs : masterEngine()->startParameters().processArgs;
+ const QString args = isMasterEngine() ? startParameters().processArgs
+ : masterEngine()->startParameters().processArgs;
// if (!remoteArch.isEmpty())
// postCommand("set architecture " + remoteArch);
- const QString solibSearchPath
- = sp.solibSearchPath.join(Utils::HostOsInfo::pathListSeparator());
+ const QString solibSearchPath = sp.solibSearchPath.join(HostOsInfo::pathListSeparator());
if (!solibSearchPath.isEmpty())
postCommand("set solib-search-path " + solibSearchPath.toLocal8Bit());
@@ -205,7 +207,7 @@ void GdbRemoteServerEngine::setupInferior()
// mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)'
// failed.\nA problem internal to GDB has been detected,[...]
if (boolSetting(TargetAsync))
- postCommand("set target-async on", CB(handleSetTargetAsync));
+ postCommand("set target-async on", NoFlags, CB(handleSetTargetAsync));
if (executableFileName.isEmpty()) {
showMessage(tr("No symbol file given."), StatusBar);
@@ -215,21 +217,21 @@ void GdbRemoteServerEngine::setupInferior()
if (!executableFileName.isEmpty()) {
postCommand("-file-exec-and-symbols \"" + executableFileName.toLocal8Bit() + '"',
- CB(handleFileExecAndSymbols));
+ NoFlags, CB(handleFileExecAndSymbols));
}
}
-void GdbRemoteServerEngine::handleSetTargetAsync(const GdbResponse &response)
+void GdbRemoteServerEngine::handleSetTargetAsync(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == GdbResultError)
+ if (response.resultClass == ResultError)
qDebug() << "Adapter too old: does not support asynchronous mode.";
}
-void GdbRemoteServerEngine::handleFileExecAndSymbols(const GdbResponse &response)
+void GdbRemoteServerEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
callTargetRemote();
} else {
QByteArray reason = response.data["msg"].data();
@@ -265,17 +267,17 @@ void GdbRemoteServerEngine::callTargetRemote()
}
if (m_isQnxGdb)
- postCommand("target qnx " + channel, CB(handleTargetQnx));
+ postCommand("target qnx " + channel, NoFlags, CB(handleTargetQnx));
else if (startParameters().multiProcess)
- postCommand("target extended-remote " + channel, CB(handleTargetExtendedRemote));
+ postCommand("target extended-remote " + channel, NoFlags, CB(handleTargetExtendedRemote));
else
- postCommand("target remote " + channel, CB(handleTargetRemote), 10);
+ postCommand("target remote " + channel, NoFlags, CB(handleTargetRemote));
}
-void GdbRemoteServerEngine::handleTargetRemote(const GdbResponse &response)
+void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
// gdb server will stop the remote application itself.
showMessage(_("INFERIOR STARTED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
@@ -293,10 +295,10 @@ void GdbRemoteServerEngine::handleTargetRemote(const GdbResponse &response)
}
}
-void GdbRemoteServerEngine::handleTargetExtendedRemote(const GdbResponse &response)
+void GdbRemoteServerEngine::handleTargetExtendedRemote(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
showMessage(_("ATTACHED TO GDB SERVER STARTED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
QString postAttachCommands = stringSetting(GdbPostAttachCommands);
@@ -307,10 +309,10 @@ void GdbRemoteServerEngine::handleTargetExtendedRemote(const GdbResponse &respon
if (startParameters().attachPID > 0) { // attach to pid if valid
// gdb server will stop the remote application itself.
postCommand("attach " + QByteArray::number(startParameters().attachPID),
- CB(handleTargetExtendedAttach));
+ NoFlags, CB(handleTargetExtendedAttach));
} else {
postCommand("-gdb-set remote exec-file " + startParameters().remoteExecutable.toLatin1(),
- CB(handleTargetExtendedAttach));
+ NoFlags, CB(handleTargetExtendedAttach));
}
} else {
QString msg = msgConnectRemoteServerFailed(
@@ -319,10 +321,10 @@ void GdbRemoteServerEngine::handleTargetExtendedRemote(const GdbResponse &respon
}
}
-void GdbRemoteServerEngine::handleTargetExtendedAttach(const GdbResponse &response)
+void GdbRemoteServerEngine::handleTargetExtendedAttach(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
// gdb server will stop the remote application itself.
handleInferiorPrepared();
} else {
@@ -332,17 +334,11 @@ void GdbRemoteServerEngine::handleTargetExtendedAttach(const GdbResponse &respon
}
}
-void GdbRemoteServerEngine::notifyInferiorSetupOk()
-{
- emit aboutToNotifyInferiorSetupOk();
- GdbEngine::notifyInferiorSetupOk();
-}
-
-void GdbRemoteServerEngine::handleTargetQnx(const GdbResponse &response)
+void GdbRemoteServerEngine::handleTargetQnx(const DebuggerResponse &response)
{
QTC_ASSERT(m_isQnxGdb, qDebug() << m_isQnxGdb);
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
// gdb server will stop the remote application itself.
showMessage(_("INFERIOR STARTED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
@@ -350,9 +346,9 @@ void GdbRemoteServerEngine::handleTargetQnx(const GdbResponse &response)
const qint64 pid = isMasterEngine() ? startParameters().attachPID : masterEngine()->startParameters().attachPID;
const QString remoteExecutable = isMasterEngine() ? startParameters().remoteExecutable : masterEngine()->startParameters().remoteExecutable;
if (pid > -1)
- postCommand("attach " + QByteArray::number(pid), CB(handleAttach));
+ postCommand("attach " + QByteArray::number(pid), NoFlags, CB(handleAttach));
else if (!remoteExecutable.isEmpty())
- postCommand("set nto-executable " + remoteExecutable.toLatin1(), CB(handleSetNtoExecutable));
+ postCommand("set nto-executable " + remoteExecutable.toLatin1(), NoFlags, CB(handleSetNtoExecutable));
else
handleInferiorPrepared();
} else {
@@ -363,18 +359,18 @@ void GdbRemoteServerEngine::handleTargetQnx(const GdbResponse &response)
}
}
-void GdbRemoteServerEngine::handleAttach(const GdbResponse &response)
+void GdbRemoteServerEngine::handleAttach(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
switch (response.resultClass) {
- case GdbResultDone:
- case GdbResultRunning: {
+ case ResultDone:
+ case ResultRunning: {
showMessage(_("INFERIOR ATTACHED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
handleInferiorPrepared();
break;
}
- case GdbResultError:
+ case ResultError:
if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
notifyInferiorSetupFailed(msgPtraceError(startParameters().startMode));
break;
@@ -386,18 +382,18 @@ void GdbRemoteServerEngine::handleAttach(const GdbResponse &response)
}
}
-void GdbRemoteServerEngine::handleSetNtoExecutable(const GdbResponse &response)
+void GdbRemoteServerEngine::handleSetNtoExecutable(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
switch (response.resultClass) {
- case GdbResultDone:
- case GdbResultRunning: {
+ case ResultDone:
+ case ResultRunning: {
showMessage(_("EXECUTABLE SET"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
handleInferiorPrepared();
break;
}
- case GdbResultError:
+ case ResultError:
default:
QString msg = QString::fromLocal8Bit(response.data["msg"].data());
notifyInferiorSetupFailed(msg);
@@ -418,10 +414,10 @@ void GdbRemoteServerEngine::runEngine()
}
}
-void GdbRemoteServerEngine::handleExecRun(const GdbResponse &response)
+void GdbRemoteServerEngine::handleExecRun(const DebuggerResponse &response)
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
- if (response.resultClass == GdbResultRunning) {
+ if (response.resultClass == ResultRunning) {
notifyEngineRunAndInferiorRunOk();
showMessage(_("INFERIOR STARTED"));
showMessage(msgInferiorSetupOk(), StatusBar);
@@ -438,7 +434,7 @@ void GdbRemoteServerEngine::interruptInferior2()
if (boolSetting(TargetAsync)) {
postCommand("-exec-interrupt", GdbEngine::Immediate,
CB(handleInterruptInferior));
- } else if (m_isQnxGdb && Utils::HostOsInfo::isWindowsHost()) {
+ } else if (m_isQnxGdb && HostOsInfo::isWindowsHost()) {
m_gdbProc->winInterruptByCtrlC();
} else {
bool ok = m_gdbProc->interrupt();
@@ -451,9 +447,9 @@ void GdbRemoteServerEngine::interruptInferior2()
}
}
-void GdbRemoteServerEngine::handleInterruptInferior(const GdbResponse &response)
+void GdbRemoteServerEngine::handleInterruptInferior(const DebuggerResponse &response)
{
- if (response.resultClass == GdbResultDone) {
+ if (response.resultClass == ResultDone) {
// The gdb server will trigger extra output that we will pick up
// to do a proper state transition.
} else {
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.h b/src/plugins/debugger/gdb/remotegdbserveradapter.h
index 9966ac057f..2b0c732d81 100644
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.h
+++ b/src/plugins/debugger/gdb/remotegdbserveradapter.h
@@ -66,7 +66,6 @@ signals:
* a server start script should be used, but none is given.
*/
void requestSetup();
- void aboutToNotifyInferiorSetupOk();
private:
Q_SLOT void readUploadStandardOutput();
@@ -77,18 +76,17 @@ private:
void notifyEngineRemoteServerRunning(const QByteArray &serverChannel, int inferiorPid);
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
- void notifyInferiorSetupOk();
- void handleSetTargetAsync(const GdbResponse &response);
- void handleFileExecAndSymbols(const GdbResponse &response);
- void handleTargetRemote(const GdbResponse &response);
- void handleTargetExtendedRemote(const GdbResponse &response);
- void handleTargetExtendedAttach(const GdbResponse &response);
- void handleTargetQnx(const GdbResponse &response);
- void handleAttach(const GdbResponse &response);
- void handleSetNtoExecutable(const GdbResponse &response);
- void handleInterruptInferior(const GdbResponse &response);
- void handleExecRun(const GdbResponse &response);
+ void handleSetTargetAsync(const DebuggerResponse &response);
+ void handleFileExecAndSymbols(const DebuggerResponse &response);
+ void handleTargetRemote(const DebuggerResponse &response);
+ void handleTargetExtendedRemote(const DebuggerResponse &response);
+ void handleTargetExtendedAttach(const DebuggerResponse &response);
+ void handleTargetQnx(const DebuggerResponse &response);
+ void handleAttach(const DebuggerResponse &response);
+ void handleSetNtoExecutable(const DebuggerResponse &response);
+ void handleInterruptInferior(const DebuggerResponse &response);
+ void handleExecRun(const DebuggerResponse &response);
QProcess m_uploadProc;
bool m_startAttempted;
diff --git a/src/plugins/debugger/gdb/startgdbserverdialog.cpp b/src/plugins/debugger/gdb/startgdbserverdialog.cpp
index 6c224b5b6c..346668ea19 100644
--- a/src/plugins/debugger/gdb/startgdbserverdialog.cpp
+++ b/src/plugins/debugger/gdb/startgdbserverdialog.cpp
@@ -37,6 +37,7 @@
#include <debugger/debuggerstartparameters.h>
#include <coreplugin/icore.h>
+#include <coreplugin/messagebox.h>
#include <projectexplorer/kitchooser.h>
#include <projectexplorer/devicesupport/deviceprocesslist.h>
#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
@@ -45,7 +46,6 @@
#include <utils/portlist.h>
#include <utils/qtcassert.h>
-#include <QMessageBox>
#include <QFileInfo>
using namespace Core;
@@ -90,7 +90,7 @@ GdbServerStarter::~GdbServerStarter()
void GdbServerStarter::handleRemoteError(const QString &errorMsg)
{
- QMessageBox::critical(0, tr("Remote Error"), errorMsg);
+ AsynchronousMessageBox::critical(tr("Remote Error"), errorMsg);
}
void GdbServerStarter::portGathererError(const QString &text)
@@ -103,8 +103,10 @@ void GdbServerStarter::portGathererError(const QString &text)
void GdbServerStarter::run()
{
QTC_ASSERT(d->device, return);
- connect(&d->gatherer, SIGNAL(error(QString)), SLOT(portGathererError(QString)));
- connect(&d->gatherer, SIGNAL(portListReady()), SLOT(portListReady()));
+ connect(&d->gatherer, &DeviceUsedPortsGatherer::error,
+ this, &GdbServerStarter::portGathererError);
+ connect(&d->gatherer, &DeviceUsedPortsGatherer::portListReady,
+ this, &GdbServerStarter::portListReady);
d->gatherer.start(d->device);
}
@@ -118,11 +120,16 @@ void GdbServerStarter::portListReady()
return;
}
- connect(&d->runner, SIGNAL(connectionError()), SLOT(handleConnectionError()));
- connect(&d->runner, SIGNAL(processStarted()), SLOT(handleProcessStarted()));
- connect(&d->runner, SIGNAL(readyReadStandardOutput()), SLOT(handleProcessOutputAvailable()));
- connect(&d->runner, SIGNAL(readyReadStandardError()), SLOT(handleProcessErrorOutput()));
- connect(&d->runner, SIGNAL(processClosed(int)), SLOT(handleProcessClosed(int)));
+ connect(&d->runner, &SshRemoteProcessRunner::connectionError,
+ this, &GdbServerStarter::handleConnectionError);
+ connect(&d->runner, &SshRemoteProcessRunner::processStarted,
+ this, &GdbServerStarter::handleProcessStarted);
+ connect(&d->runner, &SshRemoteProcessRunner::readyReadStandardOutput,
+ this, &GdbServerStarter::handleProcessOutputAvailable);
+ connect(&d->runner, &SshRemoteProcessRunner::readyReadStandardError,
+ this, &GdbServerStarter::handleProcessErrorOutput);
+ connect(&d->runner, &SshRemoteProcessRunner::processClosed,
+ this, &GdbServerStarter::handleProcessClosed);
QByteArray gdbServerPath = d->device->debugServerPath().toUtf8();
if (gdbServerPath.isEmpty())
@@ -191,15 +198,15 @@ void GdbServerStarter::attach(int port)
localExecutable = candidate;
}
if (localExecutable.isEmpty()) {
- QMessageBox::warning(ICore::mainWindow(), tr("Warning"),
+ AsynchronousMessageBox::warning(tr("Warning"),
tr("Cannot find local executable for remote process \"%1\".")
.arg(d->process.exe));
return;
}
- QList<Abi> abis = Abi::abisOfBinary(Utils::FileName::fromString(localExecutable));
+ QList<Abi> abis = Abi::abisOfBinary(FileName::fromString(localExecutable));
if (abis.isEmpty()) {
- QMessageBox::warning(ICore::mainWindow(), tr("Warning"),
+ AsynchronousMessageBox::warning(tr("Warning"),
tr("Cannot find ABI for remote process \"%1\".")
.arg(d->process.exe));
return;
diff --git a/src/plugins/debugger/gdb/termgdbadapter.cpp b/src/plugins/debugger/gdb/termgdbadapter.cpp
index 33bf3a176e..8a9b20355b 100644
--- a/src/plugins/debugger/gdb/termgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/termgdbadapter.cpp
@@ -39,18 +39,13 @@
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <coreplugin/icore.h>
-
-#include <QMessageBox>
+#include <coreplugin/messagebox.h>
using namespace Utils;
namespace Debugger {
namespace Internal {
-#define CB(callback) \
- static_cast<GdbEngine::GdbCommandCallback>(&GdbTermEngine::callback), \
- STRINGIFY(callback)
-
///////////////////////////////////////////////////////////////////////
//
// TermGdbAdapter
@@ -63,11 +58,11 @@ GdbTermEngine::GdbTermEngine(const DebuggerStartParameters &startParameters)
#ifdef Q_OS_WIN
// Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
- m_stubProc.setMode(Utils::ConsoleProcess::Suspend);
+ m_stubProc.setMode(ConsoleProcess::Suspend);
else
- m_stubProc.setMode(Utils::ConsoleProcess::Debug);
+ m_stubProc.setMode(ConsoleProcess::Debug);
#else
- m_stubProc.setMode(Utils::ConsoleProcess::Debug);
+ m_stubProc.setMode(ConsoleProcess::Debug);
m_stubProc.setSettings(Core::ICore::settings());
#endif
}
@@ -95,9 +90,12 @@ void GdbTermEngine::setupEngine()
// Set environment + dumper preload.
m_stubProc.setEnvironment(startParameters().environment);
- connect(&m_stubProc, SIGNAL(processError(QString)), SLOT(stubError(QString)));
- connect(&m_stubProc, SIGNAL(processStarted()), SLOT(stubStarted()));
- connect(&m_stubProc, SIGNAL(stubStopped()), SLOT(stubExited()));
+ connect(&m_stubProc, &ConsoleProcess::processError,
+ this, &GdbTermEngine::stubError);
+ connect(&m_stubProc, &ConsoleProcess::processStarted,
+ this, &GdbTermEngine::stubStarted);
+ connect(&m_stubProc, &ConsoleProcess::stubStopped,
+ this, &GdbTermEngine::stubExited);
// FIXME: Starting the stub implies starting the inferior. This is
// fairly unclean as far as the state machine and error reporting go.
@@ -136,17 +134,17 @@ void GdbTermEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
const qint64 attachedPID = m_stubProc.applicationPID();
- postCommand("attach " + QByteArray::number(attachedPID),
- CB(handleStubAttached));
+ postCommand("attach " + QByteArray::number(attachedPID), NoFlags,
+ [this](const DebuggerResponse &r) { handleStubAttached(r); });
}
-void GdbTermEngine::handleStubAttached(const GdbResponse &response)
+void GdbTermEngine::handleStubAttached(const DebuggerResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
switch (response.resultClass) {
- case GdbResultDone:
- case GdbResultRunning:
+ case ResultDone:
+ case ResultRunning:
if (startParameters().toolChainAbi.os() != ProjectExplorer::Abi::WindowsOS) {
showMessage(_("INFERIOR ATTACHED"));
} else {
@@ -165,7 +163,7 @@ void GdbTermEngine::handleStubAttached(const GdbResponse &response)
notifyEngineRunAndInferiorStopOk();
continueInferiorInternal();
break;
- case GdbResultError:
+ case ResultError:
if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
showMessage(msgPtraceError(startParameters().startMode));
notifyEngineRunFailed();
@@ -188,7 +186,7 @@ void GdbTermEngine::interruptInferior2()
void GdbTermEngine::stubError(const QString &msg)
{
- showMessageBox(QMessageBox::Critical, tr("Debugger Error"), msg);
+ Core::AsynchronousMessageBox::critical(tr("Debugger Error"), msg);
}
void GdbTermEngine::stubExited()
diff --git a/src/plugins/debugger/gdb/termgdbadapter.h b/src/plugins/debugger/gdb/termgdbadapter.h
index 6af88b39a1..2ffebbabb0 100644
--- a/src/plugins/debugger/gdb/termgdbadapter.h
+++ b/src/plugins/debugger/gdb/termgdbadapter.h
@@ -60,7 +60,7 @@ private:
void interruptInferior2();
void shutdownEngine();
- void handleStubAttached(const GdbResponse &response);
+ void handleStubAttached(const DebuggerResponse &response);
Q_SLOT void stubStarted();
Q_SLOT void stubExited();
diff --git a/src/plugins/debugger/imageviewer.cpp b/src/plugins/debugger/imageviewer.cpp
index 21c3501ea3..26015f9fc6 100644
--- a/src/plugins/debugger/imageviewer.cpp
+++ b/src/plugins/debugger/imageviewer.cpp
@@ -104,11 +104,11 @@ ImageViewer::ImageViewer(QWidget *parent)
, m_imageWidget(new ImageWidget)
, m_infoLabel(new QLabel)
{
- QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ auto mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(m_infoLabel);
mainLayout->addWidget(m_scrollArea);
m_scrollArea->setWidget(m_imageWidget);
- connect(m_imageWidget, SIGNAL(clicked(QString)), this, SLOT(clicked(QString)));
+ connect(m_imageWidget, &ImageWidget::clicked, this, &ImageViewer::clicked);
}
void ImageViewer::setImage(const QImage &i)
diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp
index 5fb75784fa..359403bfa4 100644
--- a/src/plugins/debugger/lldb/lldbengine.cpp
+++ b/src/plugins/debugger/lldb/lldbengine.cpp
@@ -50,25 +50,26 @@
#include <debugger/watchhandler.h>
#include <debugger/watchutils.h>
+#include <coreplugin/messagebox.h>
+#include <coreplugin/idocument.h>
+#include <coreplugin/icore.h>
+
+#include <texteditor/texteditor.h>
+
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
#include <utils/qtcprocess.h>
-#include <texteditor/texteditor.h>
-#include <coreplugin/idocument.h>
-#include <coreplugin/icore.h>
-
+#include <QApplication>
#include <QDateTime>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QTimer>
-#include <QVariant>
-
-#include <QApplication>
-#include <QMessageBox>
#include <QToolTip>
+#include <QVariant>
+using namespace Core;
using namespace Utils;
namespace Debugger {
@@ -91,25 +92,25 @@ LldbEngine::LldbEngine(const DebuggerStartParameters &startParameters)
#ifdef Q_OS_WIN
// Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
- m_stubProc.setMode(Utils::ConsoleProcess::Suspend);
+ m_stubProc.setMode(ConsoleProcess::Suspend);
else
- m_stubProc.setMode(Utils::ConsoleProcess::Debug);
+ m_stubProc.setMode(ConsoleProcess::Debug);
#else
- m_stubProc.setMode(Utils::ConsoleProcess::Debug);
- m_stubProc.setSettings(Core::ICore::settings());
+ m_stubProc.setMode(ConsoleProcess::Debug);
+ m_stubProc.setSettings(ICore::settings());
#endif
}
- connect(action(AutoDerefPointers), SIGNAL(valueChanged(QVariant)),
- SLOT(updateLocals()));
- connect(action(CreateFullBacktrace), SIGNAL(triggered()),
- SLOT(createFullBacktrace()));
- connect(action(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)),
- SLOT(updateLocals()));
- connect(action(UseDynamicType), SIGNAL(valueChanged(QVariant)),
- SLOT(updateLocals()));
- connect(action(IntelFlavor), SIGNAL(valueChanged(QVariant)),
- SLOT(updateAll()));
+ connect(action(AutoDerefPointers), &SavedAction::valueChanged,
+ this, &LldbEngine::updateLocals);
+ connect(action(CreateFullBacktrace), &QAction::triggered,
+ this, &LldbEngine::createFullBacktrace);
+ connect(action(UseDebuggingHelpers), &SavedAction::valueChanged,
+ this, &LldbEngine::updateLocals);
+ connect(action(UseDynamicType), &SavedAction::valueChanged,
+ this, &LldbEngine::updateLocals);
+ connect(action(IntelFlavor), &SavedAction::valueChanged,
+ this, &LldbEngine::updateAll);
}
LldbEngine::~LldbEngine()
@@ -120,18 +121,19 @@ LldbEngine::~LldbEngine()
void LldbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages)
{
- runCommand(Command("executeDebuggerCommand").arg("command", command));
+ DebuggerCommand cmd("executeDebuggerCommand");
+ cmd.arg("command", command);
+ runCommand(cmd);
}
-void LldbEngine::runCommand(const Command &command)
+void LldbEngine::runCommand(const DebuggerCommand &command)
{
QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll());
++m_lastToken;
QByteArray token = QByteArray::number(m_lastToken);
- QByteArray cmd = "{\"cmd\":\"" + command.function + "\","
- + command.args + "\"token\":" + token + "}\n";
- showMessage(_(token + cmd), LogInput);
- m_lldbProc.write(cmd);
+ QByteArray cmd = command.function + "({" + command.args + "})";
+ showMessage(_(token + cmd + '\n'), LogInput);
+ m_lldbProc.write("sc db." + cmd + "\n");
}
void LldbEngine::debugLastCommand()
@@ -142,7 +144,7 @@ void LldbEngine::debugLastCommand()
void LldbEngine::shutdownInferior()
{
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
- runCommand(Command("shutdownInferior"));
+ runCommand(DebuggerCommand("shutdownInferior"));
}
void LldbEngine::shutdownEngine()
@@ -174,9 +176,9 @@ bool LldbEngine::prepareCommand()
DebuggerStartParameters &sp = startParameters();
QtcProcess::SplitError perr;
sp.processArgs = QtcProcess::prepareArgs(sp.processArgs, &perr,
- Utils::HostOsInfo::hostOs(),
+ HostOsInfo::hostOs(),
&sp.environment, &sp.workingDirectory).toWindowsArgs();
- if (perr != Utils::QtcProcess::SplitOk) {
+ if (perr != QtcProcess::SplitOk) {
// perr == BadQuoting is never returned on Windows
// FIXME? QTCREATORBUG-2809
notifyEngineSetupFailed();
@@ -207,9 +209,9 @@ void LldbEngine::setupEngine()
// Set environment + dumper preload.
m_stubProc.setEnvironment(startParameters().environment);
- connect(&m_stubProc, SIGNAL(processError(QString)), SLOT(stubError(QString)));
- connect(&m_stubProc, SIGNAL(processStarted()), SLOT(stubStarted()));
- connect(&m_stubProc, SIGNAL(stubStopped()), SLOT(stubExited()));
+ connect(&m_stubProc, &ConsoleProcess::processError, this, &LldbEngine::stubError);
+ connect(&m_stubProc, &ConsoleProcess::processStarted, this, &LldbEngine::stubStarted);
+ connect(&m_stubProc, &ConsoleProcess::stubStopped, this, &LldbEngine::stubExited);
// FIXME: Starting the stub implies starting the inferior. This is
// fairly unclean as far as the state machine and error reporting go.
@@ -233,28 +235,24 @@ void LldbEngine::setupEngine()
void LldbEngine::startLldb()
{
m_lldbCmd = startParameters().debuggerCommand;
- connect(&m_lldbProc, SIGNAL(error(QProcess::ProcessError)),
- SLOT(handleLldbError(QProcess::ProcessError)));
- connect(&m_lldbProc, SIGNAL(finished(int,QProcess::ExitStatus)),
- SLOT(handleLldbFinished(int,QProcess::ExitStatus)));
- connect(&m_lldbProc, SIGNAL(readyReadStandardOutput()),
- SLOT(readLldbStandardOutput()));
- connect(&m_lldbProc, SIGNAL(readyReadStandardError()),
- SLOT(readLldbStandardError()));
-
- connect(this, SIGNAL(outputReady(QByteArray)),
- SLOT(handleResponse(QByteArray)), Qt::QueuedConnection);
-
- QStringList args;
- args.append(_("-i"));
- args.append(Core::ICore::resourcePath() + _("/debugger/lldbbridge.py"));
- args.append(m_lldbCmd);
- showMessage(_("STARTING LLDB: python ") + args.join(QLatin1Char(' ')));
+ connect(&m_lldbProc, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error),
+ this, &LldbEngine::handleLldbError);
+ connect(&m_lldbProc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
+ this, &LldbEngine::handleLldbFinished);
+ connect(&m_lldbProc, &QProcess::readyReadStandardOutput,
+ this, &LldbEngine::readLldbStandardOutput);
+ connect(&m_lldbProc, &QProcess::readyReadStandardError,
+ this, &LldbEngine::readLldbStandardError);
+
+ connect(this, &LldbEngine::outputReady,
+ this, &LldbEngine::handleResponse, Qt::QueuedConnection);
+
+ showMessage(_("STARTING LLDB: ") + m_lldbCmd);
m_lldbProc.setEnvironment(startParameters().environment.toStringList());
if (!startParameters().workingDirectory.isEmpty())
m_lldbProc.setWorkingDirectory(startParameters().workingDirectory);
- m_lldbProc.start(_("python"), args);
+ m_lldbProc.start(m_lldbCmd);
if (!m_lldbProc.waitForStarted()) {
const QString msg = tr("Unable to start LLDB \"%1\": %2")
@@ -262,8 +260,23 @@ void LldbEngine::startLldb()
notifyEngineSetupFailed();
showMessage(_("ADAPTER START FAILED"));
if (!msg.isEmpty())
- Core::ICore::showWarningWithOptions(tr("Adapter start failed."), msg);
+ ICore::showWarningWithOptions(tr("Adapter start failed."), msg);
}
+
+ showMessage(_("ADAPTER STARTED"));
+ showStatusMessage(tr("Setting up inferior..."));
+
+ const QByteArray dumperSourcePath =
+ ICore::resourcePath().toLocal8Bit() + "/debugger/";
+
+ m_lldbProc.write("sc sys.path.insert(1, '" + dumperSourcePath + "')\n");
+ m_lldbProc.write("sc from lldbbridge import *\n");
+ m_lldbProc.write("sc print(dir())\n");
+ m_lldbProc.write("sc db = Dumper()\n");
+ m_lldbProc.write("sc db.report('lldbversion=\"%s\"' % lldb.SBDebugger.GetVersionString())\n");
+
+ showMessage(_("ENGINE SUCCESSFULLY STARTED"));
+ notifyEngineSetupOk();
}
void LldbEngine::setupInferior()
@@ -272,35 +285,48 @@ void LldbEngine::setupInferior()
const QString path = stringSetting(ExtraDumperFile);
if (!path.isEmpty()) {
- QFileInfo fi(path);
-
- Command cmd1("executeDebuggerCommand");
- cmd1.arg("command", "python sys.path.insert(1, '" + fi.absolutePath().toUtf8() + "')");
- runCommand(cmd1);
-
- Command cmd2("executeDebuggerCommand");
- cmd2.arg("python from " + fi.baseName().toUtf8() + " import *");
- runCommand(cmd2);
+ DebuggerCommand cmd("addDumperModule");
+ cmd.arg("path", path.toUtf8());
+ runCommand(cmd);
}
const QString commands = stringSetting(ExtraDumperCommands);
if (!commands.isEmpty()) {
- Command cmd("executeDebuggerCommand");
- cmd.arg(commands.toUtf8());
+ DebuggerCommand cmd("executeDebuggerCommand");
+ cmd.arg("commands", commands.toUtf8());
runCommand(cmd);
}
+ DebuggerCommand cmd1("loadDumperFiles");
+ runCommand(cmd1);
+
QString executable;
- Utils::QtcProcess::Arguments args;
- Utils::QtcProcess::prepareCommand(QFileInfo(sp.executable).absoluteFilePath(),
- sp.processArgs, &executable, &args);
+ QtcProcess::Arguments args;
+ QtcProcess::prepareCommand(QFileInfo(sp.executable).absoluteFilePath(),
+ sp.processArgs, &executable, &args);
- Command cmd("setupInferior");
+ DebuggerCommand cmd("setupInferior");
cmd.arg("executable", executable);
cmd.arg("breakOnMain", sp.breakOnMain);
cmd.arg("useTerminal", sp.useTerminal);
cmd.arg("startMode", sp.startMode);
+ cmd.beginList("bkpts");
+ foreach (Breakpoint bp, breakHandler()->unclaimedBreakpoints()) {
+ if (acceptsBreakpoint(bp)) {
+ showMessage(_("TAKING OWNERSHIP OF BREAKPOINT %1 IN STATE %2")
+ .arg(bp.id().toString()).arg(bp.state()));
+ bp.setEngine(this);
+ cmd.beginGroup();
+ bp.addToCommand(&cmd);
+ cmd.endGroup();
+ } else {
+ showMessage(_("BREAKPOINT %1 IN STATE %2 IS NOT ACCEPTABLE")
+ .arg(bp.id().toString()).arg(bp.state()));
+ }
+ }
+ cmd.endList();
+
cmd.beginList("processArgs");
foreach (const QString &arg, args.toUnixArgs())
cmd.arg(arg.toUtf8().toHex());
@@ -340,19 +366,7 @@ void LldbEngine::setupInferior()
void LldbEngine::runEngine()
{
- QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
-
- Command cmd("handleBreakpoints");
- if (attemptBreakpointSynchronizationHelper(&cmd)) {
- runEngine2();
- } else {
- cmd.arg("continuation", "runEngine2");
- runCommand(cmd);
- }
-}
-
-void LldbEngine::runEngine2()
-{
+ QTC_ASSERT(state() == EngineRunRequested, qDebug() << state(); return);
showStatusMessage(tr("Running requested..."), 5000);
runCommand("runEngine");
}
@@ -414,6 +428,8 @@ void LldbEngine::handleResponse(const QByteArray &response)
const QByteArray name = item.name();
if (name == "data")
refreshLocals(item);
+ else if (name == "dumpers")
+ watchHandler()->addDumpers(item);
else if (name == "stack")
refreshStack(item);
else if (name == "stack-position")
@@ -446,8 +462,6 @@ void LldbEngine::handleResponse(const QByteArray &response)
refreshDisassembly(item);
else if (name == "memory")
refreshMemory(item);
- else if (name == "continuation")
- runContinuation(item);
else if (name == "full-backtrace")
showFullBacktrace(item);
else if (name == "statusmessage") {
@@ -465,17 +479,11 @@ void LldbEngine::showFullBacktrace(const GdbMi &data)
QString::fromUtf8(QByteArray::fromHex(data.data())));
}
-void LldbEngine::runContinuation(const GdbMi &data)
-{
- const QByteArray target = data.data();
- QMetaObject::invokeMethod(this, target, Qt::QueuedConnection);
-}
-
void LldbEngine::executeRunToLine(const ContextData &data)
{
resetLocation();
notifyInferiorRunRequested();
- Command cmd("executeRunToLocation");
+ DebuggerCommand cmd("executeRunToLocation");
cmd.arg("file", data.fileName);
cmd.arg("line", data.lineNumber);
cmd.arg("address", data.address);
@@ -486,14 +494,16 @@ void LldbEngine::executeRunToFunction(const QString &functionName)
{
resetLocation();
notifyInferiorRunRequested();
- runCommand(Command("executeRunToFunction").arg("function", functionName));
+ DebuggerCommand cmd("executeRunToFunction");
+ cmd.arg("function", functionName);
+ runCommand(cmd);
}
void LldbEngine::executeJumpToLine(const ContextData &data)
{
resetLocation();
notifyInferiorRunRequested();
- Command cmd("executeJumpToLocation");
+ DebuggerCommand cmd("executeJumpToLocation");
cmd.arg("file", data.fileName);
cmd.arg("line", data.lineNumber);
cmd.arg("address", data.address);
@@ -508,13 +518,14 @@ void LldbEngine::activateFrame(int frameIndex)
const int n = stackHandler()->stackSize();
if (frameIndex == n) {
- Command cmd("reportStack");
+ DebuggerCommand cmd("reportStack");
+ cmd.arg("nativeMixed", isNativeMixedActive());
cmd.arg("stacklimit", n * 10 + 3);
runCommand(cmd);
return;
}
- Command cmd("activateFrame");
+ DebuggerCommand cmd("activateFrame");
cmd.arg("index", frameIndex);
cmd.arg("thread", threadsHandler()->currentThread().raw());
runCommand(cmd);
@@ -525,117 +536,61 @@ void LldbEngine::activateFrame(int frameIndex)
void LldbEngine::selectThread(ThreadId threadId)
{
- runCommand(Command("selectThread").arg("id", threadId.raw()));
+ DebuggerCommand cmd("selectThread");
+ cmd.arg("id", threadId.raw());
+ runCommand(cmd);
}
-bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const
+bool LldbEngine::stateAcceptsBreakpointChanges() const
{
- return breakHandler()->breakpointData(id).isCppBreakpoint()
- && startParameters().startMode != AttachCore;
+ switch (state()) {
+ case InferiorSetupRequested:
+ case InferiorRunRequested:
+ case InferiorRunOk:
+ case InferiorStopRequested:
+ case InferiorStopOk:
+ return true;
+ default:
+ return false;
+ }
}
-bool LldbEngine::attemptBreakpointSynchronizationHelper(Command *cmd)
+bool LldbEngine::acceptsBreakpoint(Breakpoint bp) const
{
- BreakHandler *handler = breakHandler();
-
- foreach (BreakpointModelId id, handler->unclaimedBreakpointIds()) {
- // Take ownership of the breakpoint. Requests insertion.
- if (acceptsBreakpoint(id)) {
- showMessage(_("TAKING OWNERSHIP OF BREAKPOINT %1 IN STATE %2")
- .arg(id.toString()).arg(handler->state(id)));
- handler->setEngine(id, this);
- } else {
- showMessage(_("BREAKPOINT %1 IN STATE %2 IS NOT ACCEPTABLE")
- .arg(id.toString()).arg(handler->state(id)));
- }
- }
+ if (startParameters().startMode == AttachCore)
+ return false;
+ // We handle QML breakpoint unless specifically disabled.
+ if (isNativeMixedEnabled() && !(startParameters().languages & QmlLanguage))
+ return true;
+ return bp.parameters().isCppBreakpoint();
+}
- bool done = true;
- cmd->beginList("bkpts");
- foreach (BreakpointModelId id, handler->engineBreakpointIds(this)) {
- const BreakpointResponse &response = handler->response(id);
- const BreakpointState bpState = handler->state(id);
- switch (bpState) {
- case BreakpointNew:
- // Should not happen once claimed.
- QTC_CHECK(false);
- break;
- case BreakpointInsertRequested:
- done = false;
- cmd->beginGroup()
- .arg("operation", "add")
- .arg("modelid", id.toByteArray())
- .arg("type", handler->type(id))
- .arg("ignorecount", handler->ignoreCount(id))
- .arg("condition", handler->condition(id).toHex())
- .arg("function", handler->functionName(id).toUtf8())
- .arg("oneshot", handler->isOneShot(id))
- .arg("enabled", handler->isEnabled(id))
- .arg("file", handler->fileName(id).toUtf8())
- .arg("line", handler->lineNumber(id))
- .arg("address", handler->address(id))
- .arg("expression", handler->expression(id))
- .endGroup();
- handler->notifyBreakpointInsertProceeding(id);
- break;
- case BreakpointChangeRequested:
- done = false;
- cmd->beginGroup()
- .arg("operation", "change")
- .arg("modelid", id.toByteArray())
- .arg("lldbid", response.id.toByteArray())
- .arg("type", handler->type(id))
- .arg("ignorecount", handler->ignoreCount(id))
- .arg("condition", handler->condition(id).toHex())
- .arg("function", handler->functionName(id).toUtf8())
- .arg("oneshot", handler->isOneShot(id))
- .arg("enabled", handler->isEnabled(id))
- .arg("file", handler->fileName(id).toUtf8())
- .arg("line", handler->lineNumber(id))
- .arg("address", handler->address(id))
- .arg("expression", handler->expression(id))
- .endGroup();
- handler->notifyBreakpointChangeProceeding(id);
- break;
- case BreakpointRemoveRequested:
- done = false;
- cmd->beginGroup()
- .arg("operation", "remove")
- .arg("modelid", id.toByteArray())
- .arg("lldbid", response.id.toByteArray())
- .endGroup();
- handler->notifyBreakpointRemoveProceeding(id);
- break;
- case BreakpointChangeProceeding:
- case BreakpointInsertProceeding:
- case BreakpointRemoveProceeding:
- case BreakpointInserted:
- case BreakpointDead:
- QTC_ASSERT(false, qDebug() << "UNEXPECTED STATE" << bpState << "FOR BP " << id);
- break;
- default:
- QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << bpState << "FOR BP" << id);
- }
- }
- cmd->endList();
- return done;
+void LldbEngine::insertBreakpoint(Breakpoint bp)
+{
+ DebuggerCommand cmd("insertBreakpoint");
+ bp.addToCommand(&cmd);
+ bp.notifyBreakpointInsertProceeding();
+ runCommand(cmd);
}
-void LldbEngine::attemptBreakpointSynchronization()
+void LldbEngine::changeBreakpoint(Breakpoint bp)
{
- showMessage(_("ATTEMPT BREAKPOINT SYNCHRONIZATION"));
- if (!stateAcceptsBreakpointChanges()) {
- showMessage(_("BREAKPOINT SYNCHRONIZATION NOT POSSIBLE IN CURRENT STATE"));
- return;
- }
+ const BreakpointResponse &response = bp.response();
+ DebuggerCommand cmd("changeBreakpoint");
+ cmd.arg("lldbid", response.id.toByteArray());
+ bp.addToCommand(&cmd);
+ bp.notifyBreakpointChangeProceeding();
+ runCommand(cmd);
+}
- Command cmd("handleBreakpoints");
- if (!attemptBreakpointSynchronizationHelper(&cmd)) {
- showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED"));
- runCommand(cmd);
- } else {
- showMessage(_("BREAKPOINTS ARE SYNCHRONIZED"));
- }
+void LldbEngine::removeBreakpoint(Breakpoint bp)
+{
+ const BreakpointResponse &response = bp.response();
+ DebuggerCommand cmd("removeBreakpoint");
+ cmd.arg("modelid", bp.id().toByteArray());
+ cmd.arg("lldbid", response.id.toByteArray());
+ bp.notifyBreakpointRemoveProceeding();
+ runCommand(cmd);
}
void LldbEngine::updateBreakpointData(const GdbMi &bkpt, bool added)
@@ -643,9 +598,10 @@ void LldbEngine::updateBreakpointData(const GdbMi &bkpt, bool added)
BreakHandler *handler = breakHandler();
BreakpointResponseId rid = BreakpointResponseId(bkpt["lldbid"].data());
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
- if (!id.isValid())
- id = handler->findBreakpointByResponseId(rid);
- BreakpointResponse response = handler->response(id);
+ Breakpoint bp = handler->breakpointById(id);
+ if (!bp.isValid())
+ bp = handler->findBreakpointByResponseId(rid);
+ BreakpointResponse response = bp.response();
if (added)
response.id = rid;
QTC_CHECK(response.id == rid);
@@ -669,7 +625,7 @@ void LldbEngine::updateBreakpointData(const GdbMi &bkpt, bool added)
sub.functionName = location["func"].toUtf8();
sub.fileName = location["file"].toUtf8();
sub.lineNumber = location["line"].toInt();
- handler->insertSubBreakpoint(id, sub);
+ bp.insertSubBreakpoint(sub);
}
} else if (numChild == 1) {
const GdbMi location = locations.childAt(0);
@@ -679,11 +635,11 @@ void LldbEngine::updateBreakpointData(const GdbMi &bkpt, bool added)
// This can happen for pending breakpoints.
showMessage(_("NO LOCATIONS (YET) FOR BP %1").arg(response.toString()));
}
- handler->setResponse(id, response);
+ bp.setResponse(response);
if (added)
- handler->notifyBreakpointInsertOk(id);
+ bp.notifyBreakpointInsertOk();
else
- handler->notifyBreakpointChangeOk(id);
+ bp.notifyBreakpointChangeOk();
}
void LldbEngine::refreshDisassembly(const GdbMi &data)
@@ -736,23 +692,25 @@ void LldbEngine::refreshOutput(const GdbMi &output)
void LldbEngine::refreshAddedBreakpoint(const GdbMi &bkpt)
{
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
- QTC_CHECK(breakHandler()->state(id) == BreakpointInsertProceeding);
+ Breakpoint bp = breakHandler()->breakpointById(id);
+ QTC_CHECK(bp.state() == BreakpointInsertProceeding);
updateBreakpointData(bkpt, true);
}
void LldbEngine::refreshChangedBreakpoint(const GdbMi &bkpt)
{
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
- QTC_CHECK(!id.isValid() || breakHandler()->state(id) == BreakpointChangeProceeding);
+ Breakpoint bp = breakHandler()->breakpointById(id);
+ QTC_CHECK(!bp.isValid() || bp.state() == BreakpointChangeProceeding);
updateBreakpointData(bkpt, false);
}
void LldbEngine::refreshRemovedBreakpoint(const GdbMi &bkpt)
{
- BreakHandler *handler = breakHandler();
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
- QTC_CHECK(handler->state(id) == BreakpointRemoveProceeding);
- handler->notifyBreakpointRemoveOk(id);
+ Breakpoint bp = breakHandler()->breakpointById(id);
+ QTC_CHECK(bp.state() == BreakpointRemoveProceeding);
+ bp.notifyBreakpointRemoveOk();
}
void LldbEngine::loadSymbols(const QString &moduleName)
@@ -771,7 +729,8 @@ void LldbEngine::reloadModules()
void LldbEngine::refreshModules(const GdbMi &modules)
{
- Modules mods;
+ ModulesHandler *handler = modulesHandler();
+ handler->beginUpdateAll();
foreach (const GdbMi &item, modules.children()) {
Module module;
module.modulePath = item["file"].toUtf8();
@@ -779,14 +738,16 @@ void LldbEngine::refreshModules(const GdbMi &modules)
module.symbolsRead = Module::UnknownReadState;
module.startAddress = item["loaded_addr"].toAddress();
module.endAddress = 0; // FIXME: End address not easily available.
- mods.append(module);
+ handler->updateModule(module);
}
- modulesHandler()->setModules(mods);
+ handler->endUpdateAll();
}
void LldbEngine::requestModuleSymbols(const QString &moduleName)
{
- runCommand(Command("listSymbols").arg("module", moduleName));
+ DebuggerCommand cmd("listSymbols");
+ cmd.arg("module", moduleName);
+ runCommand(cmd);
}
void LldbEngine::refreshSymbols(const GdbMi &symbols)
@@ -827,8 +788,6 @@ bool LldbEngine::setToolTipExpression(TextEditor::TextEditorWidget *editorWidget
UpdateParameters params;
params.tryPartial = true;
- params.tooltipOnly = true;
- params.tooltipExpression = context.expression;
params.varList = context.iname;
doUpdateLocals(params);
@@ -844,14 +803,16 @@ void LldbEngine::updateAll()
void LldbEngine::reloadFullStack()
{
- Command cmd("reportStack");
+ DebuggerCommand cmd("reportStack");
+ cmd.arg("nativeMixed", isNativeMixedActive());
cmd.arg("stacklimit", -1);
runCommand(cmd);
}
void LldbEngine::updateStack()
{
- Command cmd("reportStack");
+ DebuggerCommand cmd("reportStack");
+ cmd.arg("nativeMixed", isNativeMixedActive());
cmd.arg("stacklimit", action(MaximalStackDepth)->value().toInt());
runCommand(cmd);
}
@@ -866,7 +827,7 @@ void LldbEngine::assignValueInDebugger(const Internal::WatchData *data,
const QString &expression, const QVariant &value)
{
Q_UNUSED(data);
- Command cmd("assignValue");
+ DebuggerCommand cmd("assignValue");
cmd.arg("exp", expression.toLatin1().toHex());
cmd.arg("value", value.toString().toLatin1().toHex());
runCommand(cmd);
@@ -887,12 +848,9 @@ void LldbEngine::updateLocals()
void LldbEngine::doUpdateLocals(UpdateParameters params)
{
- WatchHandler *handler = watchHandler();
-
- Command cmd("updateData");
- cmd.arg("expanded", handler->expansionRequests());
- cmd.arg("typeformats", handler->typeFormatRequests());
- cmd.arg("formats", handler->individualFormatRequests());
+ DebuggerCommand cmd("updateData");
+ cmd.arg("nativeMixed", isNativeMixedActive());
+ watchHandler()->appendFormatRequests(&cmd);
const static bool alwaysVerbose = !qgetenv("QTC_DEBUGGER_PYTHON_VERBOSE").isEmpty();
cmd.arg("passexceptions", alwaysVerbose);
@@ -900,7 +858,6 @@ void LldbEngine::doUpdateLocals(UpdateParameters params)
cmd.arg("autoderef", boolSetting(AutoDerefPointers));
cmd.arg("dyntype", boolSetting(UseDynamicType));
cmd.arg("partial", params.tryPartial);
- cmd.arg("tooltiponly", params.tooltipOnly);
cmd.beginList("watchers");
@@ -908,19 +865,19 @@ void LldbEngine::doUpdateLocals(UpdateParameters params)
QHashIterator<QByteArray, int> it(WatchHandler::watcherNames());
while (it.hasNext()) {
it.next();
- cmd.beginGroup()
- .arg("iname", "watch." + QByteArray::number(it.value()))
- .arg("exp", it.key().toHex())
- .endGroup();
+ cmd.beginGroup();
+ cmd.arg("iname", "watch." + QByteArray::number(it.value()));
+ cmd.arg("exp", it.key().toHex());
+ cmd.endGroup();
}
// Tooltips
DebuggerToolTipContexts toolTips = DebuggerToolTipManager::pendingTooltips(this);
foreach (const DebuggerToolTipContext &p, toolTips) {
- cmd.beginGroup()
- .arg("iname", p.iname)
- .arg("exp", p.expression.toLatin1().toHex())
- .endGroup();
+ cmd.beginGroup();
+ cmd.arg("iname", p.iname);
+ cmd.arg("exp", p.expression.toLatin1().toHex());
+ cmd.endGroup();
}
cmd.endList();
@@ -949,8 +906,7 @@ void LldbEngine::handleLldbError(QProcess::ProcessError error)
default:
//setState(EngineShutdownRequested, true);
m_lldbProc.kill();
- showMessageBox(QMessageBox::Critical, tr("LLDB I/O Error"),
- errorMessage(error));
+ AsynchronousMessageBox::critical(tr("LLDB I/O Error"), errorMessage(error));
break;
}
}
@@ -1016,29 +972,18 @@ void LldbEngine::refreshLocals(const GdbMi &vars)
//const bool partial = response.cookie.toBool();
WatchHandler *handler = watchHandler();
handler->resetValueCache();
- QList<WatchData> list;
- //if (!partial) {
- list.append(*handler->findData("local"));
- list.append(*handler->findData("watch"));
- list.append(*handler->findData("tooltip"));
- list.append(*handler->findData("return"));
- //}
+ QSet<QByteArray> toDelete;
+ foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(2))
+ toDelete.insert(item->d.iname);
foreach (const GdbMi &child, vars.children()) {
- WatchData dummy;
- dummy.iname = child["iname"].data();
- GdbMi wname = child["wname"];
- if (wname.isValid()) {
- // Happens (only) for watched expressions.
- dummy.exp = QByteArray::fromHex(wname.data());
- dummy.name = QString::fromUtf8(dummy.exp);
- } else {
- dummy.name = child["name"].toUtf8();
- }
- parseWatchData(handler->expandedINames(), dummy, child, &list);
+ WatchItem *item = new WatchItem(child);
+ handler->insertItem(item);
+ toDelete.remove(item->d.iname);
}
- handler->insertData(list);
+
+ handler->purgeOutdatedItems(toDelete);
DebuggerToolTipManager::updateEngine(this);
}
@@ -1055,7 +1000,17 @@ void LldbEngine::refreshStack(const GdbMi &stack)
frame.from = item["func"].toUtf8();
frame.line = item["line"].toInt();
frame.address = item["addr"].toAddress();
- frame.usable = QFileInfo(frame.file).isReadable();
+ GdbMi usable = item["usable"];
+ if (usable.isValid())
+ frame.usable = usable.data().toInt();
+ else
+ frame.usable = QFileInfo(frame.file).isReadable();
+ if (item["language"].data() == "js"
+ || frame.file.endsWith(QLatin1String(".js"))
+ || frame.file.endsWith(QLatin1String(".qml"))) {
+ frame.language = QmlLanguage;
+ frame.fixQmlFrame(startParameters());
+ }
frames.append(frame);
}
bool canExpand = stack["hasmore"].toInt();
@@ -1085,16 +1040,15 @@ void LldbEngine::setStackPosition(int index)
void LldbEngine::refreshRegisters(const GdbMi &registers)
{
RegisterHandler *handler = registerHandler();
- Registers regs;
foreach (const GdbMi &item, registers.children()) {
Register reg;
reg.name = item["name"].data();
reg.value = item["value"].data();
- //reg.type = item["type"].data();
- regs.append(reg);
+ reg.size = item["size"].data().toInt();
+ reg.reportedType = item["type"].data();
+ handler->updateRegister(reg);
}
- //handler->setRegisters(registers);
- handler->setAndMarkRegisters(regs);
+ handler->commitUpdates();
}
void LldbEngine::refreshThreads(const GdbMi &threads)
@@ -1205,7 +1159,7 @@ void LldbEngine::fetchDisassembler(DisassemblerAgent *agent)
m_disassemblerAgents.insert(p, id);
}
const Location &loc = agent->location();
- Command cmd("disassemble");
+ DebuggerCommand cmd("disassemble");
cmd.arg("cookie", id);
cmd.arg("address", loc.address());
cmd.arg("function", loc.functionName());
@@ -1227,7 +1181,7 @@ void LldbEngine::fetchMemory(MemoryAgent *agent, QObject *editorToken,
m_memoryAgents.insert(agent, id);
}
m_memoryAgentTokens.insert(id, editorToken);
- Command cmd("fetchMemory");
+ DebuggerCommand cmd("fetchMemory");
cmd.arg("address", addr);
cmd.arg("length", length);
cmd.arg("cookie", id);
@@ -1243,20 +1197,21 @@ void LldbEngine::changeMemory(MemoryAgent *agent, QObject *editorToken,
m_memoryAgents.insert(agent, id);
m_memoryAgentTokens.insert(id, editorToken);
}
- Command cmd("writeMemory");
+ DebuggerCommand cmd("writeMemory");
cmd.arg("address", addr);
cmd.arg("data", data.toHex());
cmd.arg("cookie", id);
runCommand(cmd);
}
-void LldbEngine::setRegisterValue(int regnr, const QString &value)
+void LldbEngine::setRegisterValue(const QByteArray &name, const QString &value)
{
- Register reg = registerHandler()->registers().at(regnr);
- runCommand(Command("setRegister").arg("name", reg.name).arg("value", value));
+ DebuggerCommand cmd("setRegister");
+ cmd.arg("name", name);
+ cmd.arg("value", value);
+ runCommand(cmd);
}
-
bool LldbEngine::hasCapability(unsigned cap) const
{
if (cap & (ReverseSteppingCapability
@@ -1308,132 +1263,13 @@ void LldbEngine::notifyEngineRemoteSetupFinished(const RemoteSetupResult &result
showMessage(_("ADAPTER START FAILED"));
if (!result.reason.isEmpty()) {
const QString title = tr("Adapter start failed");
- Core::ICore::showWarningWithOptions(title, result.reason);
+ ICore::showWarningWithOptions(title, result.reason);
}
notifyEngineSetupFailed();
return;
}
}
-///////////////////////////////////////////////////////////////////////
-//
-// Command
-//
-///////////////////////////////////////////////////////////////////////
-
-const LldbEngine::Command &LldbEngine::Command::argHelper(const char *name, const QByteArray &data) const
-{
- args.append('"');
- args.append(name);
- args.append("\":");
- args.append(data);
- args.append(",");
- return *this;
-}
-
-QByteArray LldbEngine::Command::toData(const QList<QByteArray> &value)
-{
- QByteArray res;
- foreach (const QByteArray &item, value) {
- if (!res.isEmpty())
- res.append(',');
- res += item;
- }
- return '[' + res + ']';
-}
-
-QByteArray LldbEngine::Command::toData(const QHash<QByteArray, QByteArray> &value)
-{
- QByteArray res;
- QHashIterator<QByteArray, QByteArray> it(value);
- while (it.hasNext()) {
- it.next();
- if (!res.isEmpty())
- res.append(',');
- res += '"' + it.key() + "\":" + it.value();
- }
- return '{' + res + '}';
-}
-
-const LldbEngine::Command &LldbEngine::Command::arg(const char *name, int value) const
-{
- return argHelper(name, QByteArray::number(value));
-}
-
-const LldbEngine::Command &LldbEngine::Command::arg(const char *name, qlonglong value) const
-{
- return argHelper(name, QByteArray::number(value));
-}
-
-const LldbEngine::Command &LldbEngine::Command::arg(const char *name, qulonglong value) const
-{
- return argHelper(name, QByteArray::number(value));
-}
-
-const LldbEngine::Command &LldbEngine::Command::arg(const char *name, const QString &value) const
-{
- return arg(name, value.toUtf8().data());
-}
-
-const LldbEngine::Command &LldbEngine::Command::arg(const char *name, const QByteArray &value) const
-{
- return arg(name, value.data());
-}
-
-const LldbEngine::Command &LldbEngine::Command::arg(const char *name, const char *value) const
-{
- args.append('"');
- args.append(name);
- args.append("\":\"");
- args.append(value);
- args.append("\",");
- return *this;
-}
-
-const LldbEngine::Command &LldbEngine::Command::arg(const char *value) const
-{
- args.append("\"");
- args.append(value);
- args.append("\",");
- return *this;
-}
-
-const LldbEngine::Command &LldbEngine::Command::beginList(const char *name) const
-{
- if (name) {
- args += '"';
- args += name;
- args += "\":";
- }
- args += '[';
- return *this;
-}
-
-void LldbEngine::Command::endList() const
-{
- if (args.endsWith(','))
- args.chop(1);
- args += "],";
-}
-
-const LldbEngine::Command &LldbEngine::Command::beginGroup(const char *name) const
-{
- if (name) {
- args += '"';
- args += name;
- args += "\":";
- }
- args += '{';
- return *this;
-}
-
-void LldbEngine::Command::endGroup() const
-{
- if (args.endsWith(','))
- args.chop(1);
- args += "},";
-}
-
void LldbEngine::stubStarted()
{
startLldb();
@@ -1441,7 +1277,7 @@ void LldbEngine::stubStarted()
void LldbEngine::stubError(const QString &msg)
{
- showMessageBox(QMessageBox::Critical, tr("Debugger Error"), msg);
+ AsynchronousMessageBox::critical(tr("Debugger Error"), msg);
}
void LldbEngine::stubExited()
diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h
index cb209a79cf..02fef25d6e 100644
--- a/src/plugins/debugger/lldb/lldbengine.h
+++ b/src/plugins/debugger/lldb/lldbengine.h
@@ -66,33 +66,6 @@ public:
~LldbEngine();
private:
- // Convenience struct to build up backend commands.
- struct Command
- {
- Command() {}
- Command(const char *f) : function(f) {}
-
- const Command &arg(const char *name) const;
- const Command &arg(const char *name, int value) const;
- const Command &arg(const char *name, qlonglong value) const;
- const Command &arg(const char *name, qulonglong value) const;
- const Command &arg(const char *name, const QString &value) const;
- const Command &arg(const char *name, const QByteArray &value) const;
- const Command &arg(const char *name, const char *value) const;
- const Command &beginList(const char *name = 0) const;
- void endList() const;
- const Command &beginGroup(const char *name = 0) const;
- void endGroup() const;
-
- static QByteArray toData(const QList<QByteArray> &value);
- static QByteArray toData(const QHash<QByteArray, QByteArray> &value);
-
- QByteArray function;
- mutable QByteArray args;
- private:
- const Command &argHelper(const char *name, const QByteArray &value) const;
- };
-
// DebuggerEngine implementation
void executeStep();
void executeStepOut();
@@ -122,9 +95,12 @@ private:
void activateFrame(int index);
void selectThread(ThreadId threadId);
- bool acceptsBreakpoint(BreakpointModelId id) const;
- void attemptBreakpointSynchronization();
- bool attemptBreakpointSynchronizationHelper(Command *command);
+ // This should be always the last call in a function.
+ bool stateAcceptsBreakpointChanges() const;
+ bool acceptsBreakpoint(Breakpoint bp) const;
+ void insertBreakpoint(Breakpoint bp);
+ void removeBreakpoint(Breakpoint bp);
+ void changeBreakpoint(Breakpoint bp);
void assignValueInDebugger(const WatchData *data,
const QString &expr, const QVariant &value);
@@ -143,7 +119,7 @@ private:
bool supportsThreads() const { return true; }
bool isSynchronous() const { return true; }
void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
- void setRegisterValue(int regnr, const QString &value);
+ void setRegisterValue(const QByteArray &name, const QString &value);
void fetchMemory(Internal::MemoryAgent *, QObject *, quint64 addr, quint64 length);
void changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data);
@@ -161,7 +137,6 @@ private:
Q_SLOT void readLldbStandardOutput();
Q_SLOT void readLldbStandardError();
Q_SLOT void handleResponse(const QByteArray &data);
- Q_SLOT void runEngine2();
Q_SLOT void updateAll();
Q_SLOT void updateStack();
Q_SLOT void updateLocals();
@@ -184,7 +159,6 @@ private:
void refreshAddedBreakpoint(const GdbMi &bkpts);
void refreshChangedBreakpoint(const GdbMi &bkpts);
void refreshRemovedBreakpoint(const GdbMi &bkpts);
- void runContinuation(const GdbMi &data);
void showFullBacktrace(const GdbMi &data);
typedef void (LldbEngine::*LldbCommandContinuation)();
@@ -202,9 +176,9 @@ private:
void handleChildren(const WatchData &data0, const GdbMi &item,
QList<WatchData> *list);
- void runCommand(const Command &cmd);
+ void runCommand(const DebuggerCommand &cmd);
void debugLastCommand();
- Command m_lastDebuggableCommand;
+ DebuggerCommand m_lastDebuggableCommand;
QByteArray m_inbuffer;
QString m_scriptFileName;
diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp
index d6188aba55..e2b8063a43 100644
--- a/src/plugins/debugger/loadcoredialog.cpp
+++ b/src/plugins/debugger/loadcoredialog.cpp
@@ -82,14 +82,13 @@ public:
QString localFile() const { return m_localFile; }
QString remoteFile() const { return m_remoteFile; }
-private slots:
- void handleSftpOperationFinished(QSsh::SftpJobId, const QString &error);
+private:
+ void handleSftpOperationFinished(SftpJobId, const QString &error);
void handleSftpOperationFailed(const QString &errorMessage);
void handleConnectionError(const QString &errorMessage);
void handleRemoteError(const QString &errorMessage);
void selectFile();
-private:
QSortFilterProxyModel m_model;
SftpFileSystemModel m_fileSystemModel;
QTreeView *m_fileSystemView;
@@ -128,13 +127,15 @@ SelectRemoteFileDialog::SelectRemoteFileDialog(QWidget *parent)
layout->addWidget(m_textBrowser);
layout->addWidget(m_buttonBox);
- QObject::connect(m_buttonBox, SIGNAL(rejected()), SLOT(reject()));
- QObject::connect(m_buttonBox, SIGNAL(accepted()), SLOT(selectFile()));
+ connect(m_buttonBox, &QDialogButtonBox::rejected,
+ this, &QDialog::reject);
+ connect(m_buttonBox, &QDialogButtonBox::accepted,
+ this, &SelectRemoteFileDialog::selectFile);
- connect(&m_fileSystemModel, SIGNAL(sftpOperationFailed(QString)),
- SLOT(handleSftpOperationFailed(QString)));
- connect(&m_fileSystemModel, SIGNAL(connectionError(QString)),
- SLOT(handleConnectionError(QString)));
+ connect(&m_fileSystemModel, &SftpFileSystemModel::sftpOperationFailed,
+ this, &SelectRemoteFileDialog::handleSftpOperationFailed);
+ connect(&m_fileSystemModel, &SftpFileSystemModel::connectionError,
+ this, &SelectRemoteFileDialog::handleConnectionError);
}
void SelectRemoteFileDialog::attachToDevice(Kit *k)
@@ -143,7 +144,7 @@ void SelectRemoteFileDialog::attachToDevice(Kit *k)
QTC_ASSERT(k, return);
IDevice::ConstPtr device = DeviceKitInformation::device(k);
QTC_ASSERT(device, return);
- QSsh::SshConnectionParameters sshParams = device->sshParameters();
+ SshConnectionParameters sshParams = device->sshParameters();
m_fileSystemModel.setSshConnection(sshParams);
}
@@ -159,7 +160,7 @@ void SelectRemoteFileDialog::handleConnectionError(const QString &errorMessage)
//reject();
}
-void SelectRemoteFileDialog::handleSftpOperationFinished(QSsh::SftpJobId, const QString &error)
+void SelectRemoteFileDialog::handleSftpOperationFinished(SftpJobId, const QString &error)
{
if (error.isEmpty()) {
m_textBrowser->append(tr("Download of remote file succeeded."));
@@ -184,8 +185,8 @@ void SelectRemoteFileDialog::selectFile()
m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
m_fileSystemView->setEnabled(false);
- connect(&m_fileSystemModel, SIGNAL(sftpOperationFinished(QSsh::SftpJobId,QString)),
- SLOT(handleSftpOperationFinished(QSsh::SftpJobId,QString)));
+ connect(&m_fileSystemModel, &SftpFileSystemModel::sftpOperationFinished,
+ this, &SelectRemoteFileDialog::handleSftpOperationFinished);
{
QTemporaryFile localFile(QDir::tempPath() + QLatin1String("/remotecore-XXXXXX"));
@@ -271,7 +272,7 @@ AttachCoreDialog::AttachCoreDialog(QWidget *parent)
d->forceLocalLabel->setBuddy(d->forceLocalCheckBox);
d->remoteCoreFileName = new QLineEdit(this);
- d->selectRemoteCoreButton = new QPushButton(tr("Browse..."), this);
+ d->selectRemoteCoreButton = new QPushButton(PathChooser::browseButtonLabel(), this);
d->localCoreFileName = new PathChooser(this);
d->localCoreFileName->setHistoryCompleter(QLatin1String("Debugger.CoreFile.History"));
@@ -323,14 +324,14 @@ AttachCoreDialog::~AttachCoreDialog()
int AttachCoreDialog::exec()
{
- connect(d->selectRemoteCoreButton, SIGNAL(clicked()), SLOT(selectRemoteCoreFile()));
- connect(d->remoteCoreFileName, SIGNAL(textChanged(QString)), SLOT(coreFileChanged(QString)));
- connect(d->localExecFileName, SIGNAL(changed(QString)), SLOT(changed()));
- connect(d->localCoreFileName, SIGNAL(changed(QString)), SLOT(coreFileChanged(QString)));
- connect(d->forceLocalCheckBox, SIGNAL(stateChanged(int)), SLOT(changed()));
- connect(d->kitChooser, SIGNAL(currentIndexChanged(int)), SLOT(changed()));
- connect(d->buttonBox, SIGNAL(rejected()), SLOT(reject()));
- connect(d->buttonBox, SIGNAL(accepted()), SLOT(accept()));
+ connect(d->selectRemoteCoreButton, &QAbstractButton::clicked, this, &AttachCoreDialog::selectRemoteCoreFile);
+ connect(d->remoteCoreFileName, &QLineEdit::textChanged, this, &AttachCoreDialog::coreFileChanged);
+ connect(d->localExecFileName, &PathChooser::changed, this, &AttachCoreDialog::changed);
+ connect(d->localCoreFileName, &PathChooser::changed, this, &AttachCoreDialog::coreFileChanged);
+ connect(d->forceLocalCheckBox, &QCheckBox::stateChanged, this, &AttachCoreDialog::changed);
+ connect(d->kitChooser, &KitChooser::currentIndexChanged, this, &AttachCoreDialog::changed);
+ connect(d->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+ connect(d->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
changed();
AttachCoreDialogPrivate::State st = d->getDialogState(*this);
@@ -364,7 +365,7 @@ bool AttachCoreDialog::useLocalCoreFile() const
void AttachCoreDialog::coreFileChanged(const QString &core)
{
- if (!Utils::HostOsInfo::isWindowsHost() && QFile::exists(core)) {
+ if (!HostOsInfo::isWindowsHost() && QFile::exists(core)) {
Kit *k = d->kitChooser->currentKit();
QTC_ASSERT(k, return);
FileName cmd = DebuggerKitInformation::debuggerCommand(k);
@@ -441,7 +442,7 @@ QString AttachCoreDialog::remoteCoreFile() const
return d->remoteCoreFileName->text();
}
-void AttachCoreDialog::setKitId(Core::Id id)
+void AttachCoreDialog::setKitId(Id id)
{
d->kitChooser->setCurrentKitId(id);
}
diff --git a/src/plugins/debugger/logwindow.cpp b/src/plugins/debugger/logwindow.cpp
index c40b091ec2..3c233dcc5d 100644
--- a/src/plugins/debugger/logwindow.cpp
+++ b/src/plugins/debugger/logwindow.cpp
@@ -145,27 +145,27 @@ class DebuggerPane : public QPlainTextEdit
Q_OBJECT
public:
- DebuggerPane(QWidget *parent)
+ DebuggerPane(LogWindow *parent)
: QPlainTextEdit(parent)
{
setFrameStyle(QFrame::NoFrame);
m_clearContentsAction = new QAction(this);
m_clearContentsAction->setText(tr("Clear Contents"));
m_clearContentsAction->setEnabled(true);
- connect(m_clearContentsAction, SIGNAL(triggered(bool)),
- parent, SLOT(clearContents()));
+ connect(m_clearContentsAction, &QAction::triggered,
+ parent, &LogWindow::clearContents);
m_saveContentsAction = new QAction(this);
m_saveContentsAction->setText(tr("Save Contents"));
m_saveContentsAction->setEnabled(true);
- connect(m_saveContentsAction, SIGNAL(triggered()),
- this, SLOT(saveContents()));
+ connect(m_saveContentsAction, &QAction::triggered,
+ this, &DebuggerPane::saveContents);
m_reloadDebuggingHelpersAction = new QAction(this);
m_reloadDebuggingHelpersAction->setText(tr("Reload Debugging Helpers"));
m_reloadDebuggingHelpersAction->setEnabled(true);
- connect(m_reloadDebuggingHelpersAction, SIGNAL(triggered()),
- this, SLOT(reloadDebuggingHelpers()));
+ connect(m_reloadDebuggingHelpersAction, &QAction::triggered,
+ this, &DebuggerPane::reloadDebuggingHelpers);
}
void contextMenuEvent(QContextMenuEvent *ev)
@@ -209,11 +209,10 @@ public:
setUndoRedoEnabled(true);
}
-private slots:
+private:
void saveContents();
void reloadDebuggingHelpers();
-private:
QAction *m_clearContentsAction;
QAction *m_saveContentsAction;
QAction *m_reloadDebuggingHelpersAction;
@@ -239,7 +238,7 @@ class InputPane : public DebuggerPane
{
Q_OBJECT
public:
- InputPane(QWidget *parent)
+ InputPane(LogWindow *parent)
: DebuggerPane(parent)
{
(void) new InputHighlighter(this);
@@ -305,7 +304,7 @@ class CombinedPane : public DebuggerPane
{
Q_OBJECT
public:
- CombinedPane(QWidget *parent)
+ CombinedPane(LogWindow *parent)
: DebuggerPane(parent)
{
(void) new OutputHighlighter(this);
@@ -354,7 +353,7 @@ LogWindow::LogWindow(QWidget *parent)
m_ignoreNextInputEcho = false;
- QSplitter *m_splitter = new Core::MiniSplitter(Qt::Horizontal);
+ auto m_splitter = new Core::MiniSplitter(Qt::Horizontal);
m_splitter->setParent(this);
// Mixed input/output.
@@ -374,25 +373,25 @@ LogWindow::LogWindow(QWidget *parent)
m_commandEdit->setFrame(false);
m_commandEdit->setHistoryCompleter(QLatin1String("DebuggerInput"));
- QToolButton *repeatButton = new QToolButton(this);
+ auto repeatButton = new QToolButton(this);
repeatButton->setIcon(QIcon(QLatin1String(":/debugger/images/debugger_stepover_small.png")));
repeatButton->setIconSize(QSize(12, 12));
repeatButton->setToolTip(tr("Repeat last command for debug reasons."));
- QHBoxLayout *commandBox = new QHBoxLayout;
+ auto commandBox = new QHBoxLayout;
commandBox->addWidget(repeatButton);
commandBox->addWidget(new QLabel(tr("Command:"), this));
commandBox->addWidget(m_commandEdit);
commandBox->setMargin(2);
commandBox->setSpacing(6);
- QVBoxLayout *leftBox = new QVBoxLayout;
+ auto leftBox = new QVBoxLayout;
leftBox->addWidget(m_inputText);
leftBox->addItem(commandBox);
leftBox->setMargin(0);
leftBox->setSpacing(0);
- QWidget *leftDummy = new QWidget;
+ auto leftDummy = new QWidget;
leftDummy->setLayout(leftBox);
m_splitter->addWidget(leftDummy);
@@ -400,14 +399,14 @@ LogWindow::LogWindow(QWidget *parent)
m_splitter->setStretchFactor(0, 1);
m_splitter->setStretchFactor(1, 3);
- QVBoxLayout *layout = new QVBoxLayout(this);
+ auto layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(m_splitter);
layout->addWidget(new Core::FindToolBarPlaceHolder(this));
setLayout(layout);
- Aggregation::Aggregate *aggregate = new Aggregation::Aggregate;
+ auto aggregate = new Aggregation::Aggregate;
aggregate->add(m_combinedText);
aggregate->add(new Core::BaseTextFind(m_combinedText));
@@ -419,14 +418,15 @@ LogWindow::LogWindow(QWidget *parent)
SIGNAL(statusMessageRequested(QString,int)));
connect(m_inputText, SIGNAL(commandSelected(int)),
m_combinedText, SLOT(gotoResult(int)));
- connect(m_commandEdit, SIGNAL(returnPressed()),
- SLOT(sendCommand()));
+ connect(m_commandEdit, &QLineEdit::returnPressed,
+ this, &LogWindow::sendCommand);
connect(m_inputText, SIGNAL(executeLineRequested()),
SLOT(executeLine()));
- connect(repeatButton, SIGNAL(clicked()),
- SLOT(repeatLastCommand()));
+ connect(repeatButton, &QAbstractButton::clicked,
+ this, &LogWindow::repeatLastCommand);
- connect(&m_outputTimer, SIGNAL(timeout()), SLOT(doOutput()));
+ connect(&m_outputTimer, &QTimer::timeout,
+ this, &LogWindow::doOutput);
setMinimumHeight(60);
}
diff --git a/src/plugins/debugger/memoryagent.cpp b/src/plugins/debugger/memoryagent.cpp
index 4eede82072..18835e2363 100644
--- a/src/plugins/debugger/memoryagent.cpp
+++ b/src/plugins/debugger/memoryagent.cpp
@@ -40,13 +40,12 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/messagebox.h>
#include <utils/qtcassert.h>
#include <extensionsystem/pluginmanager.h>
#include <extensionsystem/invoker.h>
-#include <QMessageBox>
-
#include <cstring>
using namespace Core;
@@ -136,15 +135,12 @@ void MemoryAgent::connectBinEditorWidget(QWidget *w)
connect(w, SIGNAL(addWatchpointRequested(quint64,uint)), SLOT(handleWatchpointRequest(quint64,uint)));
}
-bool MemoryAgent::doCreateBinEditor(quint64 addr, unsigned flags,
- const QList<MemoryMarkup> &ml, const QPoint &pos,
- QString title, QWidget *parent)
+bool MemoryAgent::doCreateBinEditor(const MemoryViewSetupData &data)
{
- const bool readOnly = (flags & DebuggerEngine::MemoryReadOnly) != 0;
- if (title.isEmpty())
- title = tr("Memory at 0x%1").arg(addr, 0, 16);
+ const bool readOnly = (data.flags & DebuggerEngine::MemoryReadOnly) != 0;
+ QString title = data.title.isEmpty() ? tr("Memory at 0x%1").arg(data.startAddress, 0, 16) : data.title;
// Separate view?
- if (flags & DebuggerEngine::MemoryView) {
+ if (data.flags & DebuggerEngine::MemoryView) {
// Ask BIN editor plugin for factory service and have it create a bin editor widget.
QWidget *binEditor = 0;
if (QObject *factory = ExtensionSystem::PluginManager::getObjectByClassName(QLatin1String("BinEditor::BinEditorWidgetFactory")))
@@ -156,24 +152,22 @@ bool MemoryAgent::doCreateBinEditor(quint64 addr, unsigned flags,
MemoryView::setBinEditorNewWindowRequestAllowed(binEditor, true);
MemoryView *topLevel = 0;
// Memory view tracking register value, providing its own updating mechanism.
- if (flags & DebuggerEngine::MemoryTrackRegister) {
- RegisterMemoryView *rmv = new RegisterMemoryView(binEditor, parent);
- rmv->init(m_engine->registerHandler(), int(addr));
- topLevel = rmv;
+ if (data.flags & DebuggerEngine::MemoryTrackRegister) {
+ topLevel = new RegisterMemoryView(binEditor, data.startAddress, data.registerName, m_engine->registerHandler(), data.parent);
} else {
// Ordinary memory view
- MemoryView::setBinEditorMarkup(binEditor, ml);
- MemoryView::setBinEditorRange(binEditor, addr, MemoryAgent::DataRange, MemoryAgent::BinBlockSize);
- topLevel = new MemoryView(binEditor, parent);
+ MemoryView::setBinEditorMarkup(binEditor, data.markup);
+ MemoryView::setBinEditorRange(binEditor, data.startAddress, MemoryAgent::DataRange, MemoryAgent::BinBlockSize);
+ topLevel = new MemoryView(binEditor, data.parent);
topLevel->setWindowTitle(title);
}
m_views << topLevel;
- topLevel->move(pos);
+ topLevel->move(data.pos);
topLevel->show();
return true;
}
// Editor: Register tracking not supported.
- QTC_ASSERT(!(flags & DebuggerEngine::MemoryTrackRegister), return false);
+ QTC_ASSERT(!(data.flags & DebuggerEngine::MemoryTrackRegister), return false);
if (!title.endsWith(QLatin1Char('$')))
title.append(QLatin1String(" $"));
IEditor *editor = EditorManager::openEditorWithContents(
@@ -186,18 +180,16 @@ bool MemoryAgent::doCreateBinEditor(quint64 addr, unsigned flags,
connectBinEditorWidget(editorBinEditor);
MemoryView::setBinEditorReadOnly(editorBinEditor, readOnly);
MemoryView::setBinEditorNewWindowRequestAllowed(editorBinEditor, true);
- MemoryView::setBinEditorRange(editorBinEditor, addr, MemoryAgent::DataRange, MemoryAgent::BinBlockSize);
- MemoryView::setBinEditorMarkup(editorBinEditor, ml);
+ MemoryView::setBinEditorRange(editorBinEditor, data.startAddress, MemoryAgent::DataRange, MemoryAgent::BinBlockSize);
+ MemoryView::setBinEditorMarkup(editorBinEditor, data.markup);
m_editors << editor;
return true;
}
-void MemoryAgent::createBinEditor(quint64 addr, unsigned flags,
- const QList<MemoryMarkup> &ml, const QPoint &pos,
- const QString &title, QWidget *parent)
+void MemoryAgent::createBinEditor(const MemoryViewSetupData &data)
{
- if (!doCreateBinEditor(addr, flags, ml, pos, title, parent))
- showMessageBox(QMessageBox::Warning,
+ if (!doCreateBinEditor(data))
+ AsynchronousMessageBox::warning(
tr("No Memory Viewer Available"),
tr("The memory contents cannot be shown as no viewer plugin "
"for binary data has been loaded."));
@@ -205,7 +197,9 @@ void MemoryAgent::createBinEditor(quint64 addr, unsigned flags,
void MemoryAgent::createBinEditor(quint64 addr)
{
- createBinEditor(addr, 0, QList<MemoryMarkup>(), QPoint(), QString(), 0);
+ MemoryViewSetupData data;
+ data.startAddress = addr;
+ createBinEditor(data);
}
void MemoryAgent::fetchLazyData(quint64 block)
@@ -240,7 +234,7 @@ void MemoryAgent::handleWatchpointRequest(quint64 address, uint size)
void MemoryAgent::updateContents()
{
- foreach (const QPointer<Core::IEditor> &e, m_editors)
+ foreach (const QPointer<IEditor> &e, m_editors)
if (e)
MemoryView::binEditorUpdateContents(e->widget());
// Update all views except register views, which trigger on
diff --git a/src/plugins/debugger/memoryagent.h b/src/plugins/debugger/memoryagent.h
index 5967c38c2b..33386f126e 100644
--- a/src/plugins/debugger/memoryagent.h
+++ b/src/plugins/debugger/memoryagent.h
@@ -34,21 +34,20 @@
#include "debuggerconstants.h"
#include <QObject>
+#include <QPoint>
#include <QPointer>
#include <QColor>
-QT_FORWARD_DECLARE_CLASS(QPoint)
-
namespace Core { class IEditor; }
namespace ProjectExplorer { class Abi; }
namespace Debugger {
+namespace Internal {
class DebuggerEngine;
-
-namespace Internal {
class MemoryView;
+
class MemoryMarkup
{
public:
@@ -62,6 +61,20 @@ public:
QString toolTip;
};
+class MemoryViewSetupData
+{
+public:
+ MemoryViewSetupData() : parent(0), startAddress(0), flags(0) {}
+
+ QWidget *parent;
+ quint64 startAddress;
+ QByteArray registerName;
+ unsigned flags;
+ QList<Internal::MemoryMarkup> markup;
+ QPoint pos;
+ QString title;
+};
+
class MemoryAgent : public QObject
{
Q_OBJECT
@@ -80,9 +93,7 @@ public:
public slots:
// Called by engine to create a new view.
- void createBinEditor(quint64 startAddr, unsigned flags,
- const QList<MemoryMarkup> &ml, const QPoint &pos,
- const QString &title, QWidget *parent);
+ void createBinEditor(const MemoryViewSetupData &data);
void createBinEditor(quint64 startAddr);
// Called by engine to create a tooltip.
void addLazyData(QObject *editorToken, quint64 addr, const QByteArray &data);
@@ -101,9 +112,7 @@ private slots:
private:
void connectBinEditorWidget(QWidget *w);
- bool doCreateBinEditor(quint64 startAddr, unsigned flags,
- const QList<MemoryMarkup> &ml, const QPoint &pos,
- QString title, QWidget *parent);
+ bool doCreateBinEditor(const MemoryViewSetupData &data);
QList<QPointer<Core::IEditor> > m_editors;
QList<QPointer<MemoryView> > m_views;
diff --git a/src/plugins/debugger/memoryview.cpp b/src/plugins/debugger/memoryview.cpp
index aefb1e469d..a7850668b0 100644
--- a/src/plugins/debugger/memoryview.cpp
+++ b/src/plugins/debugger/memoryview.cpp
@@ -138,24 +138,27 @@ void MemoryView::setMarkup(const QList<MemoryMarkup> &m)
\sa Debugger::Internal::MemoryAgent, Debugger::DebuggerEngine
*/
-RegisterMemoryView::RegisterMemoryView(QWidget *binEditor, QWidget *parent) :
+RegisterMemoryView::RegisterMemoryView(QWidget *binEditor, quint64 addr,
+ const QByteArray &regName,
+ RegisterHandler *handler, QWidget *parent) :
MemoryView(binEditor, parent),
- m_registerIndex(0), m_registerAddress(0)
+ m_registerName(regName), m_registerAddress(addr)
{
+ connect(handler, &QAbstractItemModel::modelReset, this, &QWidget::close);
+ connect(handler, &RegisterHandler::registerChanged, this, &RegisterMemoryView::onRegisterChanged);
+ updateContents();
}
-void RegisterMemoryView::slotRegisterSet(const QModelIndex &index)
+void RegisterMemoryView::onRegisterChanged(const QByteArray &name, quint64 value)
{
- if (m_registerIndex != index.row())
- return;
- const QVariant newAddressV = index.data(Qt::EditRole);
- if (newAddressV.type() == QVariant::ULongLong)
- setRegisterAddress(newAddressV.toULongLong());
+ if (name == m_registerName)
+ setRegisterAddress(value);
}
-QString RegisterMemoryView::title(const QString &registerName, quint64 a)
+QString RegisterMemoryView::title(const QByteArray &registerName, quint64 a)
{
- return tr("Memory at Register \"%1\" (0x%2)").arg(registerName).arg(a, 0, 16);
+ return tr("Memory at Register \"%1\" (0x%2)")
+ .arg(QString::fromUtf8(registerName)).arg(a, 0, 16);
}
void RegisterMemoryView::setRegisterAddress(quint64 v)
@@ -171,25 +174,13 @@ void RegisterMemoryView::setRegisterAddress(quint64 v)
setMarkup(registerMarkup(v, m_registerName));
}
-QList<MemoryMarkup> RegisterMemoryView::registerMarkup(quint64 a, const QString &name)
+QList<MemoryMarkup> RegisterMemoryView::registerMarkup(quint64 a, const QByteArray &regName)
{
QList<MemoryMarkup> result;
result.push_back(MemoryMarkup(a, 1, QColor(Qt::blue).lighter(),
- tr("Register \"%1\"").arg(name)));
+ tr("Register \"%1\"").arg(QString::fromUtf8(regName))));
return result;
}
-void RegisterMemoryView::init(RegisterHandler *h, int registerIndex)
-{
- m_registerIndex = registerIndex;
- m_registerName = QString::fromLatin1(h->registerAt(registerIndex).name);
- // Known issue: CDB might reset the model by changing the special
- // registers it reports.
- connect(h, SIGNAL(modelReset()), this, SLOT(close()));
- connect(h, SIGNAL(registerSet(QModelIndex)),
- this, SLOT(slotRegisterSet(QModelIndex)));
- setRegisterAddress(h->registerAt(m_registerIndex).editValue().toULongLong());
-}
-
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/memoryview.h b/src/plugins/debugger/memoryview.h
index a88d6742d4..aa81540ecb 100644
--- a/src/plugins/debugger/memoryview.h
+++ b/src/plugins/debugger/memoryview.h
@@ -69,21 +69,17 @@ class RegisterMemoryView : public MemoryView
{
Q_OBJECT
public:
- explicit RegisterMemoryView(QWidget *binEditor, QWidget *parent = 0);
+ explicit RegisterMemoryView(QWidget *binEditor, quint64 addr, const QByteArray &regName,
+ RegisterHandler *rh, QWidget *parent = 0);
- void init(RegisterHandler *rh, int index);
-
- static QList<MemoryMarkup> registerMarkup(quint64 a, const QString &name);
- static QString title(const QString &registerName, quint64 a = 0);
-
-private slots:
- void slotRegisterSet(const QModelIndex &index);
+ static QList<MemoryMarkup> registerMarkup(quint64 a, const QByteArray &regName);
+ static QString title(const QByteArray &registerName, quint64 a = 0);
private:
+ void onRegisterChanged(const QByteArray &name, quint64 value);
void setRegisterAddress(quint64 v);
- int m_registerIndex;
- QString m_registerName;
+ QByteArray m_registerName;
quint64 m_registerAddress;
};
diff --git a/src/plugins/debugger/moduleshandler.cpp b/src/plugins/debugger/moduleshandler.cpp
index f404d561f3..3e793a424b 100644
--- a/src/plugins/debugger/moduleshandler.cpp
+++ b/src/plugins/debugger/moduleshandler.cpp
@@ -31,7 +31,9 @@
#include "moduleshandler.h"
#include <utils/qtcassert.h>
+#include <utils/treemodel.h>
+#include <QCoreApplication>
#include <QDebug>
#include <QSortFilterProxyModel>
@@ -46,211 +48,109 @@ using namespace Utils;
namespace Debugger {
namespace Internal {
-class ModulesModel : public QAbstractItemModel
+class ModuleItem : public TreeItem
{
public:
- explicit ModulesModel(QObject *parent)
- : QAbstractItemModel(parent)
- {}
+ QVariant data(int column, int role) const;
- int columnCount(const QModelIndex &parent) const
- { return parent.isValid() ? 0 : 5; }
- int rowCount(const QModelIndex &parent) const
- { return parent.isValid() ? 0 : m_modules.size(); }
- QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
- QModelIndex index(int row, int column, const QModelIndex &) const
- { return createIndex(row, column); }
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- QVariant data(const QModelIndex &index, int role) const;
-
- void clearModel();
- void removeModule(const QString &modulePath);
- void setModules(const Modules &modules);
- void updateModule(const Module &module);
-
- int indexOfModule(const QString &modulePath) const;
-
- Modules m_modules;
+public:
+ Module module;
+ bool updated;
};
-
-QVariant ModulesModel::headerData(int section,
- Qt::Orientation orientation, int role) const
+QVariant ModuleItem::data(int column, int role) const
{
- if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
- static QString headers[] = {
- ModulesHandler::tr("Module Name") + QLatin1String(" "),
- ModulesHandler::tr("Module Path") + QLatin1String(" "),
- ModulesHandler::tr("Symbols Read") + QLatin1String(" "),
- ModulesHandler::tr("Symbols Type") + QLatin1String(" "),
- ModulesHandler::tr("Start Address") + QLatin1String(" "),
- ModulesHandler::tr("End Address") + QLatin1String(" ")
- };
- return headers[section];
- }
- return QVariant();
-}
-
-QVariant ModulesModel::data(const QModelIndex &index, int role) const
-{
- int row = index.row();
- if (row < 0 || row >= m_modules.size())
- return QVariant();
-
- const Module &module = m_modules.at(row);
-
- switch (index.column()) {
- case 0:
- if (role == Qt::DisplayRole)
- return module.moduleName;
- // FIXME: add icons
- //if (role == Qt::DecorationRole)
- // return module.symbolsRead ? icon2 : icon;
- break;
- case 1:
- if (role == Qt::DisplayRole)
- return module.modulePath;
- if (role == Qt::ToolTipRole) {
- QString msg;
- if (!module.elfData.buildId.isEmpty())
- msg += QString::fromLatin1("Build Id: " + module.elfData.buildId);
- if (!module.elfData.debugLink.isEmpty())
- msg += QString::fromLatin1("Debug Link: " + module.elfData.debugLink);
- return msg;
+ switch (column) {
+ case 0:
+ if (role == Qt::DisplayRole)
+ return module.moduleName;
+ // FIXME: add icons
+ //if (role == Qt::DecorationRole)
+ // return module.symbolsRead ? icon2 : icon;
+ break;
+ case 1:
+ if (role == Qt::DisplayRole)
+ return module.modulePath;
+ if (role == Qt::ToolTipRole) {
+ QString msg;
+ if (!module.elfData.buildId.isEmpty())
+ msg += QString::fromLatin1("Build Id: " + module.elfData.buildId);
+ if (!module.elfData.debugLink.isEmpty())
+ msg += QString::fromLatin1("Debug Link: " + module.elfData.debugLink);
+ return msg;
+ }
+ break;
+ case 2:
+ if (role == Qt::DisplayRole)
+ switch (module.symbolsRead) {
+ case Module::UnknownReadState: return ModulesHandler::tr("Unknown");
+ case Module::ReadFailed: return ModulesHandler::tr("No");
+ case Module::ReadOk: return ModulesHandler::tr("Yes");
}
- break;
- case 2:
- if (role == Qt::DisplayRole)
- switch (module.symbolsRead) {
- case Module::UnknownReadState: return ModulesHandler::tr("Unknown");
- case Module::ReadFailed: return ModulesHandler::tr("No");
- case Module::ReadOk: return ModulesHandler::tr("Yes");
- }
- break;
- case 3:
- if (role == Qt::DisplayRole)
- switch (module.elfData.symbolsType) {
- case UnknownSymbols:
- return ModulesHandler::tr("Unknown");
- case NoSymbols:
- return ModulesHandler::tr("None");
- case PlainSymbols:
- return ModulesHandler::tr("Plain");
- case FastSymbols:
- return ModulesHandler::tr("Fast");
- case LinkedSymbols:
- return ModulesHandler::tr("debuglnk");
- case BuildIdSymbols:
- return ModulesHandler::tr("buildid");
- }
- else if (role == Qt::ToolTipRole)
- switch (module.elfData.symbolsType) {
- case UnknownSymbols:
- return ModulesHandler::tr(
- "It is unknown whether this module contains debug "
- "information.\nUse \"Examine Symbols\" from the "
- "context menu to initiate a check.");
- case NoSymbols:
- return ModulesHandler::tr(
- "This module neither contains nor references debug "
- "information.\nStepping into the module or setting "
- "breakpoints by file and line will not work.");
- case PlainSymbols:
- return ModulesHandler::tr(
- "This module contains debug information.\nStepping "
- "into the module or setting breakpoints by file and "
- "line is expected to work.");
- case FastSymbols:
- return ModulesHandler::tr(
- "This module contains debug information.\nStepping "
- "into the module or setting breakpoints by file and "
- "line is expected to work.");
- case LinkedSymbols:
- case BuildIdSymbols:
- return ModulesHandler::tr(
- "This module does not contain debug information "
- "itself, but contains a reference to external "
- "debug information.");
- }
- break;
- case 4:
- if (role == Qt::DisplayRole)
- if (module.startAddress)
- return QString(QLatin1String("0x")
- + QString::number(module.startAddress, 16));
- break;
- case 5:
- if (role == Qt::DisplayRole) {
- if (module.endAddress)
- return QString(QLatin1String("0x")
- + QString::number(module.endAddress, 16));
- //: End address of loaded module
- return ModulesHandler::tr("<unknown>", "address");
+ break;
+ case 3:
+ if (role == Qt::DisplayRole)
+ switch (module.elfData.symbolsType) {
+ case UnknownSymbols:
+ return ModulesHandler::tr("Unknown");
+ case NoSymbols:
+ return ModulesHandler::tr("None");
+ case PlainSymbols:
+ return ModulesHandler::tr("Plain");
+ case FastSymbols:
+ return ModulesHandler::tr("Fast");
+ case LinkedSymbols:
+ return ModulesHandler::tr("debuglnk");
+ case BuildIdSymbols:
+ return ModulesHandler::tr("buildid");
}
- break;
- }
- return QVariant();
-}
-
-void ModulesModel::setModules(const Modules &m)
-{
- beginResetModel();
- m_modules = m;
- endResetModel();
-}
-
-void ModulesModel::clearModel()
-{
- if (!m_modules.isEmpty()) {
- beginResetModel();
- m_modules.clear();
- endResetModel();
- }
-}
-
-int ModulesModel::indexOfModule(const QString &modulePath) const
-{
- // Recent modules are more likely to be unloaded first.
- for (int i = m_modules.size() - 1; i >= 0; i--)
- if (m_modules.at(i).modulePath == modulePath)
- return i;
- return -1;
-}
-
-void ModulesModel::removeModule(const QString &modulePath)
-{
- const int row = indexOfModule(modulePath);
- QTC_ASSERT(row != -1, return);
- beginRemoveRows(QModelIndex(), row, row);
- m_modules.remove(row);
- endRemoveRows();
-}
-
-void ModulesModel::updateModule(const Module &module)
-{
- const int row = indexOfModule(module.modulePath);
- const QString path = module.modulePath;
- if (path.isEmpty())
- return;
- try { // MinGW occasionallly throws std::bad_alloc.
- ElfReader reader(path);
- ElfData elfData = reader.readHeaders();
-
- if (row == -1) {
- const int n = m_modules.size();
- beginInsertRows(QModelIndex(), n, n);
- m_modules.push_back(module);
- m_modules.back().elfData = elfData;
- endInsertRows();
- } else {
- m_modules[row] = module;
- m_modules[row].elfData = elfData;
- dataChanged(index(row, 0, QModelIndex()), index(row, 4, QModelIndex()));
+ else if (role == Qt::ToolTipRole)
+ switch (module.elfData.symbolsType) {
+ case UnknownSymbols:
+ return ModulesHandler::tr(
+ "It is unknown whether this module contains debug "
+ "information.\nUse \"Examine Symbols\" from the "
+ "context menu to initiate a check.");
+ case NoSymbols:
+ return ModulesHandler::tr(
+ "This module neither contains nor references debug "
+ "information.\nStepping into the module or setting "
+ "breakpoints by file and line will not work.");
+ case PlainSymbols:
+ return ModulesHandler::tr(
+ "This module contains debug information.\nStepping "
+ "into the module or setting breakpoints by file and "
+ "line is expected to work.");
+ case FastSymbols:
+ return ModulesHandler::tr(
+ "This module contains debug information.\nStepping "
+ "into the module or setting breakpoints by file and "
+ "line is expected to work.");
+ case LinkedSymbols:
+ case BuildIdSymbols:
+ return ModulesHandler::tr(
+ "This module does not contain debug information "
+ "itself, but contains a reference to external "
+ "debug information.");
+ }
+ break;
+ case 4:
+ if (role == Qt::DisplayRole)
+ if (module.startAddress)
+ return QString(QLatin1String("0x")
+ + QString::number(module.startAddress, 16));
+ break;
+ case 5:
+ if (role == Qt::DisplayRole) {
+ if (module.endAddress)
+ return QString(QLatin1String("0x")
+ + QString::number(module.endAddress, 16));
+ //: End address of loaded module
+ return ModulesHandler::tr("<unknown>", "address");
}
- } catch(...) {
- qWarning("%s: An exception occurred while reading module '%s'",
- Q_FUNC_INFO, qPrintable(module.modulePath));
+ break;
}
+ return QVariant();
}
//////////////////////////////////////////////////////////////////
@@ -259,11 +159,32 @@ void ModulesModel::updateModule(const Module &module)
//
//////////////////////////////////////////////////////////////////
+static ModuleItem *moduleFromPath(TreeItem *root, const QString &modulePath)
+{
+ // Recent modules are more likely to be unloaded first.
+ for (int i = root->rowCount(); --i >= 0; ) {
+ auto item = static_cast<ModuleItem *>(root->child(i));
+ if (item->module.modulePath == modulePath)
+ return item;
+ }
+ return 0;
+}
+
ModulesHandler::ModulesHandler(DebuggerEngine *engine)
{
m_engine = engine;
- m_model = new ModulesModel(this);
+
+ QString pad = QLatin1String(" ");
+ m_model = new TreeModel(this);
m_model->setObjectName(QLatin1String("ModulesModel"));
+ m_model->setHeader(QStringList()
+ << ModulesHandler::tr("Module Name") + pad
+ << ModulesHandler::tr("Module Path") + pad
+ << ModulesHandler::tr("Symbols Read") + pad
+ << ModulesHandler::tr("Symbols Type") + pad
+ << ModulesHandler::tr("Start Address") + pad
+ << ModulesHandler::tr("End Address") + pad);
+
m_proxyModel = new QSortFilterProxyModel(this);
m_proxyModel->setObjectName(QLatin1String("ModulesProxyModel"));
m_proxyModel->setSourceModel(m_model);
@@ -276,27 +197,65 @@ QAbstractItemModel *ModulesHandler::model() const
void ModulesHandler::removeAll()
{
- m_model->clearModel();
+ m_model->removeItems();
+}
+
+Modules ModulesHandler::modules() const
+{
+ Modules mods;
+ TreeItem *root = m_model->rootItem();
+ for (int i = root->rowCount(); --i >= 0; )
+ mods.append(static_cast<ModuleItem *>(root->child(i))->module);
+ return mods;
}
void ModulesHandler::removeModule(const QString &modulePath)
{
- m_model->removeModule(modulePath);
+ if (ModuleItem *item = moduleFromPath(m_model->rootItem(), modulePath))
+ m_model->removeItem(item);
}
void ModulesHandler::updateModule(const Module &module)
{
- m_model->updateModule(module);
+ const QString path = module.modulePath;
+ if (path.isEmpty())
+ return;
+
+ ModuleItem *item = moduleFromPath(m_model->rootItem(), path);
+ if (item) {
+ item->module = module;
+ } else {
+ item = new ModuleItem;
+ item->module = module;
+ m_model->rootItem()->appendChild(item);
+ }
+
+ try { // MinGW occasionallly throws std::bad_alloc.
+ ElfReader reader(path);
+ item->module.elfData = reader.readHeaders();
+ item->update();
+ } catch(...) {
+ qWarning("%s: An exception occurred while reading module '%s'",
+ Q_FUNC_INFO, qPrintable(module.modulePath));
+ }
+ item->updated = true;
}
-void ModulesHandler::setModules(const Modules &modules)
+void ModulesHandler::beginUpdateAll()
{
- m_model->setModules(modules);
+ TreeItem *root = m_model->rootItem();
+ for (int i = root->rowCount(); --i >= 0; )
+ static_cast<ModuleItem *>(root->child(i))->updated = false;
}
-Modules ModulesHandler::modules() const
+void ModulesHandler::endUpdateAll()
{
- return m_model->m_modules;
+ TreeItem *root = m_model->rootItem();
+ for (int i = root->rowCount(); --i >= 0; ) {
+ auto item = static_cast<ModuleItem *>(root->child(i));
+ if (!item->updated)
+ m_model->removeItem(item);
+ }
}
} // namespace Internal
diff --git a/src/plugins/debugger/moduleshandler.h b/src/plugins/debugger/moduleshandler.h
index 61b68e7ac3..bad6d1c879 100644
--- a/src/plugins/debugger/moduleshandler.h
+++ b/src/plugins/debugger/moduleshandler.h
@@ -32,6 +32,7 @@
#define DEBUGGER_MODULESHANDLER_H
#include <utils/elfreader.h>
+#include <utils/treemodel.h>
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
@@ -39,12 +40,9 @@ class QSortFilterProxyModel;
QT_END_NAMESPACE
namespace Debugger {
-
-class DebuggerEngine;
-
namespace Internal {
-class ModulesModel;
+class DebuggerEngine;
//////////////////////////////////////////////////////////////////
//
@@ -111,7 +109,6 @@ public:
typedef QVector<Module> Modules;
-
//////////////////////////////////////////////////////////////////
//
// ModulesHandler
@@ -127,16 +124,18 @@ public:
QAbstractItemModel *model() const;
- void setModules(const Modules &modules);
void removeModule(const QString &modulePath);
void updateModule(const Module &module);
- Modules modules() const;
+ void beginUpdateAll();
+ void endUpdateAll();
+
void removeAll();
+ Modules modules() const;
private:
DebuggerEngine *m_engine;
- ModulesModel *m_model;
+ Utils::TreeModel *m_model;
QSortFilterProxyModel *m_proxyModel;
};
diff --git a/src/plugins/debugger/moduleswindow.cpp b/src/plugins/debugger/moduleswindow.cpp
index 19ebd36362..e9605587d6 100644
--- a/src/plugins/debugger/moduleswindow.cpp
+++ b/src/plugins/debugger/moduleswindow.cpp
@@ -57,8 +57,8 @@ ModulesTreeView::ModulesTreeView()
{
setSortingEnabled(true);
- connect(this, SIGNAL(activated(QModelIndex)),
- SLOT(moduleActivated(QModelIndex)));
+ connect(this, &QAbstractItemView::activated,
+ this, &ModulesTreeView::moduleActivated);
}
void ModulesTreeView::moduleActivated(const QModelIndex &index)
diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp
index 559b2a8f8a..a6a2acb226 100644
--- a/src/plugins/debugger/pdb/pdbengine.cpp
+++ b/src/plugins/debugger/pdb/pdbengine.cpp
@@ -52,6 +52,7 @@
#include <texteditor/texteditor.h>
#include <coreplugin/idocument.h>
#include <coreplugin/icore.h>
+#include <coreplugin/messagebox.h>
#include <QDateTime>
#include <QDebug>
@@ -61,7 +62,6 @@
#include <QVariant>
#include <QApplication>
-#include <QMessageBox>
#include <QToolTip>
@@ -157,17 +157,17 @@ void PdbEngine::setupEngine()
m_pdb = _("python");
showMessage(_("STARTING PDB ") + m_pdb);
- connect(&m_pdbProc, SIGNAL(error(QProcess::ProcessError)),
- SLOT(handlePdbError(QProcess::ProcessError)));
- connect(&m_pdbProc, SIGNAL(finished(int,QProcess::ExitStatus)),
- SLOT(handlePdbFinished(int,QProcess::ExitStatus)));
- connect(&m_pdbProc, SIGNAL(readyReadStandardOutput()),
- SLOT(readPdbStandardOutput()));
- connect(&m_pdbProc, SIGNAL(readyReadStandardError()),
- SLOT(readPdbStandardError()));
+ connect(&m_pdbProc, static_cast<void(QProcess::*)(QProcess::ProcessError)>(&QProcess::error),
+ this, &PdbEngine::handlePdbError);
+ connect(&m_pdbProc, static_cast<void(QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished),
+ this, &PdbEngine::handlePdbFinished);
+ connect(&m_pdbProc, &QProcess::readyReadStandardOutput,
+ this, &PdbEngine::readPdbStandardOutput);
+ connect(&m_pdbProc, &QProcess::readyReadStandardError,
+ this, &PdbEngine::readPdbStandardError);
- connect(this, SIGNAL(outputReady(QByteArray)),
- SLOT(handleOutput2(QByteArray)), Qt::QueuedConnection);
+ connect(this, &PdbEngine::outputReady,
+ this, &PdbEngine::handleOutput2, Qt::QueuedConnection);
// We will stop immediately, so setup a proper callback.
PdbCommand cmd;
@@ -198,7 +198,7 @@ void PdbEngine::setupInferior()
QString fileName = QFileInfo(startParameters().executable).absoluteFilePath();
QFile scriptFile(fileName);
if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
- showMessageBox(QMessageBox::Critical, tr("Python Error"),
+ Core::AsynchronousMessageBox::critical(tr("Python Error"),
_("Cannot open script file %1:\n%2").
arg(fileName, scriptFile.errorString()));
notifyInferiorSetupFailed();
@@ -327,34 +327,31 @@ void PdbEngine::selectThread(ThreadId threadId)
Q_UNUSED(threadId)
}
-bool PdbEngine::acceptsBreakpoint(BreakpointModelId id) const
+bool PdbEngine::acceptsBreakpoint(Breakpoint bp) const
{
- const QString fileName = breakHandler()->fileName(id);
+ const QString fileName = bp.fileName();
return fileName.endsWith(QLatin1String(".py"));
}
-void PdbEngine::insertBreakpoint(BreakpointModelId id)
+void PdbEngine::insertBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
- QTC_CHECK(handler->state(id) == BreakpointInsertRequested);
- handler->notifyBreakpointInsertProceeding(id);
+ QTC_CHECK(bp.state() == BreakpointInsertRequested);
+ bp.notifyBreakpointInsertProceeding();
QByteArray loc;
- if (handler->type(id) == BreakpointByFunction)
- loc = handler->functionName(id).toLatin1();
+ if (bp.type() == BreakpointByFunction)
+ loc = bp.functionName().toLatin1();
else
- loc = handler->fileName(id).toLocal8Bit() + ':'
- + QByteArray::number(handler->lineNumber(id));
+ loc = bp.fileName().toLocal8Bit() + ':'
+ + QByteArray::number(bp.lineNumber());
- postCommand("break " + loc, CB(handleBreakInsert), QVariant(id));
+ postCommand("break " + loc, CB(handleBreakInsert), QVariant::fromValue(bp));
}
void PdbEngine::handleBreakInsert(const PdbResponse &response)
{
//qDebug() << "BP RESPONSE: " << response.data;
// "Breakpoint 1 at /pdb/math.py:10"
- BreakpointModelId id(response.cookie.toInt());
- BreakHandler *handler = breakHandler();
QTC_ASSERT(response.data.startsWith("Breakpoint "), return);
int pos1 = response.data.indexOf(" at ");
QTC_ASSERT(pos1 != -1, return);
@@ -366,22 +363,21 @@ void PdbEngine::handleBreakInsert(const PdbResponse &response)
br.id = BreakpointResponseId(bpnr);
br.fileName = _(file);
br.lineNumber = line.toInt();
- handler->setResponse(id, br);
- QTC_CHECK(!handler->needsChange(id));
- handler->notifyBreakpointInsertOk(id);
+ Breakpoint bp = response.cookie.value<Breakpoint>();
+ bp.setResponse(br);
+ QTC_CHECK(!bp.needsChange());
+ bp.notifyBreakpointInsertOk();
}
-void PdbEngine::removeBreakpoint(BreakpointModelId id)
+void PdbEngine::removeBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
- QTC_CHECK(handler->state(id) == BreakpointRemoveRequested);
- handler->notifyBreakpointRemoveProceeding(id);
- BreakpointResponse br = handler->response(id);
- showMessage(_("DELETING BP %1 IN %2").arg(br.id.toString())
- .arg(handler->fileName(id)));
+ QTC_CHECK(bp.state() == BreakpointRemoveRequested);
+ bp.notifyBreakpointRemoveProceeding();
+ BreakpointResponse br = bp.response();
+ showMessage(_("DELETING BP %1 IN %2").arg(br.id.toString()).arg(bp.fileName()));
postCommand("clear " + br.id.toByteArray());
// Pretend it succeeds without waiting for response.
- handler->notifyBreakpointRemoveOk(id);
+ bp.notifyBreakpointRemoveOk();
}
void PdbEngine::loadSymbols(const QString &moduleName)
@@ -402,7 +398,8 @@ void PdbEngine::handleListModules(const PdbResponse &response)
{
GdbMi out;
out.fromString(response.data.trimmed());
- Modules modules;
+ ModulesHandler *handler = modulesHandler();
+ handler->beginUpdateAll();
foreach (const GdbMi &item, out.children()) {
Module module;
module.moduleName = _(item["name"].data());
@@ -417,9 +414,9 @@ void PdbEngine::handleListModules(const PdbResponse &response)
path = _("(builtin)");
}
module.modulePath = path;
- modules.append(module);
+ handler->updateModule(module);
}
- modulesHandler()->setModules(modules);
+ handler->endUpdateAll();
}
void PdbEngine::requestModuleSymbols(const QString &moduleName)
@@ -555,8 +552,8 @@ void PdbEngine::handlePdbError(QProcess::ProcessError error)
default:
//setState(EngineShutdownRequested, true);
m_pdbProc.kill();
- showMessageBox(QMessageBox::Critical, tr("Pdb I/O Error"),
- errorMessage(error));
+ Core::AsynchronousMessageBox::critical(tr("Pdb I/O Error"),
+ errorMessage(error));
break;
}
}
@@ -728,7 +725,7 @@ void PdbEngine::updateLocals()
options.chop(1);
postCommand("qdebug('" + options + "','"
- + handler->expansionRequests() + "','"
+// + handler->expansionRequests() + "','"
+ handler->typeFormatRequests() + "','"
+ handler->individualFormatRequests() + "','"
+ watchers.toHex() + "')", CB(handleListLocals));
@@ -803,16 +800,19 @@ void PdbEngine::handleListLocals(const PdbResponse &response)
//qDebug() << "ALL: " << all.toString();
//GdbMi data = all.findChild("data");
- QList<WatchData> list;
WatchHandler *handler = watchHandler();
+
+ QSet<QByteArray> toDelete;
+ foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(2))
+ toDelete.insert(item->d.iname);
+
foreach (const GdbMi &child, all.children()) {
- WatchData dummy;
- dummy.iname = child["iname"].data();
- dummy.name = _(child["name"].data());
- //qDebug() << "CHILD: " << child.toString();
- parseWatchData(handler->expandedINames(), dummy, child, &list);
+ WatchItem *item = new WatchItem(child);
+ handler->insertItem(item);
+ toDelete.remove(item->d.iname);
}
- handler->insertData(list);
+
+ handler->purgeOutdatedItems(toDelete);
}
bool PdbEngine::hasCapability(unsigned cap) const
@@ -825,6 +825,5 @@ DebuggerEngine *createPdbEngine(const DebuggerStartParameters &startParameters)
return new PdbEngine(startParameters);
}
-
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h
index 2a1cd55ced..41dc68a119 100644
--- a/src/plugins/debugger/pdb/pdbengine.h
+++ b/src/plugins/debugger/pdb/pdbengine.h
@@ -89,9 +89,9 @@ private:
void activateFrame(int index);
void selectThread(ThreadId threadId);
- bool acceptsBreakpoint(BreakpointModelId id) const;
- void insertBreakpoint(BreakpointModelId id);
- void removeBreakpoint(BreakpointModelId id);
+ bool acceptsBreakpoint(Breakpoint bp) const;
+ void insertBreakpoint(Breakpoint bp);
+ void removeBreakpoint(Breakpoint bp);
void assignValueInDebugger(const WatchData *data,
const QString &expr, const QVariant &value);
@@ -116,11 +116,11 @@ private:
QString errorMessage(QProcess::ProcessError error) const;
bool hasCapability(unsigned cap) const;
- Q_SLOT void handlePdbFinished(int, QProcess::ExitStatus status);
- Q_SLOT void handlePdbError(QProcess::ProcessError error);
- Q_SLOT void readPdbStandardOutput();
- Q_SLOT void readPdbStandardError();
- Q_SLOT void handleOutput2(const QByteArray &data);
+ void handlePdbFinished(int, QProcess::ExitStatus status);
+ void handlePdbError(QProcess::ProcessError error);
+ void readPdbStandardOutput();
+ void readPdbStandardError();
+ void handleOutput2(const QByteArray &data);
void handleResponse(const QByteArray &ba);
void handleOutput(const QByteArray &data);
void updateAll();
diff --git a/src/plugins/debugger/qml/baseqmldebuggerclient.cpp b/src/plugins/debugger/qml/baseqmldebuggerclient.cpp
index c1b443b985..5a7f9287a1 100644
--- a/src/plugins/debugger/qml/baseqmldebuggerclient.cpp
+++ b/src/plugins/debugger/qml/baseqmldebuggerclient.cpp
@@ -29,6 +29,7 @@
****************************************************************************/
#include "baseqmldebuggerclient.h"
+#include <debugger/breakhandler.h>
#include <utils/qtcassert.h>
@@ -52,7 +53,7 @@ BaseQmlDebuggerClient::~BaseQmlDebuggerClient()
delete d;
}
-bool BaseQmlDebuggerClient::acceptsBreakpoint(const BreakpointModelId &/*id*/)
+bool BaseQmlDebuggerClient::acceptsBreakpoint(Breakpoint /*bp*/)
{
return false;
}
diff --git a/src/plugins/debugger/qml/baseqmldebuggerclient.h b/src/plugins/debugger/qml/baseqmldebuggerclient.h
index cb0d63b139..409a3dc9c5 100644
--- a/src/plugins/debugger/qml/baseqmldebuggerclient.h
+++ b/src/plugins/debugger/qml/baseqmldebuggerclient.h
@@ -67,11 +67,11 @@ public:
virtual void activateFrame(int index) = 0;
- virtual bool acceptsBreakpoint(const BreakpointModelId &id);
- virtual void insertBreakpoint(const BreakpointModelId &id, int adjustedLine,
+ virtual bool acceptsBreakpoint(Breakpoint bp);
+ virtual void insertBreakpoint(Breakpoint bp, int adjustedLine,
int adjustedColumn = -1) = 0;
- virtual void removeBreakpoint(const BreakpointModelId &id) = 0;
- virtual void changeBreakpoint(const BreakpointModelId &id) = 0;
+ virtual void removeBreakpoint(Breakpoint bp) = 0;
+ virtual void changeBreakpoint(Breakpoint bp) = 0;
virtual void synchronizeBreakpoints() = 0;
virtual void assignValueInDebugger(const WatchData *data,
diff --git a/src/plugins/debugger/qml/qmladapter.cpp b/src/plugins/debugger/qml/qmladapter.cpp
index 2557753a4e..73f29d0400 100644
--- a/src/plugins/debugger/qml/qmladapter.cpp
+++ b/src/plugins/debugger/qml/qmladapter.cpp
@@ -57,21 +57,25 @@ QmlAdapter::QmlAdapter(DebuggerEngine *engine, QObject *parent)
{
m_connectionTimer.setInterval(4000);
m_connectionTimer.setSingleShot(true);
- connect(&m_connectionTimer, SIGNAL(timeout()), SLOT(checkConnectionState()));
+ connect(&m_connectionTimer, &QTimer::timeout, this, &QmlAdapter::checkConnectionState);
m_conn = new QmlDebugConnection(this);
- connect(m_conn, SIGNAL(stateMessage(QString)), SLOT(showConnectionStateMessage(QString)));
- connect(m_conn, SIGNAL(errorMessage(QString)), SLOT(showConnectionErrorMessage(QString)));
- connect(m_conn, SIGNAL(error(QDebugSupport::Error)),
- SLOT(connectionErrorOccurred(QDebugSupport::Error)));
- connect(m_conn, SIGNAL(opened()), &m_connectionTimer, SLOT(stop()));
- connect(m_conn, SIGNAL(opened()), SIGNAL(connected()));
- connect(m_conn, SIGNAL(closed()), SIGNAL(disconnected()));
+ connect(m_conn, &QmlDebugConnection::stateMessage,
+ this, &QmlAdapter::showConnectionStateMessage);
+ connect(m_conn, &QmlDebugConnection::errorMessage,
+ this, &QmlAdapter::showConnectionErrorMessage);
+ connect(m_conn, &QmlDebugConnection::error,
+ this, &QmlAdapter::connectionErrorOccurred);
+ connect(m_conn, &QmlDebugConnection::opened,
+ &m_connectionTimer, &QTimer::stop);
+ connect(m_conn, &QmlDebugConnection::opened,
+ this, &QmlAdapter::connected);
+ connect(m_conn, &QmlDebugConnection::closed,
+ this, &QmlAdapter::disconnected);
createDebuggerClients();
m_msgClient = new QDebugMessageClient(m_conn);
- connect(m_msgClient, SIGNAL(newState(QmlDebug::QmlDebugClient::State)),
- this, SLOT(clientStateChanged(QmlDebug::QmlDebugClient::State)));
+ connect(m_msgClient, &QDebugMessageClient::newState, this, &QmlAdapter::clientStateChanged);
}
@@ -125,7 +129,7 @@ void QmlAdapter::clientStateChanged(QmlDebugClient::State state)
void QmlAdapter::debugClientStateChanged(QmlDebugClient::State state)
{
- if (state != QmlDebug::QmlDebugClient::Enabled)
+ if (state != QmlDebugClient::Enabled)
return;
QmlDebugClient *client = qobject_cast<QmlDebugClient*>(sender());
QTC_ASSERT(client, return);
@@ -150,16 +154,16 @@ bool QmlAdapter::isConnected() const
void QmlAdapter::createDebuggerClients()
{
QScriptDebuggerClient *debugClient1 = new QScriptDebuggerClient(m_conn);
- connect(debugClient1, SIGNAL(newState(QmlDebug::QmlDebugClient::State)),
- this, SLOT(clientStateChanged(QmlDebug::QmlDebugClient::State)));
- connect(debugClient1, SIGNAL(newState(QmlDebug::QmlDebugClient::State)),
- this, SLOT(debugClientStateChanged(QmlDebug::QmlDebugClient::State)));
+ connect(debugClient1, &QScriptDebuggerClient::newState,
+ this, &QmlAdapter::clientStateChanged);
+ connect(debugClient1, &QScriptDebuggerClient::newState,
+ this, &QmlAdapter::debugClientStateChanged);
QmlV8DebuggerClient *debugClient2 = new QmlV8DebuggerClient(m_conn);
- connect(debugClient2, SIGNAL(newState(QmlDebug::QmlDebugClient::State)),
- this, SLOT(clientStateChanged(QmlDebug::QmlDebugClient::State)));
- connect(debugClient2, SIGNAL(newState(QmlDebug::QmlDebugClient::State)),
- this, SLOT(debugClientStateChanged(QmlDebug::QmlDebugClient::State)));
+ connect(debugClient2, &QmlV8DebuggerClient::newState,
+ this, &QmlAdapter::clientStateChanged);
+ connect(debugClient2, &QmlV8DebuggerClient::newState,
+ this, &QmlAdapter::debugClientStateChanged);
m_debugClients.insert(debugClient1->name(),debugClient1);
m_debugClients.insert(debugClient2->name(),debugClient2);
@@ -206,21 +210,21 @@ QDebugMessageClient *QmlAdapter::messageClient() const
}
void QmlAdapter::logServiceStateChange(const QString &service, float version,
- QmlDebug::QmlDebugClient::State newState)
+ QmlDebugClient::State newState)
{
switch (newState) {
- case QmlDebug::QmlDebugClient::Unavailable: {
+ case QmlDebugClient::Unavailable: {
showConnectionStateMessage(_("Status of \"%1\" Version: %2 changed to 'unavailable'.").
arg(service).arg(QString::number(version)));
break;
}
- case QmlDebug::QmlDebugClient::Enabled: {
+ case QmlDebugClient::Enabled: {
showConnectionStateMessage(_("Status of \"%1\" Version: %2 changed to 'enabled'.").
arg(service).arg(QString::number(version)));
break;
}
- case QmlDebug::QmlDebugClient::NotConnected: {
+ case QmlDebugClient::NotConnected: {
showConnectionStateMessage(_("Status of \"%1\" Version: %2 changed to 'not connected'.").
arg(service).arg(QString::number(version)));
break;
diff --git a/src/plugins/debugger/qml/qmladapter.h b/src/plugins/debugger/qml/qmladapter.h
index bba06ea8e4..e9f3936878 100644
--- a/src/plugins/debugger/qml/qmladapter.h
+++ b/src/plugins/debugger/qml/qmladapter.h
@@ -43,11 +43,10 @@ class QDebugMessageClient;
}
namespace Debugger {
-
-class DebuggerEngine;
-
namespace Internal {
+
class BaseQmlDebuggerClient;
+class DebuggerEngine;
class QmlAdapterPrivate;
class QmlAdapter : public QObject
diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp
index f6813113be..1d01a19020 100644
--- a/src/plugins/debugger/qml/qmlcppengine.cpp
+++ b/src/plugins/debugger/qml/qmlcppengine.cpp
@@ -30,8 +30,10 @@
#include "qmlcppengine.h"
#include "qmlengine.h"
+
#include <debugger/debuggerruncontrol.h>
#include <debugger/debuggerstartparameters.h>
+#include <debugger/breakhandler.h>
#include <debugger/stackhandler.h>
#include <debugger/watchhandler.h>
@@ -184,9 +186,9 @@ void QmlCppEngine::reloadFullStack()
m_cppEngine->reloadFullStack();
}
-void QmlCppEngine::setRegisterValue(int regnr, const QString &value)
+void QmlCppEngine::setRegisterValue(const QByteArray &name, const QString &value)
{
- m_cppEngine->setRegisterValue(regnr, value);
+ m_cppEngine->setRegisterValue(name, value);
}
@@ -244,10 +246,10 @@ void QmlCppEngine::attemptBreakpointSynchronization()
}
}
-bool QmlCppEngine::acceptsBreakpoint(BreakpointModelId id) const
+bool QmlCppEngine::acceptsBreakpoint(Breakpoint bp) const
{
- return m_cppEngine->acceptsBreakpoint(id)
- || m_qmlEngine->acceptsBreakpoint(id);
+ return m_cppEngine->acceptsBreakpoint(bp)
+ || m_qmlEngine->acceptsBreakpoint(bp);
}
void QmlCppEngine::selectThread(ThreadId threadId)
@@ -285,26 +287,10 @@ void QmlCppEngine::detachDebugger()
void QmlCppEngine::executeStep()
{
-// TODO: stepping from qml -> cpp requires more thought
-// if (m_activeEngine == m_qmlEngine) {
-// QTC_CHECK(m_cppEngine->state() == InferiorRunOk);
-// if (m_cppEngine->setupQmlStep(true))
-// return; // Wait for callback to readyToExecuteQmlStep()
-// } else {
-// notifyInferiorRunRequested();
-// m_cppEngine->executeStep();
-// }
-
notifyInferiorRunRequested();
m_activeEngine->executeStep();
}
-void QmlCppEngine::readyToExecuteQmlStep()
-{
- notifyInferiorRunRequested();
- m_qmlEngine->executeStep();
-}
-
void QmlCppEngine::executeStepOut()
{
notifyInferiorRunRequested();
@@ -424,7 +410,6 @@ void QmlCppEngine::notifyInferiorShutdownOk()
void QmlCppEngine::notifyInferiorSetupOk()
{
EDEBUG("\nMASTER INFERIOR SETUP OK");
- emit aboutToNotifyInferiorSetupOk();
DebuggerEngine::notifyInferiorSetupOk();
}
@@ -774,6 +759,18 @@ void QmlCppEngine::resetLocation()
DebuggerEngine::resetLocation();
}
+void QmlCppEngine::reloadDebuggingHelpers()
+{
+ if (m_cppEngine)
+ m_cppEngine->reloadDebuggingHelpers();
+}
+
+void QmlCppEngine::debugLastCommand()
+{
+ if (m_cppEngine)
+ m_cppEngine->debugLastCommand();
+}
+
DebuggerEngine *QmlCppEngine::cppEngine() const
{
return m_cppEngine;
diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h
index 665d343119..898803ee69 100644
--- a/src/plugins/debugger/qml/qmlcppengine.h
+++ b/src/plugins/debugger/qml/qmlcppengine.h
@@ -68,7 +68,7 @@ public:
void reloadSourceFiles();
void reloadFullStack();
- void setRegisterValue(int regnr, const QString &value);
+ void setRegisterValue(const QByteArray &name, const QString &value);
bool hasCapability(unsigned cap) const;
bool isSynchronous() const;
@@ -78,7 +78,7 @@ public:
void updateAll();
void attemptBreakpointSynchronization();
- bool acceptsBreakpoint(BreakpointModelId id) const;
+ bool acceptsBreakpoint(Breakpoint bp) const;
void selectThread(ThreadId threadId);
void assignValueInDebugger(const WatchData *data,
@@ -97,6 +97,8 @@ public:
protected:
void detachDebugger();
+ void reloadDebuggingHelpers();
+ void debugLastCommand();
void executeStep();
void executeStepOut();
void executeNext();
@@ -128,15 +130,11 @@ protected:
void notifyInferiorSetupOk();
void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
-signals:
- void aboutToNotifyInferiorSetupOk();
-
private:
void engineStateChanged(DebuggerState newState);
void setState(DebuggerState newState, bool forced = false);
void slaveEngineStateChanged(DebuggerEngine *slaveEngine, DebuggerState state);
- void readyToExecuteQmlStep();
void setActiveEngine(DebuggerEngine *engine);
private:
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index 4924fce386..8f8422d14d 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -249,9 +249,9 @@ public:
quint32 *column;
};
-QmlJS::ConsoleManagerInterface *qmlConsoleManager()
+ConsoleManagerInterface *qmlConsoleManager()
{
- return QmlJS::ConsoleManagerInterface::instance();
+ return ConsoleManagerInterface::instance();
}
///////////////////////////////////////////////////////////////////////
@@ -351,12 +351,6 @@ QmlEngine::~QmlEngine()
Core::EditorManager::closeDocuments(documentsToClose.toList());
}
-void QmlEngine::notifyInferiorSetupOk()
-{
- emit aboutToNotifyInferiorSetupOk();
- DebuggerEngine::notifyInferiorSetupOk();
-}
-
void QmlEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
@@ -803,21 +797,20 @@ void QmlEngine::selectThread(ThreadId threadId)
Q_UNUSED(threadId)
}
-void QmlEngine::insertBreakpoint(BreakpointModelId id)
+void QmlEngine::insertBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
- BreakpointState state = handler->state(id);
- QTC_ASSERT(state == BreakpointInsertRequested, qDebug() << id << this << state);
- handler->notifyBreakpointInsertProceeding(id);
+ BreakpointState state = bp.state();
+ QTC_ASSERT(state == BreakpointInsertRequested, qDebug() << bp << this << state);
+ bp.notifyBreakpointInsertProceeding();
- const BreakpointParameters &params = handler->breakpointData(id);
+ const BreakpointParameters &params = bp.parameters();
quint32 line = params.lineNumber;
quint32 column = 0;
if (params.type == BreakpointByFileAndLine) {
bool valid = false;
if (!adjustBreakpointLineAndColumn(params.fileName, &line, &column,
&valid)) {
- pendingBreakpoints.insertMulti(params.fileName, id);
+ pendingBreakpoints.insertMulti(params.fileName, bp);
return;
}
if (!valid)
@@ -825,65 +818,61 @@ void QmlEngine::insertBreakpoint(BreakpointModelId id)
}
if (m_adapter.activeDebuggerClient()) {
- m_adapter.activeDebuggerClient()->insertBreakpoint(id, line, column);
+ m_adapter.activeDebuggerClient()->insertBreakpoint(bp, line, column);
} else {
foreach (BaseQmlDebuggerClient *client, m_adapter.debuggerClients()) {
- client->insertBreakpoint(id, line, column);
+ client->insertBreakpoint(bp, line, column);
}
}
}
-void QmlEngine::removeBreakpoint(BreakpointModelId id)
+void QmlEngine::removeBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
-
- const BreakpointParameters &params = handler->breakpointData(id);
+ const BreakpointParameters &params = bp.parameters();
if (params.type == BreakpointByFileAndLine &&
pendingBreakpoints.contains(params.fileName)) {
- QHash<QString, BreakpointModelId>::iterator i =
- pendingBreakpoints.find(params.fileName);
- while (i != pendingBreakpoints.end() && i.key() == params.fileName) {
- if (i.value() == id) {
- pendingBreakpoints.erase(i);
+ auto it = pendingBreakpoints.find(params.fileName);
+ while (it != pendingBreakpoints.end() && it.key() == params.fileName) {
+ if (it.value() == bp.id()) {
+ pendingBreakpoints.erase(it);
return;
}
- ++i;
+ ++it;
}
}
- BreakpointState state = handler->state(id);
- QTC_ASSERT(state == BreakpointRemoveRequested, qDebug() << id << this << state);
- handler->notifyBreakpointRemoveProceeding(id);
+ BreakpointState state = bp.state();
+ QTC_ASSERT(state == BreakpointRemoveRequested, qDebug() << bp << this << state);
+ bp.notifyBreakpointRemoveProceeding();
if (m_adapter.activeDebuggerClient()) {
- m_adapter.activeDebuggerClient()->removeBreakpoint(id);
+ m_adapter.activeDebuggerClient()->removeBreakpoint(bp);
} else {
foreach (BaseQmlDebuggerClient *client, m_adapter.debuggerClients()) {
- client->removeBreakpoint(id);
+ client->removeBreakpoint(bp);
}
}
- if (handler->state(id) == BreakpointRemoveProceeding)
- handler->notifyBreakpointRemoveOk(id);
+ if (bp.state() == BreakpointRemoveProceeding)
+ bp.notifyBreakpointRemoveOk();
}
-void QmlEngine::changeBreakpoint(BreakpointModelId id)
+void QmlEngine::changeBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = breakHandler();
- BreakpointState state = handler->state(id);
- QTC_ASSERT(state == BreakpointChangeRequested, qDebug() << id << this << state);
- handler->notifyBreakpointChangeProceeding(id);
+ BreakpointState state = bp.state();
+ QTC_ASSERT(state == BreakpointChangeRequested, qDebug() << bp << this << state);
+ bp.notifyBreakpointChangeProceeding();
if (m_adapter.activeDebuggerClient()) {
- m_adapter.activeDebuggerClient()->changeBreakpoint(id);
+ m_adapter.activeDebuggerClient()->changeBreakpoint(bp);
} else {
foreach (BaseQmlDebuggerClient *client, m_adapter.debuggerClients()) {
- client->changeBreakpoint(id);
+ client->changeBreakpoint(bp);
}
}
- if (handler->state(id) == BreakpointChangeProceeding)
- handler->notifyBreakpointChangeOk(id);
+ if (bp.state() == BreakpointChangeProceeding)
+ bp.notifyBreakpointChangeOk();
}
void QmlEngine::attemptBreakpointSynchronization()
@@ -896,26 +885,26 @@ void QmlEngine::attemptBreakpointSynchronization()
BreakHandler *handler = breakHandler();
DebuggerEngine *bpOwner = isSlaveEngine() ? masterEngine() : this;
- foreach (BreakpointModelId id, handler->unclaimedBreakpointIds()) {
+ foreach (Breakpoint bp, handler->unclaimedBreakpoints()) {
// Take ownership of the breakpoint. Requests insertion.
- if (acceptsBreakpoint(id))
- handler->setEngine(id, bpOwner);
+ if (acceptsBreakpoint(bp))
+ bp.setEngine(bpOwner);
}
- foreach (BreakpointModelId id, handler->engineBreakpointIds(bpOwner)) {
- switch (handler->state(id)) {
+ foreach (Breakpoint bp, handler->engineBreakpoints(bpOwner)) {
+ switch (bp.state()) {
case BreakpointNew:
// Should not happen once claimed.
QTC_CHECK(false);
continue;
case BreakpointInsertRequested:
- insertBreakpoint(id);
+ insertBreakpoint(bp);
continue;
case BreakpointChangeRequested:
- changeBreakpoint(id);
+ changeBreakpoint(bp);
continue;
case BreakpointRemoveRequested:
- removeBreakpoint(id);
+ removeBreakpoint(bp);
continue;
case BreakpointChangeProceeding:
case BreakpointInsertProceeding:
@@ -924,7 +913,7 @@ void QmlEngine::attemptBreakpointSynchronization()
case BreakpointDead:
continue;
}
- QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << id << state());
+ QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << bp << state());
}
DebuggerEngine::attemptBreakpointSynchronization();
@@ -938,9 +927,9 @@ void QmlEngine::attemptBreakpointSynchronization()
}
}
-bool QmlEngine::acceptsBreakpoint(BreakpointModelId id) const
+bool QmlEngine::acceptsBreakpoint(Breakpoint bp) const
{
- if (!breakHandler()->breakpointData(id).isCppBreakpoint())
+ if (!bp.parameters().isCppBreakpoint())
return true;
//If it is a Cpp Breakpoint query if the type can be also handled by the debugger client
@@ -949,7 +938,7 @@ bool QmlEngine::acceptsBreakpoint(BreakpointModelId id) const
//This is because the older client does not support BreakpointOnQmlSignalHandler
bool acceptBreakpoint = false;
if (m_adapter.activeDebuggerClient())
- acceptBreakpoint = m_adapter.activeDebuggerClient()->acceptsBreakpoint(id);
+ acceptBreakpoint = m_adapter.activeDebuggerClient()->acceptsBreakpoint(bp);
return acceptBreakpoint;
}
@@ -1052,7 +1041,7 @@ void QmlEngine::synchronizeWatchers()
}
}
-QmlJS::ConsoleItem *constructLogItemTree(QmlJS::ConsoleItem *parent,
+ConsoleItem *constructLogItemTree(ConsoleItem *parent,
const QVariant &result,
const QString &key = QString())
{
@@ -1146,14 +1135,14 @@ void QmlEngine::disconnected()
notifyInferiorExited();
}
-void QmlEngine::documentUpdated(QmlJS::Document::Ptr doc)
+void QmlEngine::documentUpdated(Document::Ptr doc)
{
QString fileName = doc->fileName();
if (pendingBreakpoints.contains(fileName)) {
- QList<BreakpointModelId> ids = pendingBreakpoints.values(fileName);
+ QList<Breakpoint> bps = pendingBreakpoints.values(fileName);
pendingBreakpoints.remove(fileName);
- foreach (const BreakpointModelId &id, ids)
- insertBreakpoint(id);
+ foreach (const Breakpoint bp, bps)
+ insertBreakpoint(bp);
}
}
@@ -1178,7 +1167,7 @@ void QmlEngine::updateCurrentContext()
synchronizeWatchers();
- QmlJS::ConsoleManagerInterface *consoleManager = qmlConsoleManager();
+ ConsoleManagerInterface *consoleManager = qmlConsoleManager();
if (consoleManager)
consoleManager->setContext(tr("Context:") + QLatin1Char(' ') + context);
}
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index 9b8b9987bf..baddc4ae65 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -60,7 +60,6 @@ public:
DebuggerEngine *masterEngine = 0);
~QmlEngine();
- void notifyInferiorSetupOk();
void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
@@ -85,12 +84,11 @@ public:
void updateScriptSource(const QString &fileName, int lineOffset,
int columnOffset, const QString &source);
- void insertBreakpoint(BreakpointModelId id);
+ void insertBreakpoint(Breakpoint bp);
signals:
void tooltipRequested(const QPoint &mousePos,
TextEditor::TextEditorWidget *editorWidget, int cursorPos);
- void aboutToNotifyInferiorSetupOk();
private slots:
void disconnected();
@@ -142,9 +140,9 @@ private:
void selectThread(ThreadId threadId);
void attemptBreakpointSynchronization();
- void removeBreakpoint(BreakpointModelId id);
- void changeBreakpoint(BreakpointModelId id);
- bool acceptsBreakpoint(BreakpointModelId id) const;
+ void removeBreakpoint(Breakpoint bp);
+ void changeBreakpoint(Breakpoint bp);
+ bool acceptsBreakpoint(Breakpoint bp) const;
void assignValueInDebugger(const WatchData *data,
const QString &expr, const QVariant &value);
@@ -192,7 +190,7 @@ private:
QHash<QString, QTextDocument*> m_sourceDocuments;
QHash<QString, QWeakPointer<TextEditor::BaseTextEditor> > m_sourceEditors;
InteractiveInterpreter m_interpreter;
- QHash<QString,BreakpointModelId> pendingBreakpoints;
+ QHash<QString,Breakpoint> pendingBreakpoints;
QList<quint32> queryIds;
bool m_retryOnConnectFail;
bool m_automaticConnect;
diff --git a/src/plugins/debugger/qml/qmlinspectoradapter.cpp b/src/plugins/debugger/qml/qmlinspectoradapter.cpp
index 3c711f98e7..08edb3588b 100644
--- a/src/plugins/debugger/qml/qmlinspectoradapter.cpp
+++ b/src/plugins/debugger/qml/qmlinspectoradapter.cpp
@@ -299,7 +299,7 @@ void QmlInspectorAdapter::createPreviewForEditor(Core::IEditor *newEditor)
!= QmlJSEditor::Constants::C_QMLJSEDITOR_ID)
return;
- QString filename = newEditor->document()->filePath();
+ QString filename = newEditor->document()->filePath().toString();
QmlJS::ModelManagerInterface *modelManager =
QmlJS::ModelManagerInterface::instance();
if (modelManager) {
@@ -330,7 +330,7 @@ void QmlInspectorAdapter::createPreviewForEditor(Core::IEditor *newEditor)
connect(preview, SIGNAL(reloadRequest()),
this, SLOT(onReload()));
- m_textPreviews.insert(newEditor->document()->filePath(), preview);
+ m_textPreviews.insert(newEditor->document()->filePath().toString(), preview);
preview->associateEditor(newEditor);
preview->updateDebugIds();
}
@@ -340,7 +340,7 @@ void QmlInspectorAdapter::createPreviewForEditor(Core::IEditor *newEditor)
void QmlInspectorAdapter::removePreviewForEditor(Core::IEditor *editor)
{
if (QmlLiveTextPreview *preview
- = m_textPreviews.value(editor->document()->filePath())) {
+ = m_textPreviews.value(editor->document()->filePath().toString())) {
preview->unassociateEditor(editor);
}
}
@@ -364,7 +364,7 @@ void QmlInspectorAdapter::updatePendingPreviewDocuments(QmlJS::Document::Ptr doc
Core::IEditor *editor = editors.takeFirst();
createPreviewForEditor(editor);
QmlLiveTextPreview *preview
- = m_textPreviews.value(editor->document()->filePath());
+ = m_textPreviews.value(editor->document()->filePath().toString());
foreach (Core::IEditor *editor, editors)
preview->associateEditor(editor);
}
@@ -460,7 +460,7 @@ void QmlInspectorAdapter::initializePreviews()
QList<Core::IEditor *> editors = Core::DocumentModel::editorsForDocument(document);
createPreviewForEditor(editors.takeFirst());
QmlLiveTextPreview *preview
- = m_textPreviews.value(document->filePath());
+ = m_textPreviews.value(document->filePath().toString());
foreach (Core::IEditor *editor, editors)
preview->associateEditor(editor);
}
diff --git a/src/plugins/debugger/qml/qmlinspectoradapter.h b/src/plugins/debugger/qml/qmlinspectoradapter.h
index 6a481dd926..a39f196aba 100644
--- a/src/plugins/debugger/qml/qmlinspectoradapter.h
+++ b/src/plugins/debugger/qml/qmlinspectoradapter.h
@@ -47,11 +47,9 @@ class FileReference;
}
namespace Debugger {
-
-class DebuggerEngine;
-
namespace Internal {
+class DebuggerEngine;
class WatchTreeView;
class QmlAdapter;
class QmlInspectorAgent;
diff --git a/src/plugins/debugger/qml/qmlinspectoragent.cpp b/src/plugins/debugger/qml/qmlinspectoragent.cpp
index 4bf64ed312..0e34026b37 100644
--- a/src/plugins/debugger/qml/qmlinspectoragent.cpp
+++ b/src/plugins/debugger/qml/qmlinspectoragent.cpp
@@ -37,11 +37,11 @@
#include <debugger/watchhandler.h>
#include <qmldebug/qmldebugconstants.h>
+#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
#include <QElapsedTimer>
-#include <QFileInfo>
#include <QLoggingCategory>
using namespace QmlDebug;
@@ -68,7 +68,8 @@ QmlInspectorAgent::QmlInspectorAgent(DebuggerEngine *engine, QObject *parent)
SIGNAL(valueChanged(QVariant)), SLOT(updateState()));
m_delayQueryTimer.setSingleShot(true);
m_delayQueryTimer.setInterval(100);
- connect(&m_delayQueryTimer, SIGNAL(timeout()), SLOT(queryEngineContext()));
+ connect(&m_delayQueryTimer, &QTimer::timeout,
+ this, &QmlInspectorAgent::queryEngineContext);
}
quint32 QmlInspectorAgent::queryExpressionResult(int debugId,
@@ -395,14 +396,14 @@ void QmlInspectorAgent::setEngineClient(BaseEngineDebugClient *client)
m_engineClient = client;
if (m_engineClient) {
- connect(m_engineClient, SIGNAL(newState(QmlDebug::QmlDebugClient::State)),
- this, SLOT(updateState()));
- connect(m_engineClient, SIGNAL(result(quint32,QVariant,QByteArray)),
- this, SLOT(onResult(quint32,QVariant,QByteArray)));
- connect(m_engineClient, SIGNAL(newObject(int,int,int)),
- this, SLOT(newObject(int,int,int)));
- connect(m_engineClient, SIGNAL(valueChanged(int,QByteArray,QVariant)),
- this, SLOT(onValueChanged(int,QByteArray,QVariant)));
+ connect(m_engineClient, &BaseEngineDebugClient::newState,
+ this, &QmlInspectorAgent::updateState);
+ connect(m_engineClient, &BaseEngineDebugClient::result,
+ this, &QmlInspectorAgent::onResult);
+ connect(m_engineClient, &BaseEngineDebugClient::newObject,
+ this, &QmlInspectorAgent::newObject);
+ connect(m_engineClient, &BaseEngineDebugClient::valueChanged,
+ this, &QmlInspectorAgent::onValueChanged);
}
updateState();
@@ -583,7 +584,7 @@ void QmlInspectorAgent::fetchContextObjectsForLocation(const QString &file,
log(LogSend, QString::fromLatin1("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(),
+ quint32 queryId = m_engineClient->queryObjectsForLocation(Utils::FileName::fromString(file).fileName(),
lineNumber, columnNumber);
qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << file << ':' << lineNumber
<< ':' << columnNumber << ')' << " - query id" << queryId;
diff --git a/src/plugins/debugger/qml/qmlinspectoragent.h b/src/plugins/debugger/qml/qmlinspectoragent.h
index 3c19a19c4a..3c01307f15 100644
--- a/src/plugins/debugger/qml/qmlinspectoragent.h
+++ b/src/plugins/debugger/qml/qmlinspectoragent.h
@@ -37,11 +37,9 @@
#include <qmldebug/baseenginedebugclient.h>
namespace Debugger {
-
-class DebuggerEngine;
-
namespace Internal {
+class DebuggerEngine;
class WatchData;
//map <filename, editorRevision> -> <lineNumber, columnNumber> -> debugId
diff --git a/src/plugins/debugger/qml/qmllivetextpreview.cpp b/src/plugins/debugger/qml/qmllivetextpreview.cpp
index 6877d373bd..80ef6220c7 100644
--- a/src/plugins/debugger/qml/qmllivetextpreview.cpp
+++ b/src/plugins/debugger/qml/qmllivetextpreview.cpp
@@ -346,8 +346,8 @@ void MapObjectWithDebugReference::process(UiObjectBinding *ast)
/*!
* Manages a Qml/JS document for the inspector
*/
-QmlLiveTextPreview::QmlLiveTextPreview(const QmlJS::Document::Ptr &doc,
- const QmlJS::Document::Ptr &initDoc,
+QmlLiveTextPreview::QmlLiveTextPreview(const Document::Ptr &doc,
+ const Document::Ptr &initDoc,
QmlInspectorAdapter *inspectorAdapter,
QObject *parent)
: QObject(parent)
@@ -362,8 +362,8 @@ QmlLiveTextPreview::QmlLiveTextPreview(const QmlJS::Document::Ptr &doc,
{
QTC_CHECK(doc->fileName() == initDoc->fileName());
- QmlJS::ModelManagerInterface *modelManager
- = QmlJS::ModelManagerInterface::instance();
+ ModelManagerInterface *modelManager
+ = ModelManagerInterface::instance();
if (modelManager) {
connect(modelManager, SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)),
SLOT(documentChanged(QmlJS::Document::Ptr)));
@@ -424,7 +424,7 @@ void QmlLiveTextPreview::unassociateEditor(Core::IEditor *oldEditor)
}
}
-void QmlLiveTextPreview::resetInitialDoc(const QmlJS::Document::Ptr &doc)
+void QmlLiveTextPreview::resetInitialDoc(const Document::Ptr &doc)
{
m_initialDoc = doc;
m_previousDoc = doc;
@@ -463,7 +463,7 @@ void QmlLiveTextPreview::updateDebugIds()
if (it != m_inspectorAdapter->agent()->debugIdHash().constEnd()) {
// Map all the object that comes from the document as it has been loaded
// by the server.
- const QmlJS::Document::Ptr &doc = m_initialDoc;
+ const Document::Ptr &doc = m_initialDoc;
MapObjectWithDebugReference visitor;
visitor.ids = (*it);
@@ -477,7 +477,7 @@ void QmlLiveTextPreview::updateDebugIds()
}
}
- const QmlJS::Document::Ptr &doc = m_previousDoc;
+ const Document::Ptr &doc = m_previousDoc;
if (!doc->qmlProgram())
return;
@@ -500,7 +500,7 @@ void QmlLiveTextPreview::updateDebugIds()
= m_createdObjects.constBegin();
it != m_createdObjects.constEnd(); ++it) {
- const QmlJS::Document::Ptr &doc = it.key();
+ const Document::Ptr &doc = it.key();
DebugIdHash::const_iterator id_it = m_inspectorAdapter->agent()->debugIdHash().constFind(
qMakePair<QString, int>(doc->fileName(), doc->editorRevision()));
@@ -527,14 +527,14 @@ void QmlLiveTextPreview::updateDebugIds()
changeSelectedElements(m_lastOffsets, QString());
}
-void QmlLiveTextPreview::changeSelectedElements(const QList<QmlJS::AST::UiObjectMember*> offsetObjects,
+void QmlLiveTextPreview::changeSelectedElements(const QList<UiObjectMember*> offsetObjects,
const QString &wordAtCursor)
{
if (m_editors.isEmpty() || !m_previousDoc)
return;
QList<int> offsets;
- foreach (QmlJS::AST::UiObjectMember *member, offsetObjects)
+ foreach (UiObjectMember *member, offsetObjects)
offsets << member->firstSourceLocation().offset;
if (!changeSelectedElements(offsets, wordAtCursor) && m_initialDoc && offsetObjects.count()) {
@@ -588,7 +588,7 @@ bool QmlLiveTextPreview::changeSelectedElements(const QList<int> offsets,
return true;
}
-void QmlLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc)
+void QmlLiveTextPreview::documentChanged(Document::Ptr doc)
{
if (doc->fileName() != m_previousDoc->fileName())
return;
@@ -650,11 +650,11 @@ void QmlLiveTextPreview::onAutomaticUpdateFailed()
QList<int> QmlLiveTextPreview::objectReferencesForOffset(quint32 offset)
{
QList<int> result;
- QHashIterator<QmlJS::AST::UiObjectMember*, QList<int> > iter(m_debugIds);
- QmlJS::AST::UiObjectMember *possibleNode = 0;
+ QHashIterator<UiObjectMember*, QList<int> > iter(m_debugIds);
+ UiObjectMember *possibleNode = 0;
while (iter.hasNext()) {
iter.next();
- QmlJS::AST::UiObjectMember *member = iter.key();
+ UiObjectMember *member = iter.key();
quint32 startOffset = member->firstSourceLocation().offset;
quint32 endOffset = member->lastSourceLocation().offset;
if (startOffset <= offset && offset <= endOffset) {
diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
index f4c0816450..0e119956ca 100644
--- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
+++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
@@ -471,7 +471,7 @@ void QmlV8DebuggerClientPrivate::setBreakpoint(const QString type, const QString
args.setProperty(_(TYPE), QScriptValue(type));
if (type == _(SCRIPTREGEXP))
args.setProperty(_(TARGET),
- QScriptValue(QFileInfo(target).fileName()));
+ QScriptValue(Utils::FileName::fromString(target).fileName()));
else
args.setProperty(_(TARGET), QScriptValue(target));
@@ -842,23 +842,22 @@ void QmlV8DebuggerClient::activateFrame(int index)
d->engine->stackHandler()->setCurrentIndex(index);
}
-bool QmlV8DebuggerClient::acceptsBreakpoint(const BreakpointModelId &id)
+bool QmlV8DebuggerClient::acceptsBreakpoint(Breakpoint bp)
{
- BreakpointType type = d->engine->breakHandler()->breakpointData(id).type;
+ BreakpointType type = bp.type();
return (type == BreakpointOnQmlSignalEmit
|| type == BreakpointByFileAndLine
|| type == BreakpointAtJavaScriptThrow);
}
-void QmlV8DebuggerClient::insertBreakpoint(const BreakpointModelId &id,
+void QmlV8DebuggerClient::insertBreakpoint(Breakpoint bp,
int adjustedLine,
int adjustedColumn)
{
- BreakHandler *handler = d->engine->breakHandler();
- const BreakpointParameters &params = handler->breakpointData(id);
+ const BreakpointParameters &params = bp.parameters();
if (params.type == BreakpointAtJavaScriptThrow) {
- handler->notifyBreakpointInsertOk(id);
+ bp.notifyBreakpointInsertOk();
d->setExceptionBreak(AllExceptions, params.enabled);
} else if (params.type == BreakpointByFileAndLine) {
@@ -868,19 +867,18 @@ void QmlV8DebuggerClient::insertBreakpoint(const BreakpointModelId &id,
} else if (params.type == BreakpointOnQmlSignalEmit) {
d->setBreakpoint(QString(_(EVENT)), params.functionName, params.enabled);
- d->engine->breakHandler()->notifyBreakpointInsertOk(id);
+ bp.notifyBreakpointInsertOk();
}
- d->breakpointsSync.insert(d->sequence, id);
+ d->breakpointsSync.insert(d->sequence, bp.id());
}
-void QmlV8DebuggerClient::removeBreakpoint(const BreakpointModelId &id)
+void QmlV8DebuggerClient::removeBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = d->engine->breakHandler();
- const BreakpointParameters &params = handler->breakpointData(id);
+ const BreakpointParameters &params = bp.parameters();
- int breakpoint = d->breakpoints.value(id);
- d->breakpoints.remove(id);
+ int breakpoint = d->breakpoints.value(bp.id());
+ d->breakpoints.remove(bp.id());
if (params.type == BreakpointAtJavaScriptThrow)
d->setExceptionBreak(AllExceptions);
@@ -890,25 +888,25 @@ void QmlV8DebuggerClient::removeBreakpoint(const BreakpointModelId &id)
d->clearBreakpoint(breakpoint);
}
-void QmlV8DebuggerClient::changeBreakpoint(const BreakpointModelId &id)
+void QmlV8DebuggerClient::changeBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = d->engine->breakHandler();
- const BreakpointParameters &params = handler->breakpointData(id);
+ const BreakpointParameters &params = bp.parameters();
- BreakpointResponse br = handler->response(id);
+ BreakpointResponse br = bp.response();
if (params.type == BreakpointAtJavaScriptThrow) {
d->setExceptionBreak(AllExceptions, params.enabled);
br.enabled = params.enabled;
- handler->setResponse(id, br);
+ bp.setResponse(br);
} else if (params.type == BreakpointOnQmlSignalEmit) {
d->setBreakpoint(QString(_(EVENT)), params.functionName, params.enabled);
br.enabled = params.enabled;
- handler->setResponse(id, br);
+ bp.setResponse(br);
} else {
//V8 supports only minimalistic changes in breakpoint
//Remove the breakpoint and add again
- handler->notifyBreakpointChangeOk(id);
- handler->removeBreakpoint(id);
+ bp.notifyBreakpointChangeOk();
+ bp.removeBreakpoint();
+ BreakHandler *handler = d->engine->breakHandler();
handler->appendBreakpoint(params);
}
}
@@ -984,7 +982,8 @@ void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId
void QmlV8DebuggerClient::setEngine(QmlEngine *engine)
{
d->engine = engine;
- connect(this, SIGNAL(stackFrameCompleted()), engine, SIGNAL(stackFrameCompleted()));
+ connect(this, &QmlV8DebuggerClient::stackFrameCompleted,
+ engine, &QmlEngine::stackFrameCompleted);
}
void QmlV8DebuggerClient::getSourceFiles()
@@ -1086,12 +1085,12 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
//The breakpoint requested line should be same as
//actual line
BreakHandler *handler = d->engine->breakHandler();
- if (handler->state(id) != BreakpointInserted) {
- BreakpointResponse br = handler->response(id);
- br.lineNumber = breakpointData.value(_("line")
- ).toInt() + 1;
- handler->setResponse(id, br);
- handler->notifyBreakpointInsertOk(id);
+ Breakpoint bp = handler->breakpointById(id);
+ if (bp.state() != BreakpointInserted) {
+ BreakpointResponse br = bp.response();
+ br.lineNumber = breakpointData.value(_("line")).toInt() + 1;
+ bp.setResponse(br);
+ bp.notifyBreakpointInsertOk();
}
}
@@ -1211,10 +1210,10 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
BreakHandler *handler = d->engine->breakHandler();
foreach (int v8Id, v8BreakpointIds) {
- const BreakpointModelId internalId = d->breakpoints.key(v8Id);
-
- if (internalId.isValid()) {
- const BreakpointParameters &params = handler->breakpointData(internalId);
+ const BreakpointModelId id = d->breakpoints.key(v8Id);
+ Breakpoint bp = handler->breakpointById(id);
+ if (bp.isValid()) {
+ const BreakpointParameters &params = bp.parameters();
d->clearBreakpoint(v8Id);
d->setBreakpoint(QString(_(SCRIPTREGEXP)),
@@ -1224,7 +1223,7 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
newColumn,
QString(QString::fromLatin1(params.condition)),
params.ignoreCount);
- d->breakpointsSync.insert(d->sequence, internalId);
+ d->breakpointsSync.insert(d->sequence, id);
}
}
d->continueDebugging(Continue);
@@ -1242,17 +1241,18 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
BreakHandler *handler = d->engine->breakHandler();
foreach (int v8Id, v8BreakpointIds) {
const BreakpointModelId id = d->breakpoints.key(v8Id);
- if (id.isValid()) {
- BreakpointResponse br = handler->response(id);
+ Breakpoint bp = handler->breakpointById(id);
+ if (bp) {
+ BreakpointResponse br = bp.response();
if (br.functionName.isEmpty()) {
br.functionName = invocationText;
- handler->setResponse(id, br);
+ bp.setResponse(br);
}
- if (handler->state(id) != BreakpointInserted) {
+ if (bp.state() != BreakpointInserted) {
br.lineNumber = breakData.value(
_("sourceLine")).toInt() + 1;
- handler->setResponse(id, br);
- handler->notifyBreakpointInsertOk(id);
+ bp.setResponse(br);
+ bp.notifyBreakpointInsertOk();
}
}
}
diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h
index 07f360c9d9..524084a11f 100644
--- a/src/plugins/debugger/qml/qmlv8debuggerclient.h
+++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h
@@ -77,11 +77,11 @@ public:
void activateFrame(int index);
- bool acceptsBreakpoint(const BreakpointModelId &id);
- void insertBreakpoint(const BreakpointModelId &id, int adjustedLine,
+ bool acceptsBreakpoint(Breakpoint bp);
+ void insertBreakpoint(Breakpoint bp, int adjustedLine,
int adjustedColumn = -1);
- void removeBreakpoint(const BreakpointModelId &id);
- void changeBreakpoint(const BreakpointModelId &id);
+ void removeBreakpoint(Breakpoint bp);
+ void changeBreakpoint(Breakpoint bp);
void synchronizeBreakpoints();
void assignValueInDebugger(const WatchData *data,
diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp
index 20944d9083..923a1bcb89 100644
--- a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp
+++ b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp
@@ -37,8 +37,9 @@
#include <debugger/debuggerstringutils.h>
#include <qmldebug/qmldebugclient.h>
+#include <coreplugin/messagebox.h>
+
#include <QFileInfo>
-#include <QMessageBox>
#include <utils/qtcassert.h>
using QmlDebug::QmlDebugStream;
@@ -219,9 +220,9 @@ void QScriptDebuggerClient::startSession()
BreakHandler *handler = d->engine->breakHandler();
DebuggerEngine * engine = d->engine->isSlaveEngine() ?
d->engine->masterEngine() : d->engine;
- foreach (BreakpointModelId id, handler->engineBreakpointIds(engine)) {
- QTC_CHECK(handler->state(id) == BreakpointInsertProceeding);
- handler->notifyBreakpointInsertOk(id);
+ foreach (Breakpoint bp, handler->engineBreakpoints(engine)) {
+ QTC_CHECK(bp.state() == BreakpointInsertProceeding);
+ bp.notifyBreakpointInsertOk();
}
d->sessionStarted = true;
}
@@ -246,46 +247,42 @@ void QScriptDebuggerClient::activateFrame(int index)
sendMessage(reply);
}
-void QScriptDebuggerClient::insertBreakpoint(const BreakpointModelId &id,
+void QScriptDebuggerClient::insertBreakpoint(Breakpoint bp,
int adjustedLine,
int /*adjustedColumn*/)
{
- BreakHandler *handler = d->engine->breakHandler();
- JSAgentBreakpointData bp;
- bp.fileUrl = QUrl::fromLocalFile(handler->fileName(id)).toString().toUtf8();
- bp.lineNumber = adjustedLine;
- bp.functionName = handler->functionName(id).toUtf8();
- d->breakpoints.insert(bp);
+ JSAgentBreakpointData jsbp;
+ jsbp.fileUrl = QUrl::fromLocalFile(bp.fileName()).toString().toUtf8();
+ jsbp.lineNumber = adjustedLine;
+ jsbp.functionName = bp.functionName().toUtf8();
+ d->breakpoints.insert(jsbp);
- BreakpointResponse br = handler->response(id);
+ BreakpointResponse br = bp.response();
br.lineNumber = adjustedLine;
- handler->setResponse(id, br);
- if (d->sessionStarted && handler->state(id) == BreakpointInsertProceeding)
- handler->notifyBreakpointInsertOk(id);
+ bp.setResponse(br);
+ if (d->sessionStarted && bp.state() == BreakpointInsertProceeding)
+ bp.notifyBreakpointInsertOk();
}
-void QScriptDebuggerClient::removeBreakpoint(const BreakpointModelId &id)
+void QScriptDebuggerClient::removeBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = d->engine->breakHandler();
- JSAgentBreakpointData bp;
- bp.fileUrl = QUrl::fromLocalFile(handler->fileName(id)).toString().toUtf8();
- bp.lineNumber = handler->lineNumber(id);
- bp.functionName = handler->functionName(id).toUtf8();
- d->breakpoints.remove(bp);
+ JSAgentBreakpointData jsbp;
+ jsbp.fileUrl = QUrl::fromLocalFile(bp.fileName()).toString().toUtf8();
+ jsbp.lineNumber = bp.lineNumber();
+ jsbp.functionName = bp.functionName().toUtf8();
+ d->breakpoints.remove(jsbp);
}
-void QScriptDebuggerClient::changeBreakpoint(const BreakpointModelId &id)
+void QScriptDebuggerClient::changeBreakpoint(Breakpoint bp)
{
- BreakHandler *handler = d->engine->breakHandler();
- if (handler->isEnabled(id)) {
- BreakpointResponse br = handler->response(id);
- insertBreakpoint(id, br.lineNumber);
- } else {
- removeBreakpoint(id);
- }
- BreakpointResponse br = handler->response(id);
- br.enabled = handler->isEnabled(id);
- handler->setResponse(id, br);
+ if (bp.isEnabled())
+ insertBreakpoint(bp, bp.response().lineNumber);
+ else
+ removeBreakpoint(bp);
+
+ BreakpointResponse br = bp.response();
+ br.enabled = bp.isEnabled();
+ bp.setResponse(br);
}
void QScriptDebuggerClient::synchronizeBreakpoints()
@@ -448,7 +445,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
.arg(error.toHtmlEscaped())
: tr("<p>An uncaught exception occurred in \"%1\":</p><p>%2</p>")
.arg(QLatin1String(stackFrames.value(0).fileUrl), error.toHtmlEscaped());
- showMessageBox(QMessageBox::Information, tr("Uncaught Exception"), msg);
+ Core::AsynchronousMessageBox::information(tr("Uncaught Exception"), msg);
} else {
QString file;
int line = -1;
@@ -585,7 +582,8 @@ void QScriptDebuggerClient::insertLocalsAndWatches(QList<WatchData> &locals,
void QScriptDebuggerClient::setEngine(QmlEngine *engine)
{
d->engine = engine;
- connect(this, SIGNAL(stackFrameCompleted()), engine, SIGNAL(stackFrameCompleted()));
+ connect(this, &QScriptDebuggerClient::stackFrameCompleted,
+ engine, &DebuggerEngine::stackFrameCompleted);
}
void QScriptDebuggerClientPrivate::logSendMessage(const QString &msg) const
diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.h b/src/plugins/debugger/qml/qscriptdebuggerclient.h
index 7865bc6b68..a09a1839c2 100644
--- a/src/plugins/debugger/qml/qscriptdebuggerclient.h
+++ b/src/plugins/debugger/qml/qscriptdebuggerclient.h
@@ -62,10 +62,10 @@ public:
void activateFrame(int index);
- void insertBreakpoint(const BreakpointModelId &id, int adjustedLine,
+ void insertBreakpoint(Breakpoint bp, int adjustedLine,
int adjustedColumn = -1);
- void removeBreakpoint(const BreakpointModelId &id);
- void changeBreakpoint(const BreakpointModelId &id);
+ void removeBreakpoint(Breakpoint bp);
+ void changeBreakpoint(Breakpoint bp);
void synchronizeBreakpoints();
void assignValueInDebugger(const WatchData *data, const QString &expression,
diff --git a/src/plugins/debugger/registerhandler.cpp b/src/plugins/debugger/registerhandler.cpp
index 61e3de0b2d..d40536acbb 100644
--- a/src/plugins/debugger/registerhandler.cpp
+++ b/src/plugins/debugger/registerhandler.cpp
@@ -46,518 +46,537 @@ namespace Internal {
//
//////////////////////////////////////////////////////////////////
-enum RegisterType
-{
- RegisterUnknown,
- //RegisterDummy, // like AH if EAX is present.
- RegisterI8,
- RegisterI16,
- RegisterI32,
- RegisterI64,
- RegisterI128,
- RegisterF32,
- RegisterF64,
- RegisterF80,
- RegisterXMM,
- RegisterMMX,
- RegisterNeon,
- RegisterFlags32
-};
-
static struct RegisterNameAndType
{
const char *name;
- RegisterType type;
+ RegisterKind kind;
+ int size;
} theNameAndType[] = {
// ARM
- { "r0", RegisterI32 },
- { "r1", RegisterI32 },
- { "r2", RegisterI32 },
- { "r3", RegisterI32 },
- { "r4", RegisterI32 },
- { "r5", RegisterI32 },
- { "r6", RegisterI32 },
- { "r7", RegisterI32 },
- { "r8", RegisterI32 },
- { "r9", RegisterI32 },
- { "r10", RegisterI32 },
- { "r11", RegisterI32 },
- { "r12", RegisterI32 },
- { "sp", RegisterI32 },
- { "lr", RegisterI32 },
- { "pc", RegisterI32 },
- { "cpsr", RegisterFlags32 },
- { "d0", RegisterI64 },
- { "d1", RegisterI64 },
- { "d2", RegisterI64 },
- { "d3", RegisterI64 },
- { "d4", RegisterI64 },
- { "d5", RegisterI64 },
- { "d6", RegisterI64 },
- { "d7", RegisterI64 },
- { "d8", RegisterI64 },
- { "d9", RegisterI64 },
- { "d10", RegisterI64 },
- { "d11", RegisterI64 },
- { "d12", RegisterI64 },
- { "d13", RegisterI64 },
- { "d14", RegisterI64 },
- { "d15", RegisterI64 },
- { "d16", RegisterI64 },
- { "d17", RegisterI64 },
- { "d18", RegisterI64 },
- { "d19", RegisterI64 },
- { "d20", RegisterI64 },
- { "d21", RegisterI64 },
- { "d22", RegisterI64 },
- { "d23", RegisterI64 },
- { "d24", RegisterI64 },
- { "d25", RegisterI64 },
- { "d26", RegisterI64 },
- { "d27", RegisterI64 },
- { "d28", RegisterI64 },
- { "d29", RegisterI64 },
- { "d30", RegisterI64 },
- { "d31", RegisterI64 },
- { "fpscr", RegisterFlags32 },
- { "s0", RegisterI32 },
- { "s1", RegisterI32 },
- { "s2", RegisterI32 },
- { "s3", RegisterI32 },
- { "s4", RegisterI32 },
- { "s5", RegisterI32 },
- { "s6", RegisterI32 },
- { "s7", RegisterI32 },
- { "s8", RegisterI32 },
- { "s9", RegisterI32 },
- { "s10", RegisterI32 },
- { "s11", RegisterI32 },
- { "s12", RegisterI32 },
- { "s13", RegisterI32 },
- { "s14", RegisterI32 },
- { "s15", RegisterI32 },
- { "s16", RegisterI32 },
- { "s17", RegisterI32 },
- { "s18", RegisterI32 },
- { "s19", RegisterI32 },
- { "s20", RegisterI32 },
- { "s21", RegisterI32 },
- { "s22", RegisterI32 },
- { "s23", RegisterI32 },
- { "s24", RegisterI32 },
- { "s25", RegisterI32 },
- { "s26", RegisterI32 },
- { "s27", RegisterI32 },
- { "s28", RegisterI32 },
- { "s29", RegisterI32 },
- { "s30", RegisterI32 },
- { "s31", RegisterI32 },
- { "q0", RegisterI128 },
- { "q1", RegisterI128 },
- { "q2", RegisterI128 },
- { "q3", RegisterI128 },
- { "q4", RegisterI128 },
- { "q5", RegisterI128 },
- { "q6", RegisterI128 },
- { "q7", RegisterI128 },
- { "q8", RegisterI128 },
- { "q9", RegisterI128 },
- { "q10", RegisterI128 },
- { "q11", RegisterI128 },
- { "q12", RegisterI128 },
- { "q13", RegisterI128 },
- { "q14", RegisterI128 },
- { "q15", RegisterI128 },
+ { "r0", IntegerRegister, 4 },
+ { "r1", IntegerRegister, 4 },
+ { "r2", IntegerRegister, 4 },
+ { "r3", IntegerRegister, 4 },
+ { "r4", IntegerRegister, 4 },
+ { "r5", IntegerRegister, 4 },
+ { "r6", IntegerRegister, 4 },
+ { "r7", IntegerRegister, 4 },
+ { "r8", IntegerRegister, 4 },
+ { "r9", IntegerRegister, 4 },
+ { "r10", IntegerRegister, 4 },
+ { "r11", IntegerRegister, 4 },
+ { "r12", IntegerRegister, 4 },
+ { "sp", IntegerRegister, 4 },
+ { "lr", IntegerRegister, 4 },
+ { "pc", IntegerRegister, 4 },
+ { "cpsr", FlagRegister, 4 },
+ { "d0", IntegerRegister, 8 },
+ { "d1", IntegerRegister, 8 },
+ { "d2", IntegerRegister, 8 },
+ { "d3", IntegerRegister, 8 },
+ { "d4", IntegerRegister, 8 },
+ { "d5", IntegerRegister, 8 },
+ { "d6", IntegerRegister, 8 },
+ { "d7", IntegerRegister, 8 },
+ { "d8", IntegerRegister, 8 },
+ { "d9", IntegerRegister, 8 },
+ { "d10", IntegerRegister, 8 },
+ { "d11", IntegerRegister, 8 },
+ { "d12", IntegerRegister, 8 },
+ { "d13", IntegerRegister, 8 },
+ { "d14", IntegerRegister, 8 },
+ { "d15", IntegerRegister, 8 },
+ { "d16", IntegerRegister, 8 },
+ { "d17", IntegerRegister, 8 },
+ { "d18", IntegerRegister, 8 },
+ { "d19", IntegerRegister, 8 },
+ { "d20", IntegerRegister, 8 },
+ { "d21", IntegerRegister, 8 },
+ { "d22", IntegerRegister, 8 },
+ { "d23", IntegerRegister, 8 },
+ { "d24", IntegerRegister, 8 },
+ { "d25", IntegerRegister, 8 },
+ { "d26", IntegerRegister, 8 },
+ { "d27", IntegerRegister, 8 },
+ { "d28", IntegerRegister, 8 },
+ { "d29", IntegerRegister, 8 },
+ { "d30", IntegerRegister, 8 },
+ { "d31", IntegerRegister, 8 },
+ { "fpscr", FlagRegister, 4 },
+ { "s0", IntegerRegister, 4 },
+ { "s1", IntegerRegister, 4 },
+ { "s2", IntegerRegister, 4 },
+ { "s3", IntegerRegister, 4 },
+ { "s4", IntegerRegister, 4 },
+ { "s5", IntegerRegister, 4 },
+ { "s6", IntegerRegister, 4 },
+ { "s7", IntegerRegister, 4 },
+ { "s8", IntegerRegister, 4 },
+ { "s9", IntegerRegister, 4 },
+ { "s10", IntegerRegister, 4 },
+ { "s11", IntegerRegister, 4 },
+ { "s12", IntegerRegister, 4 },
+ { "s13", IntegerRegister, 4 },
+ { "s14", IntegerRegister, 4 },
+ { "s15", IntegerRegister, 4 },
+ { "s16", IntegerRegister, 4 },
+ { "s17", IntegerRegister, 4 },
+ { "s18", IntegerRegister, 4 },
+ { "s19", IntegerRegister, 4 },
+ { "s20", IntegerRegister, 4 },
+ { "s21", IntegerRegister, 4 },
+ { "s22", IntegerRegister, 4 },
+ { "s23", IntegerRegister, 4 },
+ { "s24", IntegerRegister, 4 },
+ { "s25", IntegerRegister, 4 },
+ { "s26", IntegerRegister, 4 },
+ { "s27", IntegerRegister, 4 },
+ { "s28", IntegerRegister, 4 },
+ { "s29", IntegerRegister, 4 },
+ { "s30", IntegerRegister, 4 },
+ { "s31", IntegerRegister, 4 },
+ { "q0", IntegerRegister, 16 },
+ { "q1", IntegerRegister, 16 },
+ { "q2", IntegerRegister, 16 },
+ { "q3", IntegerRegister, 16 },
+ { "q4", IntegerRegister, 16 },
+ { "q5", IntegerRegister, 16 },
+ { "q6", IntegerRegister, 16 },
+ { "q7", IntegerRegister, 16 },
+ { "q8", IntegerRegister, 16 },
+ { "q9", IntegerRegister, 16 },
+ { "q10", IntegerRegister, 16 },
+ { "q11", IntegerRegister, 16 },
+ { "q12", IntegerRegister, 16 },
+ { "q13", IntegerRegister, 16 },
+ { "q14", IntegerRegister, 16 },
+ { "q15", IntegerRegister, 16 },
// Intel
- { "eax", RegisterI32 },
- { "ecx", RegisterI32 },
- { "edx", RegisterI32 },
- { "ebx", RegisterI32 },
- { "esp", RegisterI32 },
- { "ebp", RegisterI32 },
- { "esi", RegisterI32 },
- { "edi", RegisterI32 },
- { "eip", RegisterI32 },
- { "eflags", RegisterFlags32 },
- { "cs", RegisterI32 },
- { "ss", RegisterI32 },
- { "ds", RegisterI32 },
- { "es", RegisterI32 },
- { "fs", RegisterI32 },
- { "gs", RegisterI32 },
- { "st0", RegisterF80 },
- { "st1", RegisterF80 },
- { "st2", RegisterF80 },
- { "st3", RegisterF80 },
- { "st4", RegisterF80 },
- { "st5", RegisterF80 },
- { "st6", RegisterF80 },
- { "st7", RegisterF80 },
- { "fctrl", RegisterFlags32 },
- { "fstat", RegisterFlags32 },
- { "ftag", RegisterFlags32 },
- { "fiseg", RegisterFlags32 },
- { "fioff", RegisterFlags32 },
- { "foseg", RegisterFlags32 },
- { "fooff", RegisterFlags32 },
- { "fop", RegisterFlags32 },
- { "xmm0", RegisterXMM },
- { "xmm1", RegisterXMM },
- { "xmm2", RegisterXMM },
- { "xmm3", RegisterXMM },
- { "xmm4", RegisterXMM },
- { "xmm5", RegisterXMM },
- { "xmm6", RegisterXMM },
- { "xmm7", RegisterXMM },
- { "mxcsr", RegisterFlags32 },
- { "orig_eax", RegisterI32 },
- { "al", RegisterI8 },
- { "cl", RegisterI8 },
- { "dl", RegisterI8 },
- { "bl", RegisterI8 },
- { "ah", RegisterI8 },
- { "ch", RegisterI8 },
- { "dh", RegisterI8 },
- { "bh", RegisterI8 },
- { "ax", RegisterI16 },
- { "cx", RegisterI16 },
- { "dx", RegisterI16 },
- { "bx", RegisterI16 },
- { "bp", RegisterI16 },
- { "si", RegisterI16 },
- { "di", RegisterI16 },
- { "mm0", RegisterMMX },
- { "mm1", RegisterMMX },
- { "mm2", RegisterMMX },
- { "mm3", RegisterMMX },
- { "mm4", RegisterMMX },
- { "mm5", RegisterMMX },
- { "mm6", RegisterMMX },
- { "mm7", RegisterMMX }
+ { "eax", IntegerRegister, 4 },
+ { "ecx", IntegerRegister, 4 },
+ { "edx", IntegerRegister, 4 },
+ { "ebx", IntegerRegister, 4 },
+ { "esp", IntegerRegister, 4 },
+ { "ebp", IntegerRegister, 4 },
+ { "esi", IntegerRegister, 4 },
+ { "edi", IntegerRegister, 4 },
+ { "eip", IntegerRegister, 4 },
+ { "rax", IntegerRegister, 8 },
+ { "rcx", IntegerRegister, 8 },
+ { "rdx", IntegerRegister, 8 },
+ { "rbx", IntegerRegister, 8 },
+ { "rsp", IntegerRegister, 8 },
+ { "rbp", IntegerRegister, 8 },
+ { "rsi", IntegerRegister, 8 },
+ { "rdi", IntegerRegister, 8 },
+ { "rip", IntegerRegister, 8 },
+ { "eflags", FlagRegister, 4 },
+ { "cs", IntegerRegister, 2 },
+ { "ss", IntegerRegister, 2 },
+ { "ds", IntegerRegister, 2 },
+ { "es", IntegerRegister, 2 },
+ { "fs", IntegerRegister, 2 },
+ { "gs", IntegerRegister, 2 },
+ { "st0", FloatRegister, 10 },
+ { "st1", FloatRegister, 10 },
+ { "st2", FloatRegister, 10 },
+ { "st3", FloatRegister, 10 },
+ { "st4", FloatRegister, 10 },
+ { "st5", FloatRegister, 10 },
+ { "st6", FloatRegister, 10 },
+ { "st7", FloatRegister, 10 },
+ { "fctrl", FlagRegister, 4 },
+ { "fstat", FlagRegister, 4 },
+ { "ftag", FlagRegister, 4 },
+ { "fiseg", FlagRegister, 4 },
+ { "fioff", FlagRegister, 4 },
+ { "foseg", FlagRegister, 4 },
+ { "fooff", FlagRegister, 4 },
+ { "fop", FlagRegister, 4 },
+ { "mxcsr", FlagRegister, 4 },
+ { "orig_eax", IntegerRegister, 4 },
+ { "al", IntegerRegister, 1 },
+ { "cl", IntegerRegister, 1 },
+ { "dl", IntegerRegister, 1 },
+ { "bl", IntegerRegister, 1 },
+ { "ah", IntegerRegister, 1 },
+ { "ch", IntegerRegister, 1 },
+ { "dh", IntegerRegister, 1 },
+ { "bh", IntegerRegister, 1 },
+ { "ax", IntegerRegister, 2 },
+ { "cx", IntegerRegister, 2 },
+ { "dx", IntegerRegister, 2 },
+ { "bx", IntegerRegister, 2 },
+ { "bp", IntegerRegister, 2 },
+ { "si", IntegerRegister, 2 },
+ { "di", IntegerRegister, 2 }
};
-static RegisterType guessType(const QByteArray &name)
+//////////////////////////////////////////////////////////////////
+//
+// RegisterValue
+//
+//////////////////////////////////////////////////////////////////
+
+// FIXME: This should not really be needed. Instead the guessing, if any,
+// should done by the engines.
+static void fixup(Register *reg, RegisterKind kind, int size)
{
- static QHash<QByteArray, RegisterType> theTypes;
- if (theTypes.isEmpty()) {
- for (int i = 0; i != sizeof(theNameAndType) / sizeof(theNameAndType[0]); ++i)
- theTypes[theNameAndType[i].name] = theNameAndType[i].type;
- }
- return theTypes.value(name, RegisterUnknown);
+ reg->kind = kind;
+ if (!reg->size)
+ reg->size = size;
}
-static int childCountFromType(int type)
+void Register::guessMissingData()
{
- switch (type) {
- case RegisterUnknown: return 0;
- case RegisterI8: return 0;
- case RegisterI16: return 1;
- case RegisterI32: return 2;
- case RegisterI64: return 3;
- case RegisterI128: return 4;
- case RegisterF32: return 0;
- case RegisterF64: return 0;
- case RegisterF80: return 0;
- case RegisterXMM: return 3;
- case RegisterMMX: return 3;
- case RegisterNeon: return 3;
- case RegisterFlags32: return 0;
+ if (name.startsWith("xmm")) {
+ fixup(this, VectorRegister, 16);
+ return;
}
+
+ for (int i = 0; i != sizeof(theNameAndType) / sizeof(theNameAndType[0]); ++i) {
+ if (theNameAndType[i].name == name) {
+ fixup(this, theNameAndType[i].kind, theNameAndType[i].size);
+ return;
+ }
+ }
+
+ if (reportedType == "int")
+ fixup(this, IntegerRegister, 4);
+ else if (reportedType == "float")
+ fixup(this, IntegerRegister, 8);
+ else if (reportedType == "_i387_ext")
+ fixup(this, IntegerRegister, 10);
+ else if (reportedType == "*1" || reportedType == "long")
+ fixup(this, IntegerRegister, 0);
+ else if (reportedType.contains("vec"))
+ fixup(this, VectorRegister, 0);
+ else if (reportedType.startsWith("int"))
+ fixup(this, IntegerRegister, 0);
+}
+
+static QString subTypeName(RegisterKind kind, int size)
+{
+ if (kind == IntegerRegister)
+ return QString::fromLatin1("[i%1]").arg(size * 8);
+ if (kind == FloatRegister)
+ return QString::fromLatin1("[f%1]").arg(size * 8);
QTC_ASSERT(false, /**/);
- return 0;
+ return QString();
}
-static int bitWidthFromType(int type, int subType)
+static uint decodeHexChar(unsigned char c)
{
- const uint integer[] = { 8, 16, 32, 64, 128 };
- const uint xmm[] = { 8, 16, 32, 64, 128 };
- const uint mmx[] = { 8, 16, 32, 64, 128 };
- const uint neon[] = { 8, 16, 32, 64, 128 };
-
- switch (type) {
- case RegisterUnknown: return 0;
- case RegisterI8: return 8;
- case RegisterI16: return integer[subType];
- case RegisterI32: return integer[subType];
- case RegisterI64: return integer[subType];
- case RegisterI128: return integer[subType];
- case RegisterF32: return 0;
- case RegisterF64: return 0;
- case RegisterF80: return 0;
- case RegisterXMM: return xmm[subType];
- case RegisterMMX: return mmx[subType];
- case RegisterNeon: return neon[subType];
- case RegisterFlags32: return 0;
+ c -= '0';
+ if (c < 10)
+ return c;
+ c -= 'A' - '0';
+ if (c < 6)
+ return 10 + c;
+ c -= 'a' - 'A';
+ if (c < 6)
+ return 10 + c;
+ return uint(-1);
+}
+
+void RegisterValue::operator=(const QByteArray &ba)
+{
+ uint shift = 0;
+ int j = 0;
+ v.u64[1] = v.u64[0] = 0;
+ for (int i = ba.size(); --i >= 0 && j < 16; ++j) {
+ quint64 d = decodeHexChar(ba.at(i));
+ if (d == uint(-1))
+ return;
+ v.u64[0] |= (d << shift);
+ shift += 4;
+ }
+ j = 0;
+ shift = 0;
+ for (int i = ba.size() - 16; --i >= 0 && j < 16; ++j) {
+ quint64 d = decodeHexChar(ba.at(i));
+ if (d == uint(-1))
+ return;
+ v.u64[1] |= (d << shift);
+ shift += 4;
}
- QTC_ASSERT(false, /**/);
- return 0;
}
-static const uint TopLevelId = UINT_MAX;
-static bool isTopLevelItem(const QModelIndex &index)
+bool RegisterValue::operator==(const RegisterValue &other)
{
- return quintptr(index.internalId()) == quintptr(TopLevelId);
+ return v.u64[0] == other.v.u64[0] && v.u64[1] == other.v.u64[1];
}
-Register::Register(const QByteArray &name_)
- : name(name_), changed(true)
+static QByteArray format(quint64 v, int base, int size)
{
- type = guessType(name);
+ QByteArray result = QByteArray::number(v, base);
+ if (base == 16)
+ result.prepend(QByteArray(2*size - result.size(), '0'));
+ return result;
}
+QByteArray RegisterValue::toByteArray(int base, RegisterKind kind, int size) const
+{
+ if (kind == FloatRegister) {
+ if (size == 4)
+ return QByteArray::number(v.f[0]);
+ if (size == 8)
+ return QByteArray::number(v.d[0]);
+ }
+
+ QByteArray result;
+ if (size > 8) {
+ result += format(v.u64[1], base, size - 8);
+ size = 8;
+ if (base != 16)
+ result += ',';
+ }
+ result += format(v.u64[0], base, size);
+ if (base == 16)
+ result.prepend("0x");
+ return result;
+}
+
+RegisterValue RegisterValue::subValue(int size, int index) const
+{
+ RegisterValue value;
+ switch (size) {
+ case 1:
+ value.v.u8[0] = v.u8[index];
+ break;
+ case 2:
+ value.v.u16[0] = v.u16[index];
+ break;
+ case 4:
+ value.v.u32[0] = v.u32[index];
+ break;
+ case 8:
+ value.v.u64[0] = v.u64[index];
+ break;
+ }
+ return value;
+}
//////////////////////////////////////////////////////////////////
//
-// RegisterHandler
+// RegisterSubItem and RegisterItem
//
//////////////////////////////////////////////////////////////////
-RegisterHandler::RegisterHandler()
+class RegisterSubItem : public Utils::TreeItem
{
- setObjectName(QLatin1String("RegisterModel"));
- m_base = 16;
- calculateWidth();
-#if USE_REGISTER_MODEL_TEST
- new ModelTest(this, 0);
-#endif
-}
+public:
+ RegisterSubItem(RegisterKind subKind, int subSize, int count)
+ : m_subKind(subKind), m_subSize(subSize), m_count(count), m_changed(false)
+ {}
+
+ QVariant data(int column, int role) const;
+
+ Qt::ItemFlags flags(int column) const
+ {
+ //return column == 1 ? Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable
+ // : Qt::ItemIsSelectable|Qt::ItemIsEnabled;
+ Q_UNUSED(column);
+ return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
+ }
-int RegisterHandler::rowCount(const QModelIndex &idx) const
-{
- if (idx.column() > 0)
- return 0;
- if (!idx.isValid())
- return m_registers.size(); // Top level.
- if (!isTopLevelItem(idx))
- return 0; // Sub-Items don't have children.
- if (idx.row() >= m_registers.size())
- return 0;
- return childCountFromType(m_registers[idx.row()].type);
-}
+ RegisterKind m_subKind;
+ int m_subSize;
+ int m_count;
+ bool m_changed;
+};
-int RegisterHandler::columnCount(const QModelIndex &idx) const
+class RegisterItem : public Utils::TreeItem
{
- if (idx.column() > 0)
- return 0;
- if (!idx.isValid())
- return 2;
- if (!isTopLevelItem(idx))
- return 0; // Sub-Items don't have children.
- return 2;
-}
+public:
+ explicit RegisterItem(const Register &reg);
-QModelIndex RegisterHandler::index(int row, int col, const QModelIndex &parent) const
-{
- if (row < 0 || col < 0 || col >= 2)
- return QModelIndex();
- if (!parent.isValid()) // Top level.
- return createIndex(row, col, TopLevelId);
- if (!isTopLevelItem(parent)) // Sub-Item has no children.
- return QModelIndex();
- if (parent.column() > 0)
- return QModelIndex();
- return createIndex(row, col, parent.row());
-}
+ QVariant data(int column, int role) const;
+ Qt::ItemFlags flags(int column) const;
-QModelIndex RegisterHandler::parent(const QModelIndex &idx) const
+ quint64 addressValue() const;
+
+ Register m_reg;
+ int m_base;
+ bool m_changed;
+};
+
+RegisterItem::RegisterItem(const Register &reg) :
+ m_reg(reg), m_base(16), m_changed(true)
{
- if (!idx.isValid())
- return QModelIndex();
- if (!isTopLevelItem(idx))
- return createIndex(idx.internalId(), 0, TopLevelId);
- return QModelIndex();
+ if (m_reg.kind == UnknownRegister)
+ m_reg.guessMissingData();
+
+ if (m_reg.kind == IntegerRegister || m_reg.kind == VectorRegister) {
+ for (int s = m_reg.size / 2; s; s = s / 2)
+ appendChild(new RegisterSubItem(IntegerRegister, s, m_reg.size / s));
+ }
+ if (m_reg.kind == IntegerRegister || m_reg.kind == VectorRegister) {
+ for (int s = m_reg.size; s >= 4; s = s / 2)
+ appendChild(new RegisterSubItem(FloatRegister, s, m_reg.size / s));
+ }
}
-// Editor value: Preferably number, else string.
-QVariant Register::editValue() const
+Qt::ItemFlags RegisterItem::flags(int column) const
{
- bool ok = true;
- // Try to convert to number?
- const qulonglong v = value.toULongLong(&ok, 0); // Autodetect format
- if (ok)
- return QVariant(v);
- return QVariant(value);
+ const Qt::ItemFlags notEditable = Qt::ItemIsSelectable|Qt::ItemIsEnabled;
+ // Can edit registers if they are hex numbers and not arrays.
+ if (column == 1) // && IntegerWatchLineEdit::isUnsignedHexNumber(QLatin1String(m_reg.display)))
+ return notEditable | Qt::ItemIsEditable;
+ return notEditable;
}
-// Editor value: Preferably padded number, else padded string.
-QString Register::displayValue(int base, int strlen) const
+quint64 RegisterItem::addressValue() const
{
- const QVariant editV = editValue();
- if (editV.type() == QVariant::ULongLong)
- return QString::fromLatin1("%1").arg(editV.toULongLong(), strlen, base);
- const QString stringValue = editV.toString();
- if (stringValue.size() < strlen)
- return QString(strlen - stringValue.size(), QLatin1Char(' ')) + QLatin1String(value);
- return stringValue;
+ return m_reg.value.v.u64[0];
}
-QVariant RegisterHandler::data(const QModelIndex &index, int role) const
+QVariant RegisterItem::data(int column, int role) const
{
- if (!index.isValid())
- return QVariant();
+ switch (role) {
+ case RegisterNameRole:
+ return m_reg.name;
- QModelIndex topLevel = index.parent();
- const int mainRow = topLevel.isValid() ? topLevel.row() : index.row();
+ case RegisterIsBigRole:
+ return m_reg.value.v.u64[1] > 0;
- if (mainRow >= m_registers.size())
- return QVariant();
+ case RegisterChangedRole:
+ return m_changed;
+ case RegisterNumberBaseRole:
+ return m_base;
- const Register &reg = m_registers.at(mainRow);
+ case RegisterAsAddressRole:
+ return addressValue();
- if (topLevel.isValid()) {
- //
- // Nested
- //
- int subType = index.row();
- int bitWidth = bitWidthFromType(reg.type, subType);
-
- switch (role) {
case Qt::DisplayRole:
- switch (index.column()) {
- case 0: {
- switch (bitWidth) {
- case 8: return QLatin1String("[Bytes]");
- case 16: return QLatin1String("[Words]");
- case 32: return QLatin1String("[DWords]");
- case 64: return QLatin1String("[QWords]");
- case 128: return QLatin1String("[TWords]");
- case -32: return QLatin1String("[Single]");
- case -64: return QLatin1String("[Double]");
- return QVariant(bitWidth);
+ switch (column) {
+ case 0: {
+ QByteArray res = m_reg.name;
+ if (!m_reg.description.isEmpty())
+ res += " (" + m_reg.description + ')';
+ return res;
+ }
+ case 1: {
+ return m_reg.value.toByteArray(m_base, m_reg.kind, m_reg.size);
}
}
- }
- default:
- break;
- }
- } else {
- //
- // Toplevel
- //
+ case Qt::ToolTipRole:
+ return QString::fromLatin1("Current Value: %1\nPreviousValue: %2")
+ .arg(QString::fromLatin1(m_reg.value.toByteArray(m_base, m_reg.kind, m_reg.size)))
+ .arg(QString::fromLatin1(m_reg.previousValue.toByteArray(m_base, m_reg.kind, m_reg.size)));
- switch (role) {
- case Qt::DisplayRole:
- switch (index.column()) {
- case 0: {
- const QString padding = QLatin1String(" ");
- return QVariant(padding + QLatin1String(reg.name) + padding);
- //return QVariant(reg.name);
- }
- case 1: // Display: Pad value for alignment
- return reg.displayValue(m_base, m_strlen);
- } // switch column
case Qt::EditRole: // Edit: Unpadded for editing
- return reg.editValue();
+ return m_reg.value.toByteArray(m_base, m_reg.kind, m_reg.size);
+
case Qt::TextAlignmentRole:
- return index.column() == 1 ? QVariant(Qt::AlignRight) : QVariant();
+ return column == 1 ? QVariant(Qt::AlignRight) : QVariant();
+
default:
break;
- }
}
return QVariant();
}
-QVariant RegisterHandler::headerData(int section, Qt::Orientation orientation,
- int role) const
+QVariant RegisterSubItem::data(int column, int role) const
{
- if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
- switch (section) {
- case 0: return tr("Name");
- case 1: return tr("Value (Base %1)").arg(m_base);
- };
- }
- return QVariant();
-}
+ switch (role) {
+ case RegisterChangedRole:
+ return m_changed;
-Qt::ItemFlags RegisterHandler::flags(const QModelIndex &idx) const
-{
- if (!idx.isValid())
- return Qt::ItemFlags();
+ case RegisterNumberBaseRole:
+ return 16;
- const Qt::ItemFlags notEditable = Qt::ItemIsSelectable|Qt::ItemIsEnabled;
- // Can edit registers if they are hex numbers and not arrays.
- if (idx.column() == 1
- && IntegerWatchLineEdit::isUnsignedHexNumber(QLatin1String(m_registers.at(idx.row()).value)))
- return notEditable | Qt::ItemIsEditable;
- return notEditable;
-}
+ case RegisterAsAddressRole:
+ return 0;
-void RegisterHandler::removeAll()
-{
- beginResetModel();
- m_registers.clear();
- endResetModel();
-}
+ case Qt::DisplayRole:
+ switch (column) {
+ case 0:
+ return subTypeName(m_subKind, m_subSize);
+ case 1: {
+ QTC_ASSERT(parent(), return QVariant());
+ RegisterItem *registerItem = static_cast<RegisterItem *>(parent());
+ RegisterValue value = registerItem->m_reg.value;
+ QByteArray ba;
+ for (int i = 0; i != m_count; ++i) {
+ ba += value.subValue(m_subSize, i).toByteArray(16, m_subKind, m_subSize);
+ int tab = 5 * (i + 1) * m_subSize;
+ ba += QByteArray(tab - ba.size(), ' ');
+ }
+ return ba;
+ }
+ }
+ default:
+ break;
+ }
-bool RegisterHandler::isEmpty() const
-{
- return m_registers.isEmpty();
+ return QVariant();
}
-// Compare register sets by name
-static inline bool compareRegisterSet(const Registers &r1, const Registers &r2)
-{
- if (r1.size() != r2.size())
- return false;
- const int size = r1.size();
- for (int r = 0; r < size; r++)
- if (r1.at(r).name != r2.at(r).name)
- return false;
- return true;
-}
+//////////////////////////////////////////////////////////////////
+//
+// RegisterHandler
+//
+//////////////////////////////////////////////////////////////////
-void RegisterHandler::setRegisters(const Registers &registers)
+RegisterHandler::RegisterHandler()
{
- beginResetModel();
- m_registers = registers;
- const int size = m_registers.size();
- for (int r = 0; r < size; r++)
- m_registers[r].changed = false;
- calculateWidth();
- endResetModel();
+ setObjectName(QLatin1String("RegisterModel"));
+ setHeader(QStringList() << tr("Name") << tr("Value"));
+
+#if USE_REGISTER_MODEL_TEST
+ new ModelTest(this, 0);
+#endif
}
-void RegisterHandler::setAndMarkRegisters(const Registers &registers)
+void RegisterHandler::updateRegister(const Register &r)
{
- if (!compareRegisterSet(m_registers, registers)) {
- setRegisters(registers);
+ RegisterItem *reg = m_registerByName.value(r.name, 0);
+ if (!reg) {
+ reg = new RegisterItem(r);
+ m_registerByName[r.name] = reg;
+ rootItem()->appendChild(reg);
return;
}
- const int size = m_registers.size();
- for (int r = 0; r != size; ++r) {
- const QModelIndex regIndex = index(r, 1, QModelIndex());
- if (m_registers.at(r).value != registers.at(r).value) {
- // Indicate red if values change, keep changed.
- m_registers[r].changed = m_registers.at(r).changed
- || !m_registers.at(r).value.isEmpty();
- m_registers[r].value = registers.at(r).value;
- emit dataChanged(regIndex, regIndex);
- }
- emit registerSet(regIndex); // Notify attached memory views.
- }
-}
-Registers RegisterHandler::registers() const
-{
- return m_registers;
+ if (r.size > 0)
+ reg->m_reg.size = r.size;
+ if (!r.description.isEmpty())
+ reg->m_reg.description = r.description;
+ if (reg->m_reg.value != r.value) {
+ // Indicate red if values change, keep changed.
+ reg->m_changed = true;
+ reg->m_reg.previousValue = reg->m_reg.value;
+ reg->m_reg.value = r.value;
+ emit registerChanged(reg->m_reg.name, reg->addressValue()); // Notify attached memory views.
+ } else {
+ reg->m_changed = false;
+ }
}
-void RegisterHandler::calculateWidth()
+void RegisterHandler::setNumberBase(const QByteArray &name, int base)
{
- m_strlen = (m_base == 2 ? 64 : m_base == 8 ? 32 : m_base == 10 ? 26 : 16);
+ RegisterItem *reg = m_registerByName.value(name, 0);
+ QTC_ASSERT(reg, return);
+ reg->m_base = base;
+ QModelIndex index = indexFromItem(reg);
+ emit dataChanged(index, index);
}
-void RegisterHandler::setNumberBase(int base)
+RegisterMap RegisterHandler::registerMap() const
{
- if (m_base != base) {
- beginResetModel();
- m_base = base;
- calculateWidth();
- endResetModel();
+ RegisterMap result;
+ Utils::TreeItem *root = rootItem();
+ for (int i = 0, n = root->rowCount(); i != n; ++i) {
+ RegisterItem *reg = static_cast<RegisterItem *>(root->child(i));
+ quint64 value = reg->addressValue();
+ if (value)
+ result.insert(value, reg->m_reg.name);
}
+ return result;
}
} // namespace Internal
diff --git a/src/plugins/debugger/registerhandler.h b/src/plugins/debugger/registerhandler.h
index a2c843dd6e..f22b52a14d 100644
--- a/src/plugins/debugger/registerhandler.h
+++ b/src/plugins/debugger/registerhandler.h
@@ -31,35 +31,73 @@
#ifndef DEBUGGER_REGISTERHANDLER_H
#define DEBUGGER_REGISTERHANDLER_H
+#include <utils/treemodel.h>
+
#include <QAbstractTableModel>
+#include <QHash>
#include <QVector>
namespace Debugger {
namespace Internal {
-class Register
+enum RegisterDataRole
{
-public:
- Register() : type(0), changed(true) {}
- Register(const QByteArray &name_);
+ RegisterNameRole = Qt::UserRole,
+ RegisterIsBigRole,
+ RegisterChangedRole,
+ RegisterNumberBaseRole,
+ RegisterAsAddressRole
+};
+
+enum RegisterKind
+{
+ UnknownRegister,
+ IntegerRegister,
+ FloatRegister,
+ VectorRegister,
+ FlagRegister,
+ OtherRegister
+};
- QVariant editValue() const;
- QString displayValue(int base, int strlen) const;
+class RegisterValue
+{
+public:
+ RegisterValue() { v.u64[1] = v.u64[0] = 0; }
+ void operator=(const QByteArray &ba);
+ bool operator==(const RegisterValue &other);
+ bool operator!=(const RegisterValue &other) { return !operator==(other); }
+ QByteArray toByteArray(int base, RegisterKind kind, int size) const;
+ RegisterValue subValue(int size, int index) const;
+
+ union {
+ quint8 u8[16];
+ quint16 u16[8];
+ quint32 u32[4];
+ quint64 u64[2];
+ float f[4];
+ double d[2];
+ } v;
+};
+class Register
+{
public:
+ Register() { size = 0; kind = UnknownRegister; }
+ void guessMissingData();
+
QByteArray name;
- /* Value should be an integer for which autodetection by passing
- * base=0 to QString::toULongLong() should work (C-language conventions).
- * Values that cannot be converted (such as 128bit MMX-registers) are
- * passed through. */
- QByteArray value;
- int type;
- bool changed;
+ QByteArray reportedType;
+ RegisterValue value;
+ RegisterValue previousValue;
+ QByteArray description;
+ int size;
+ RegisterKind kind;
};
-typedef QVector<Register> Registers;
+class RegisterItem;
+typedef QMap<quint64, QByteArray> RegisterMap;
-class RegisterHandler : public QAbstractTableModel
+class RegisterHandler : public Utils::TreeModel
{
Q_OBJECT
@@ -68,34 +106,17 @@ public:
QAbstractItemModel *model() { return this; }
- bool isEmpty() const; // nothing known so far?
- // Set up register names (gdb)
- void setRegisters(const Registers &registers);
- // Set register values
- void setAndMarkRegisters(const Registers &registers);
- Registers registers() const;
- Register registerAt(int i) const { return m_registers.at(i); }
- void removeAll();
- Q_SLOT void setNumberBase(int base);
- int numberBase() const { return m_base; }
+ void updateRegister(const Register &reg);
+
+ void setNumberBase(const QByteArray &name, int base);
+ void commitUpdates() { emit layoutChanged(); }
+ RegisterMap registerMap() const;
signals:
- void registerSet(const QModelIndex &r); // Register was set, for memory views
+ void registerChanged(const QByteArray &name, quint64 value); // For memory views
private:
- void calculateWidth();
- int rowCount(const QModelIndex &idx = QModelIndex()) const;
- int columnCount(const QModelIndex &idx = QModelIndex()) const;
- QModelIndex index(int row, int col, const QModelIndex &parent) const;
- QModelIndex parent(const QModelIndex &idx) const;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- Qt::ItemFlags flags(const QModelIndex &idx) const;
-
- Registers m_registers;
- int m_base;
- int m_strlen; // approximate width of a value in chars.
+ QHash<QByteArray, RegisterItem *> m_registerByName;
};
} // namespace Internal
diff --git a/src/plugins/debugger/registerwindow.cpp b/src/plugins/debugger/registerwindow.cpp
index c75af5547a..724feeb8eb 100644
--- a/src/plugins/debugger/registerwindow.cpp
+++ b/src/plugins/debugger/registerwindow.cpp
@@ -30,6 +30,7 @@
#include "registerwindow.h"
#include "memoryview.h"
+#include "memoryagent.h"
#include "debuggeractions.h"
#include "debuggerdialogs.h"
#include "debuggercore.h"
@@ -42,22 +43,13 @@
#include <utils/qtcassert.h>
#include <QDebug>
-
#include <QItemDelegate>
#include <QMenu>
#include <QPainter>
-
namespace Debugger {
namespace Internal {
-static RegisterHandler *currentHandler()
-{
- DebuggerEngine *engine = currentEngine();
- QTC_ASSERT(engine, return 0);
- return engine->registerHandler();
-}
-
///////////////////////////////////////////////////////////////////////
//
// RegisterDelegate
@@ -74,10 +66,9 @@ public:
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
const QModelIndex &index) const
{
- Register reg = currentHandler()->registerAt(index.row());
IntegerWatchLineEdit *lineEdit = new IntegerWatchLineEdit(parent);
- const int base = currentHandler()->numberBase();
- const bool big = reg.value.size() > 16;
+ const int base = index.data(RegisterNumberBaseRole).toInt();
+ const bool big = index.data(RegisterIsBigRole).toBool();
// Big integers are assumed to be hexadecimal.
lineEdit->setBigInt(big);
lineEdit->setBase(big ? 16 : base);
@@ -101,11 +92,11 @@ public:
return;
IntegerWatchLineEdit *lineEdit = qobject_cast<IntegerWatchLineEdit*>(editor);
QTC_ASSERT(lineEdit, return);
- const int base = currentHandler()->numberBase();
+ const int base = index.data(RegisterNumberBaseRole).toInt();
QString value = lineEdit->text();
if (base == 16 && !value.startsWith(QLatin1String("0x")))
value.insert(0, QLatin1String("0x"));
- currentEngine()->setRegisterValue(index.row(), value);
+ currentEngine()->setRegisterValue(index.data(RegisterNameRole).toByteArray(), value);
}
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
@@ -118,28 +109,38 @@ public:
const QModelIndex &index) const
{
if (index.column() == 1) {
- bool paintRed = currentHandler()->registerAt(index.row()).changed;
+ const bool paintRed = index.data(RegisterChangedRole).toBool();
QPen oldPen = painter->pen();
+ const QColor lightColor(140, 140, 140);
if (paintRed)
painter->setPen(QColor(200, 0, 0));
+ else
+ painter->setPen(lightColor);
// FIXME: performance? this changes only on real font changes.
QFontMetrics fm(option.font);
- int charWidth = fm.width(QLatin1Char('x'));
- for (int i = '1'; i <= '9'; ++i)
- charWidth = qMax(charWidth, fm.width(QLatin1Char(i)));
- for (int i = 'a'; i <= 'f'; ++i)
- charWidth = qMax(charWidth, fm.width(QLatin1Char(i)));
+ int charWidth = qMax(fm.width(QLatin1Char('x')), fm.width(QLatin1Char('0')));
QString str = index.data(Qt::DisplayRole).toString();
int x = option.rect.x();
+ bool light = !paintRed;
for (int i = 0; i < str.size(); ++i) {
- QRect r = option.rect;
- r.setX(x);
- r.setWidth(charWidth);
+ const QChar c = str.at(i);
+ const int uc = c.unicode();
+ if (light && (uc != 'x' && uc != '0')) {
+ light = false;
+ painter->setPen(oldPen.color());
+ }
+ if (uc == ' ') {
+ light = true;
+ painter->setPen(lightColor);
+ } else {
+ QRect r = option.rect;
+ r.setX(x);
+ r.setWidth(charWidth);
+ painter->drawText(r, Qt::AlignHCenter, c);
+ }
x += charWidth;
- painter->drawText(r, Qt::AlignHCenter, QString(str.at(i)));
}
- if (paintRed)
- painter->setPen(oldPen);
+ painter->setPen(oldPen);
} else {
QItemDelegate::paint(painter, option, index);
}
@@ -156,6 +157,7 @@ public:
RegisterTreeView::RegisterTreeView()
{
setItemDelegate(new RegisterDelegate(this));
+ setRootIsDecorated(true);
}
void RegisterTreeView::contextMenuEvent(QContextMenuEvent *ev)
@@ -164,7 +166,8 @@ void RegisterTreeView::contextMenuEvent(QContextMenuEvent *ev)
DebuggerEngine *engine = currentEngine();
QTC_ASSERT(engine, return);
- RegisterHandler *handler = currentHandler();
+ RegisterHandler *handler = engine->registerHandler();
+
const bool actionsEnabled = engine->debuggerActionsEnabled();
const DebuggerState state = engine->state();
@@ -174,13 +177,8 @@ void RegisterTreeView::contextMenuEvent(QContextMenuEvent *ev)
menu.addSeparator();
- Register aRegister;
const QModelIndex idx = indexAt(ev->pos());
- if (idx.isValid())
- aRegister = handler->registers().at(idx.row());
- const QVariant addressV = aRegister.editValue();
- const quint64 address = addressV.type() == QVariant::ULongLong
- ? addressV.toULongLong() : 0;
+ const quint64 address = idx.data(RegisterAsAddressRole).toULongLong();
QAction *actViewMemory = menu.addAction(QString());
QAction *actEditMemory = menu.addAction(QString());
@@ -188,12 +186,14 @@ void RegisterTreeView::contextMenuEvent(QContextMenuEvent *ev)
QAction *actShowDisassembler = menu.addAction(tr("Open Disassembler..."));
actShowDisassembler->setEnabled(engine->hasCapability(DisassemblerCapability));
+ const QByteArray registerName = idx.data(RegisterNameRole).toByteArray();
+ const QString registerNameStr = QString::fromUtf8(registerName);
if (address) {
const bool canShow = actionsEnabled && engine->hasCapability(ShowMemoryCapability);
actEditMemory->setText(tr("Open Memory Editor at 0x%1").arg(address, 0, 16));
actEditMemory->setEnabled(canShow);
actViewMemory->setText(tr("Open Memory View at Value of Register %1 0x%2")
- .arg(QString::fromLatin1(aRegister.name)).arg(address, 0, 16));
+ .arg(registerNameStr).arg(address, 0, 16));
actShowDisassemblerAt->setText(tr("Open Disassembler at 0x%1")
.arg(address, 0, 16));
actShowDisassemblerAt->setEnabled(engine->hasCapability(DisassemblerCapability));
@@ -207,7 +207,7 @@ void RegisterTreeView::contextMenuEvent(QContextMenuEvent *ev)
}
menu.addSeparator();
- const int base = handler->numberBase();
+ const int base = idx.data(RegisterNumberBaseRole).toInt();
QAction *act16 = menu.addAction(tr("Hexadecimal"));
act16->setCheckable(true);
act16->setChecked(base == 16);
@@ -230,14 +230,20 @@ void RegisterTreeView::contextMenuEvent(QContextMenuEvent *ev)
if (act == actReload) {
engine->reloadRegisters();
} else if (act == actEditMemory) {
- const QString registerName = QString::fromLatin1(aRegister.name);
- engine->openMemoryView(address, 0,
- RegisterMemoryView::registerMarkup(address, registerName),
- QPoint(), RegisterMemoryView::title(registerName), 0);
+ MemoryViewSetupData data;
+ data.startAddress = address;
+ data.registerName = registerName;
+ data.markup = RegisterMemoryView::registerMarkup(address, registerName);
+ data.title = RegisterMemoryView::title(registerName);
+ engine->openMemoryView(data);
} else if (act == actViewMemory) {
- engine->openMemoryView(idx.row(),
- DebuggerEngine::MemoryTrackRegister|DebuggerEngine::MemoryView,
- QList<MemoryMarkup>(), position, QString(), this);
+ MemoryViewSetupData data;
+ data.startAddress = address;
+ data.flags = DebuggerEngine::MemoryTrackRegister|DebuggerEngine::MemoryView,
+ data.registerName = registerName;
+ data.pos = position;
+ data.parent = this;
+ engine->openMemoryView(data);
} else if (act == actShowDisassembler) {
AddressDialog dialog;
if (address)
@@ -247,13 +253,13 @@ void RegisterTreeView::contextMenuEvent(QContextMenuEvent *ev)
} else if (act == actShowDisassemblerAt) {
engine->openDisassemblerView(Location(address));
} else if (act == act16)
- handler->setNumberBase(16);
+ handler->setNumberBase(registerName, 16);
else if (act == act10)
- handler->setNumberBase(10);
+ handler->setNumberBase(registerName, 10);
else if (act == act8)
- handler->setNumberBase(8);
+ handler->setNumberBase(registerName, 8);
else if (act == act2)
- handler->setNumberBase(2);
+ handler->setNumberBase(registerName, 2);
}
void RegisterTreeView::reloadRegisters()
diff --git a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
index 020837c718..7e0628120a 100644
--- a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
+++ b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
@@ -31,6 +31,7 @@
#include "cdbsymbolpathlisteditor.h"
#include <coreplugin/icore.h>
+#include <coreplugin/messagebox.h>
#include <utils/pathchooser.h>
#include <utils/checkablemessagebox.h>
@@ -67,8 +68,8 @@ CacheDirectoryDialog::CacheDirectoryDialog(QWidget *parent) :
setLayout(mainLayout);
- connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
- connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(m_buttonBox, &QDialogButtonBox::accepted, this, &CacheDirectoryDialog::accept);
+ connect(m_buttonBox, &QDialogButtonBox::rejected, this, &CacheDirectoryDialog::reject);
}
void CacheDirectoryDialog::setPath(const QString &p)
@@ -98,15 +99,15 @@ void CacheDirectoryDialog::accept()
}
// Does a file of the same name exist?
if (fi.exists()) {
- QMessageBox::warning(this, tr("Already Exists"),
- tr("A file named \"%1\" already exists.").arg(cache));
+ Core::AsynchronousMessageBox::warning(tr("Already Exists"),
+ tr("A file named \"%1\" already exists.").arg(cache));
return;
}
// Create
QDir root(QDir::root());
if (!root.mkpath(cache)) {
- QMessageBox::warning(this, tr("Cannot Create"),
- tr("The folder \"%1\" could not be created.").arg(cache));
+ Core::AsynchronousMessageBox::warning(tr("Cannot Create"),
+ tr("The folder \"%1\" could not be created.").arg(cache));
return;
}
QDialog::accept();
diff --git a/src/plugins/debugger/snapshothandler.h b/src/plugins/debugger/snapshothandler.h
index 9cd3ee35e9..0a7c0f0441 100644
--- a/src/plugins/debugger/snapshothandler.h
+++ b/src/plugins/debugger/snapshothandler.h
@@ -35,18 +35,16 @@
#include <QPointer>
namespace Debugger {
+namespace Internal {
class DebuggerEngine;
-namespace Internal {
-
////////////////////////////////////////////////////////////////////////
//
// SnapshotModel
//
////////////////////////////////////////////////////////////////////////
-
class SnapshotHandler : public QAbstractTableModel
{
Q_OBJECT
diff --git a/src/plugins/debugger/sourceagent.cpp b/src/plugins/debugger/sourceagent.cpp
index 69e438d895..937836c229 100644
--- a/src/plugins/debugger/sourceagent.cpp
+++ b/src/plugins/debugger/sourceagent.cpp
@@ -40,16 +40,16 @@
#include <cppeditor/cppeditorconstants.h>
+#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <QDebug>
-#include <QFileInfo>
-
#include <QTextBlock>
#include <limits.h>
using namespace Core;
+using namespace TextEditor;
namespace Debugger {
namespace Internal {
@@ -61,9 +61,9 @@ public:
~SourceAgentPrivate();
public:
- QPointer<TextEditor::BaseTextEditor> editor;
+ QPointer<BaseTextEditor> editor;
QPointer<DebuggerEngine> engine;
- TextEditor::TextMark *locationMark;
+ TextMark *locationMark;
QString path;
QString producer;
};
@@ -73,7 +73,6 @@ SourceAgentPrivate::SourceAgentPrivate()
, locationMark(0)
, producer(QLatin1String("remote"))
{
-
}
SourceAgentPrivate::~SourceAgentPrivate()
@@ -104,14 +103,11 @@ void SourceAgent::setSourceProducerName(const QString &name)
void SourceAgent::setContent(const QString &filePath, const QString &content)
{
QTC_ASSERT(d, return);
- using namespace Core;
- using namespace TextEditor;
-
d->path = filePath;
if (!d->editor) {
QString titlePattern = d->producer + QLatin1String(": ")
- + QFileInfo(filePath).fileName();
+ + Utils::FileName::fromString(filePath).fileName();
d->editor = qobject_cast<BaseTextEditor *>(
EditorManager::openEditorWithContents(
CppEditor::Constants::CPPEDITOR_ID,
@@ -143,9 +139,11 @@ void SourceAgent::updateLocationMarker()
d->locationMark = 0;
if (d->engine->stackHandler()->currentFrame().file == d->path) {
int lineNumber = d->engine->stackHandler()->currentFrame().line;
- d->locationMark = new TextEditor::TextMark(QString(), lineNumber);
- d->locationMark->setIcon(Internal::locationMarkIcon());
- d->locationMark->setPriority(TextEditor::TextMark::HighPriority);
+
+ d->locationMark = new TextMark(QString(), lineNumber);
+ d->locationMark->setIcon(locationMarkIcon());
+ d->locationMark->setPriority(TextMark::HighPriority);
+
d->editor->textDocument()->addMark(d->locationMark);
QTextCursor tc = d->editor->textCursor();
QTextBlock block = tc.document()->findBlockByNumber(lineNumber - 1);
diff --git a/src/plugins/debugger/sourceagent.h b/src/plugins/debugger/sourceagent.h
index c2c301d59f..3727023e7d 100644
--- a/src/plugins/debugger/sourceagent.h
+++ b/src/plugins/debugger/sourceagent.h
@@ -34,16 +34,15 @@
#include <QString>
namespace Debugger {
-
-class DebuggerEngine;
-
namespace Internal {
+class DebuggerEngine;
class SourceAgentPrivate;
+
class SourceAgent
{
public:
- explicit SourceAgent(Debugger::DebuggerEngine *engine);
+ explicit SourceAgent(DebuggerEngine *engine);
~SourceAgent();
void setSourceProducerName(const QString &name);
void resetLocation();
diff --git a/src/plugins/debugger/sourceutils.cpp b/src/plugins/debugger/sourceutils.cpp
index 0c6e96e502..9e1d80bf9b 100644
--- a/src/plugins/debugger/sourceutils.cpp
+++ b/src/plugins/debugger/sourceutils.cpp
@@ -264,7 +264,7 @@ bool getUninitializedVariables(const Snapshot &snapshot,
bool isCppEditor(TextEditorWidget *editorWidget)
{
const TextDocument *document = editorWidget->textDocument();
- return ProjectFile::classify(document->filePath()) != ProjectFile::Unclassified;
+ return ProjectFile::classify(document->filePath().toString()) != ProjectFile::Unclassified;
}
QString cppFunctionAt(const QString &fileName, int line, int column)
@@ -282,7 +282,6 @@ QString cppExpressionAt(TextEditorWidget *editorWidget, int pos,
int *line, int *column, QString *function,
int *scopeFromLine, int *scopeToLine)
{
- *line = *column = 0;
if (function)
function->clear();
@@ -297,15 +296,13 @@ QString cppExpressionAt(TextEditorWidget *editorWidget, int pos,
// Fetch the expression's code.
ExpressionUnderCursor expressionUnderCursor;
expr = expressionUnderCursor(tc);
- *column = tc.positionInBlock();
- *line = tc.blockNumber();
- } else {
- *column = tc.positionInBlock();
- *line = tc.blockNumber();
}
+ *column = tc.positionInBlock();
+ *line = tc.blockNumber() + 1;
+
if (!expr.isEmpty()) {
- QString fileName = editorWidget->textDocument()->filePath();
+ QString fileName = editorWidget->textDocument()->filePath().toString();
const Snapshot snapshot = CppModelManager::instance()->snapshot();
if (const Document::Ptr document = snapshot.document(fileName)) {
QString func = document->functionAt(*line, *column, scopeFromLine, scopeToLine);
diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp
index dfeeb66084..ec5fe96641 100644
--- a/src/plugins/debugger/stackhandler.cpp
+++ b/src/plugins/debugger/stackhandler.cpp
@@ -34,11 +34,11 @@
#include "debuggercore.h"
#include "simplifytype.h"
+#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
#include <QDebug>
-#include <QFileInfo>
namespace Debugger {
namespace Internal {
@@ -64,8 +64,8 @@ StackHandler::StackHandler()
m_contentsValid = false;
m_currentIndex = -1;
m_canExpand = false;
- connect(action(OperateByInstruction), SIGNAL(triggered()),
- this, SLOT(resetModel()));
+ connect(action(OperateByInstruction), &QAction::triggered,
+ this, &StackHandler::resetModel);
}
StackHandler::~StackHandler()
@@ -80,7 +80,7 @@ int StackHandler::rowCount(const QModelIndex &parent) const
int StackHandler::columnCount(const QModelIndex &parent) const
{
- return parent.isValid() ? 0 : 5;
+ return parent.isValid() ? 0 : StackColumnCount;
}
QVariant StackHandler::data(const QModelIndex &index, int role) const
@@ -89,11 +89,11 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const
return QVariant();
if (index.row() == m_stackFrames.size()) {
- if (role == Qt::DisplayRole && index.column() == 0)
+ if (role == Qt::DisplayRole && index.column() == StackLevelColumn)
return tr("...");
- if (role == Qt::DisplayRole && index.column() == 1)
+ if (role == Qt::DisplayRole && index.column() == StackFunctionNameColumn)
return tr("<More>");
- if (role == Qt::DecorationRole && index.column() == 0)
+ if (role == Qt::DecorationRole && index.column() == StackLevelColumn)
return m_emptyIcon;
return QVariant();
}
@@ -102,15 +102,15 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const
if (role == Qt::DisplayRole) {
switch (index.column()) {
- case 0: // Stack frame level
+ case StackLevelColumn:
return QString::number(frame.level);
- case 1: // Function name
+ case StackFunctionNameColumn:
return simplifyType(frame.function);
- case 2: // File name
- return frame.file.isEmpty() ? frame.from : QFileInfo(frame.file).fileName();
- case 3: // Line number
+ case StackFileNameColumn:
+ return frame.file.isEmpty() ? frame.from : Utils::FileName::fromString(frame.file).fileName();
+ case StackLineNumberColumn:
return frame.line > 0 ? QVariant(frame.line) : QVariant();
- case 4: // Address
+ case StackAddressColumn:
if (frame.address)
return QString::fromLatin1("0x%1").arg(frame.address, 0, 16);
return QString();
@@ -118,7 +118,7 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const
return QVariant();
}
- if (role == Qt::DecorationRole && index.column() == 0) {
+ if (role == Qt::DecorationRole && index.column() == StackLevelColumn) {
// Return icon that indicates whether this is the active stack frame
return (m_contentsValid && index.row() == m_currentIndex)
? m_positionIcon : m_emptyIcon;
diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h
index 3e8bcbf57f..26d94bff4c 100644
--- a/src/plugins/debugger/stackhandler.h
+++ b/src/plugins/debugger/stackhandler.h
@@ -38,21 +38,16 @@
namespace Debugger {
namespace Internal {
-////////////////////////////////////////////////////////////////////////
-//
-// StackCookie
-//
-////////////////////////////////////////////////////////////////////////
-
-struct StackCookie
+enum StackColumns
{
- StackCookie() : isFull(true), gotoLocation(false) {}
- StackCookie(bool full, bool jump) : isFull(full), gotoLocation(jump) {}
- bool isFull;
- bool gotoLocation;
+ StackLevelColumn,
+ StackFunctionNameColumn,
+ StackFileNameColumn,
+ StackLineNumberColumn,
+ StackAddressColumn,
+ StackColumnCount = StackAddressColumn,
};
-
////////////////////////////////////////////////////////////////////////
//
// StackModel
@@ -110,7 +105,4 @@ private:
} // namespace Internal
} // namespace Debugger
-Q_DECLARE_METATYPE(Debugger::Internal::StackCookie)
-
-
#endif // DEBUGGER_STACKHANDLER_H
diff --git a/src/plugins/debugger/stackwindow.cpp b/src/plugins/debugger/stackwindow.cpp
index 15db90da04..4c863307c0 100644
--- a/src/plugins/debugger/stackwindow.cpp
+++ b/src/plugins/debugger/stackwindow.cpp
@@ -37,6 +37,7 @@
#include "debuggerdialogs.h"
#include "memoryagent.h"
+#include <coreplugin/messagebox.h>
#include <utils/savedaction.h>
@@ -50,7 +51,6 @@
#include <QContextMenuEvent>
#include <QInputDialog>
#include <QFileDialog>
-#include <QMessageBox>
#include <QMenu>
namespace Debugger {
@@ -71,7 +71,7 @@ StackTreeView::StackTreeView()
void StackTreeView::showAddressColumn(bool on)
{
- setColumnHidden(4, !on);
+ setColumnHidden(StackAddressColumn, !on);
}
void StackTreeView::rowActivated(const QModelIndex &index)
@@ -82,8 +82,8 @@ void StackTreeView::rowActivated(const QModelIndex &index)
void StackTreeView::setModel(QAbstractItemModel *model)
{
BaseTreeView::setModel(model);
- resizeColumnToContents(0);
- resizeColumnToContents(3);
+ resizeColumnToContents(StackLevelColumn);
+ resizeColumnToContents(StackLineNumberColumn);
showAddressColumn(action(UseAddressInStackView)->isChecked());
}
@@ -127,7 +127,7 @@ void saveTaskFile(QWidget *parent, const StackHandler *sh)
const QString fileName = fileDialog.selectedFiles().front();
file.setFileName(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QMessageBox::warning(parent, StackTreeView::tr("Cannot Open Task File"),
+ Core::AsynchronousMessageBox::warning(StackTreeView::tr("Cannot Open Task File"),
StackTreeView::tr("Cannot open \"%1\": %2").arg(QDir::toNativeSeparators(fileName), file.errorString()));
}
}
@@ -214,12 +214,13 @@ void StackTreeView::contextMenuEvent(QContextMenuEvent *ev)
if (act == actCopyContents) {
copyContentsToClipboard();
} else if (act == actShowMemory) {
- const QString title = tr("Memory at Frame #%1 (%2) 0x%3").
- arg(row).arg(frame.function).arg(address, 0, 16);
- QList<MemoryMarkup> ml;
- ml.push_back(MemoryMarkup(address, 1, QColor(Qt::blue).lighter(),
+ MemoryViewSetupData data;
+ data.startAddress = address;
+ data.title = tr("Memory at Frame #%1 (%2) 0x%3").
+ arg(row).arg(frame.function).arg(address, 0, 16);
+ data.markup.push_back(MemoryMarkup(address, 1, QColor(Qt::blue).lighter(),
tr("Frame #%1 (%2)").arg(row).arg(frame.function)));
- engine->openMemoryView(address, 0, ml, QPoint(), title);
+ engine->openMemoryView(data);
} else if (act == actShowDisassemblerAtAddress) {
AddressDialog dialog;
if (address)
diff --git a/src/plugins/debugger/terminal.cpp b/src/plugins/debugger/terminal.cpp
new file mode 100644
index 0000000000..e133f36572
--- /dev/null
+++ b/src/plugins/debugger/terminal.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "terminal.h"
+
+#include <QDebug>
+#include <QIODevice>
+#include <QSocketNotifier>
+
+#include <utils/qtcassert.h>
+
+#ifdef Q_OS_UNIX
+# define DEBUGGER_USE_TERMINAL
+#endif
+
+#ifdef DEBUGGER_USE_TERMINAL
+# include <errno.h>
+# include <fcntl.h>
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+# include <sys/ioctl.h>
+# include <sys/stat.h>
+#endif
+
+namespace Debugger {
+namespace Internal {
+
+static QString currentError()
+{
+ int err = errno;
+ return QString::fromLatin1(strerror(err));
+}
+
+Terminal::Terminal(QObject *parent)
+ : QObject(parent), m_isUsable(false), m_masterFd(-1), m_masterReader(0)
+{
+}
+
+void Terminal::setup()
+{
+#ifdef DEBUGGER_USE_TERMINAL
+ if (!qEnvironmentVariableIsSet("QTC_USE_PTY"))
+ return;
+
+ m_masterFd = ::open("/dev/ptmx", O_RDWR);
+ if (m_masterFd < 0) {
+ error(tr("Terminal: Cannot open /dev/ptmx: %1").arg(currentError()));
+ return;
+ }
+
+ const char *sName = ptsname(m_masterFd);
+ if (!sName) {
+ error(tr("Terminal: ptsname failed: %1").arg(currentError()));
+ return;
+ }
+ m_slaveName = sName;
+
+ struct stat s;
+ int r = ::stat(m_slaveName.constData(), &s);
+ if (r != 0) {
+ error(tr("Terminal: Error: %1").arg(currentError()));
+ return;
+ }
+ if (!S_ISCHR(s.st_mode)) {
+ error(tr("Terminal: Slave is no character device"));
+ return;
+ }
+
+ m_masterReader = new QSocketNotifier(m_masterFd, QSocketNotifier::Read, this);
+ connect(m_masterReader, &QSocketNotifier::activated,
+ this, &Terminal::onSlaveReaderActivated);
+
+ r = grantpt(m_masterFd);
+ if (r != 0) {
+ error(tr("Terminal: grantpt failed: %1").arg(currentError()));
+ return;
+ }
+
+ r = unlockpt(m_masterFd);
+ if (r != 0) {
+ error(tr("Terminal: unlock failed: %1").arg(currentError()));
+ return;
+ }
+
+ m_isUsable = true;
+#endif
+}
+
+bool Terminal::isUsable() const
+{
+ return m_isUsable;
+}
+
+int Terminal::write(const QByteArray &msg)
+{
+#ifdef DEBUGGER_USE_TERMINAL
+ return ::write(m_masterFd, msg.constData(), msg.size());
+#else
+ Q_UNUSED(msg);
+ return -1;
+#endif
+}
+
+bool Terminal::sendInterrupt()
+{
+#ifdef DEBUGGER_USE_TERMINAL
+ if (!m_isUsable)
+ return false;
+ ssize_t written = ::write(m_masterFd, "\003", 1);
+ return written == 1;
+#else
+ return false;
+#endif
+}
+
+void Terminal::onSlaveReaderActivated(int fd)
+{
+#ifdef DEBUGGER_USE_TERMINAL
+ ssize_t available = 0;
+ int ret = ::ioctl(fd, FIONREAD, (char *) &available);
+ if (ret != 0)
+ return;
+
+ QByteArray buffer(available, Qt::Uninitialized);
+ ssize_t got = ::read(fd, buffer.data(), available);
+ int err = errno;
+ if (got < 0) {
+ error(tr("Terminal: Read failed: %1").arg(QString::fromLatin1(strerror(err))));
+ return;
+ }
+ buffer.resize(got);
+ if (got >= 0)
+ stdOutReady(QString::fromUtf8(buffer));
+#else
+ Q_UNUSED(fd);
+#endif
+}
+
+} // namespace Internal
+} // namespace Debugger
+
diff --git a/src/plugins/debugger/breakpointmarker.h b/src/plugins/debugger/terminal.h
index fee89edd65..3ddfffe2f5 100644
--- a/src/plugins/debugger/breakpointmarker.h
+++ b/src/plugins/debugger/terminal.h
@@ -28,36 +28,45 @@
**
****************************************************************************/
-#ifndef DEBUGGER_BREAKPOINTMARKER_H
-#define DEBUGGER_BREAKPOINTMARKER_H
+#ifndef DEBUGGER_TERMINAL_H
+#define DEBUGGER_TERMINAL_H
-#include "breakpoint.h"
-
-#include <texteditor/textmark.h>
+#include <QCoreApplication>
+#include <QSocketNotifier>
namespace Debugger {
namespace Internal {
-// The red blob on the left side in the cpp editor.
-class BreakpointMarker : public TextEditor::TextMark
+class Terminal : public QObject
{
+ Q_OBJECT
+
public:
- BreakpointMarker(BreakpointModelId id, const QString &fileName, int lineNumber);
- ~BreakpointMarker();
- void removedFromEditor();
- void updateLineNumber(int lineNumber);
- void updateFileName(const QString &fileName);
- bool isDraggable() const { return true; }
- void dragToLine(int lineNumber);
- bool isClickable() const { return true; }
- void clicked();
+ Terminal(QObject *parent = 0);
+
+ void setup();
+ bool isUsable() const;
+
+ QByteArray slaveDevice() const { return m_slaveName; }
+
+ int write(const QByteArray &msg);
+ bool sendInterrupt();
+
+signals:
+ void stdOutReady(const QString &);
+ void stdErrReady(const QString &);
+ void error(const QString &);
private:
- BreakpointModelId m_id;
- friend class BreakHandler;
+ void onSlaveReaderActivated(int fd);
+
+ bool m_isUsable;
+ int m_masterFd;
+ QSocketNotifier *m_masterReader;
+ QByteArray m_slaveName;
};
} // namespace Internal
} // namespace Debugger
-#endif
+#endif // DEBUGGER_TERMINAL_H
diff --git a/src/plugins/debugger/unstartedappwatcherdialog.cpp b/src/plugins/debugger/unstartedappwatcherdialog.cpp
index 9c9aa3741e..5c683aa40e 100644
--- a/src/plugins/debugger/unstartedappwatcherdialog.cpp
+++ b/src/plugins/debugger/unstartedappwatcherdialog.cpp
@@ -39,7 +39,7 @@
#include <projectexplorer/target.h>
#include <projectexplorer/project.h>
#include <projectexplorer/kitmanager.h>
-#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projecttree.h>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/localapplicationrunconfiguration.h>
@@ -88,7 +88,7 @@ UnstartedAppWatcherDialog::UnstartedAppWatcherDialog(QWidget *parent)
m_kitChooser->populate();
m_kitChooser->setVisible(true);
- Project *project = ProjectExplorerPlugin::currentProject();
+ Project *project = ProjectTree::currentProject();
if (project && project->activeTarget() && project->activeTarget()->kit())
m_kitChooser->setCurrentKitId(project->activeTarget()->kit()->id());
else if (KitManager::defaultKit())
@@ -147,12 +147,17 @@ UnstartedAppWatcherDialog::UnstartedAppWatcherDialog(QWidget *parent)
mainLayout->addRow(buttonsLine);
setLayout(mainLayout);
- connect(m_pathChooser, SIGNAL(beforeBrowsing()), this, SLOT(selectExecutable()));
- connect(m_watchingPushButton, SIGNAL(toggled(bool)), this, SLOT(startStopWatching(bool)));
- connect(m_pathChooser, SIGNAL(pathChanged(QString)), this, SLOT(stopAndCheckExecutable()));
- connect(m_closePushButton, SIGNAL(clicked()), this, SLOT(reject()));
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(findProcess()));
- connect(m_kitChooser, &ProjectExplorer::KitChooser::currentIndexChanged,
+ connect(m_pathChooser, &Utils::PathChooser::beforeBrowsing,
+ this, &UnstartedAppWatcherDialog::selectExecutable);
+ connect(m_watchingPushButton, &QAbstractButton::toggled,
+ this, &UnstartedAppWatcherDialog::startStopWatching);
+ connect(m_pathChooser, &Utils::PathChooser::pathChanged, this,
+ &UnstartedAppWatcherDialog::stopAndCheckExecutable);
+ connect(m_closePushButton, &QAbstractButton::clicked,
+ this, &QDialog::reject);
+ connect(&m_timer, &QTimer::timeout,
+ this, &UnstartedAppWatcherDialog::findProcess);
+ connect(m_kitChooser, &KitChooser::currentIndexChanged,
this, &UnstartedAppWatcherDialog::kitChanged);
kitChanged();
@@ -163,7 +168,7 @@ void UnstartedAppWatcherDialog::selectExecutable()
{
QString path;
- Project *project = ProjectExplorerPlugin::currentProject();
+ Project *project = ProjectTree::currentProject();
if (project && project->activeTarget() && project->activeTarget()->activeRunConfiguration()) {
diff --git a/src/plugins/debugger/unstartedappwatcherdialog.h b/src/plugins/debugger/unstartedappwatcherdialog.h
index 618a9f6381..5edb21781f 100644
--- a/src/plugins/debugger/unstartedappwatcherdialog.h
+++ b/src/plugins/debugger/unstartedappwatcherdialog.h
@@ -62,20 +62,19 @@ public:
ProjectExplorer::DeviceProcessItem currentProcess() const;
bool hideOnAttach() const;
bool continueOnAttach() const;
+ void startWatching();
-public slots:
+signals:
+ void processFound();
+
+private:
void selectExecutable();
- void startWatching();
void pidFound(const ProjectExplorer::DeviceProcessItem &p);
void startStopWatching(bool start);
void findProcess();
void stopAndCheckExecutable();
void kitChanged();
-signals:
- void processFound();
-
-private:
enum UnstartedAppWacherState
{
InvalidWacherState,
diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp
index 08647b04ff..197677caf0 100644
--- a/src/plugins/debugger/watchdata.cpp
+++ b/src/plugins/debugger/watchdata.cpp
@@ -156,6 +156,15 @@ bool WatchData::isEqual(const WatchData &other) const
&& error == other.error;
}
+bool WatchData::isAncestorOf(const QByteArray &childIName) const
+{
+ if (iname.size() >= childIName.size())
+ return false;
+ if (!childIName.startsWith(iname))
+ return false;
+ return childIName.at(iname.size()) == '.';
+}
+
bool WatchData::isVTablePointer() const
{
// First case: Cdb only. No user type can be named like this, this is safe.
@@ -526,7 +535,7 @@ QString decodeItemHelper(const double &t)
}
template <class T>
-void decodeArrayHelper(QList<WatchData> *list, const WatchData &tmplate,
+void decodeArrayHelper(std::function<void(const WatchData &)> itemHandler, const WatchData &tmplate,
const QByteArray &rawData)
{
const QByteArray ba = QByteArray::fromHex(rawData);
@@ -542,62 +551,59 @@ void decodeArrayHelper(QList<WatchData> *list, const WatchData &tmplate,
data.address += i * sizeof(T);
data.exp = exp + QByteArray::number(data.address, 16);
data.setAllUnneeded();
- list->append(data);
+ itemHandler(data);
}
}
-static void decodeArray(QList<WatchData> *list, const WatchData &tmplate,
+void decodeArrayData(std::function<void(const WatchData &)> itemHandler, const WatchData &tmplate,
const QByteArray &rawData, int encoding)
{
switch (encoding) {
case Hex2EncodedInt1:
- decodeArrayHelper<signed char>(list, tmplate, rawData);
+ decodeArrayHelper<signed char>(itemHandler, tmplate, rawData);
break;
case Hex2EncodedInt2:
- decodeArrayHelper<short>(list, tmplate, rawData);
+ decodeArrayHelper<short>(itemHandler, tmplate, rawData);
break;
case Hex2EncodedInt4:
- decodeArrayHelper<int>(list, tmplate, rawData);
+ decodeArrayHelper<int>(itemHandler, tmplate, rawData);
break;
case Hex2EncodedInt8:
- decodeArrayHelper<qint64>(list, tmplate, rawData);
+ decodeArrayHelper<qint64>(itemHandler, tmplate, rawData);
break;
case Hex2EncodedUInt1:
- decodeArrayHelper<uchar>(list, tmplate, rawData);
+ decodeArrayHelper<uchar>(itemHandler, tmplate, rawData);
break;
case Hex2EncodedUInt2:
- decodeArrayHelper<ushort>(list, tmplate, rawData);
+ decodeArrayHelper<ushort>(itemHandler, tmplate, rawData);
break;
case Hex2EncodedUInt4:
- decodeArrayHelper<uint>(list, tmplate, rawData);
+ decodeArrayHelper<uint>(itemHandler, tmplate, rawData);
break;
case Hex2EncodedUInt8:
- decodeArrayHelper<quint64>(list, tmplate, rawData);
+ decodeArrayHelper<quint64>(itemHandler, tmplate, rawData);
break;
case Hex2EncodedFloat4:
- decodeArrayHelper<float>(list, tmplate, rawData);
+ decodeArrayHelper<float>(itemHandler, tmplate, rawData);
break;
case Hex2EncodedFloat8:
- decodeArrayHelper<double>(list, tmplate, rawData);
+ decodeArrayHelper<double>(itemHandler, tmplate, rawData);
break;
default:
qDebug() << "ENCODING ERROR: " << encoding;
}
}
-void parseWatchData(const QSet<QByteArray> &expandedINames,
- const WatchData &data0, const GdbMi &item,
- QList<WatchData> *list)
+void parseChildrenData(const WatchData &data0, const GdbMi &item,
+ std::function<void(const WatchData &)> itemHandler,
+ std::function<void(const WatchData &, const GdbMi &)> childHandler,
+ std::function<void(const WatchData &childTemplate, const QByteArray &encodedData, int encoding)> arrayDecoder)
{
//qDebug() << "HANDLE CHILDREN: " << data0.toString() << item.toString();
WatchData data = data0;
- bool isExpanded = expandedINames.contains(data.iname);
- if (!isExpanded)
- data.setChildrenUnneeded();
+ data.setChildrenUnneeded();
GdbMi children = item["children"];
- if (children.isValid() || !isExpanded)
- data.setChildrenUnneeded();
data.updateType(item["type"]);
GdbMi mi = item["editvalue"];
@@ -640,7 +646,7 @@ void parseWatchData(const QSet<QByteArray> &expandedINames,
setWatchDataValueEditable(data, item["valueeditable"]);
data.updateChildCount(item["numchild"]);
//qDebug() << "\nAPPEND TO LIST: " << data.toString() << "\n";
- list->append(data);
+ itemHandler(data);
bool ok = false;
qulonglong addressBase = item["addrbase"].data().toULongLong(&ok, 0);
@@ -657,7 +663,7 @@ void parseWatchData(const QSet<QByteArray> &expandedINames,
int encoding = item["arrayencoding"].toInt();
childtemplate.iname = data.iname + '.';
childtemplate.address = addressBase;
- decodeArray(list, childtemplate, mi.data(), encoding);
+ arrayDecoder(childtemplate, mi.data(), encoding);
} else {
for (int i = 0, n = children.children().size(); i != n; ++i) {
const GdbMi &child = children.children().at(i);
@@ -687,11 +693,28 @@ void parseWatchData(const QSet<QByteArray> &expandedINames,
int encoding = child["keyencoded"].toInt();
data1.name = decodeData(key, encoding);
}
- parseWatchData(expandedINames, data1, child, list);
+ childHandler(data1, child);
}
}
}
+void parseWatchData(const WatchData &data0, const GdbMi &input,
+ QList<WatchData> *list)
+{
+ auto itemHandler = [list](const WatchData &data) {
+ list->append(data);
+ };
+ auto childHandler = [list](const WatchData &innerData, const GdbMi &innerInput) {
+ parseWatchData(innerData, innerInput, list);
+ };
+ auto arrayDecoder = [itemHandler](const WatchData &childTemplate,
+ const QByteArray &encodedData, int encoding) {
+ decodeArrayData(itemHandler, childTemplate, encodedData, encoding);
+ };
+
+ parseChildrenData(data0, input, itemHandler, childHandler, arrayDecoder);
+}
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h
index cef0a6095d..b00de93220 100644
--- a/src/plugins/debugger/watchdata.h
+++ b/src/plugins/debugger/watchdata.h
@@ -34,6 +34,8 @@
#include <QCoreApplication>
#include <QMetaType>
+#include <functional>
+
namespace Debugger {
namespace Internal {
@@ -96,6 +98,7 @@ public:
bool isVTablePointer() const;
bool isEqual(const WatchData &other) const;
+ bool isAncestorOf(const QByteArray &childIName) const;
void setError(const QString &);
void setValue(const QString &);
@@ -151,9 +154,20 @@ public:
qint32 source; // Originated from dumper or symbol evaluation? (CDB only)
};
-void parseWatchData(const QSet<QByteArray> &expandedINames,
- const WatchData &parent, const GdbMi &child,
- QList<WatchData> *insertions);
+void decodeArrayData(std::function<void(const WatchData &)> itemHandler,
+ const WatchData &tmplate,
+ const QByteArray &rawData,
+ int encoding);
+
+void parseChildrenData(const WatchData &parent, const GdbMi &child,
+ std::function<void(const WatchData &)> itemHandler,
+ std::function<void(const WatchData &, const GdbMi &)> childHandler,
+ std::function<void(const WatchData &childTemplate,
+ const QByteArray &encodedData,
+ int encoding)> arrayDecoder);
+
+void parseWatchData(const WatchData &parent, const GdbMi &child,
+ QList<WatchData> *insertions);
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index a45a9dee19..cb5ac6f30d 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -41,10 +41,13 @@
#include "imageviewer.h"
#include "watchutils.h"
+#include <coreplugin/icore.h>
+
#include <utils/algorithm.h>
#include <utils/basetreeview.h>
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
+#include <utils/checkablemessagebox.h>
#include <QDebug>
#include <QFile>
@@ -55,12 +58,7 @@
#include <cstring>
#include <ctype.h>
-//#define USE_WATCH_MODEL_TEST 0
-//#define USE_EXPENSIVE_CHECKS 0
-
-#if USE_WATCH_MODEL_TEST
-#include <modeltest.h>
-#endif
+using namespace Utils;
namespace Debugger {
namespace Internal {
@@ -70,13 +68,6 @@ enum { debugModel = 0 };
#define MODEL_DEBUG(s) do { if (debugModel) qDebug() << s; } while (0)
-#if USE_EXPENSIVE_CHECKS
-#define CHECK(s) s
-#else
-#define CHECK(s)
-#endif
-
-
static QHash<QByteArray, int> theWatcherNames;
static QHash<QByteArray, int> theTypeFormats;
static QHash<QByteArray, int> theIndividualFormats;
@@ -109,36 +100,6 @@ static QByteArray stripForFormat(const QByteArray &ba)
return res;
}
-////////////////////////////////////////////////////////////////////
-//
-// WatchItem
-//
-////////////////////////////////////////////////////////////////////
-
-// Used to make sure the item cache is notified of construction and
-// destruction of items.
-
-class WatchItem;
-typedef QList<WatchItem *> WatchItems;
-
-WatchItem *itemConstructor(WatchModel *model, const QByteArray &iname);
-void itemDestructor(WatchModel *model, WatchItem *item);
-
-class WatchItem : public WatchData
-{
-public:
- WatchItem *parent; // Not owned.
- WatchItems children; // Not owned. Handled via itemDestructor().
-
-private:
- friend WatchItem *itemConstructor(WatchModel *model, const QByteArray &iname);
- friend void itemDestructor(WatchModel *model, WatchItem *item);
-
- WatchItem() { parent = 0; }
- ~WatchItem() { parent = 0; }
- WatchItem(const WatchItem &); // Not implemented.
-};
-
///////////////////////////////////////////////////////////////////////
//
// SeparatedView
@@ -232,79 +193,33 @@ public:
class WatchModel : public WatchModelBase
{
-private:
- explicit WatchModel(WatchHandler *handler);
- ~WatchModel();
-
- friend WatchItem *itemConstructor(WatchModel *model, const QByteArray &iname);
- friend void itemDestructor(WatchModel *model, WatchItem *item);
-
public:
- int rowCount(const QModelIndex &idx = QModelIndex()) const;
- int columnCount(const QModelIndex &idx) const;
+ explicit WatchModel(WatchHandler *handler);
static QString nameForFormat(int format);
TypeFormatList typeFormatList(const WatchData &value) const;
-private:
- QVariant data(const QModelIndex &idx, int role) const;
bool setData(const QModelIndex &idx, const QVariant &value, int role);
- QModelIndex index(int, int, const QModelIndex &idx) const;
- QModelIndex parent(const QModelIndex &idx) const;
- bool hasChildren(const QModelIndex &idx) const;
- Qt::ItemFlags flags(const QModelIndex &idx) const;
- QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- bool canFetchMore(const QModelIndex &parent) const;
- void fetchMore(const QModelIndex &parent);
-
- void invalidateAll(const QModelIndex &parentIndex = QModelIndex());
- void resetValueCacheRecursively(WatchItem *item);
-
- WatchItem *createItem(const QByteArray &iname, const QString &name, WatchItem *parent);
-
- friend class WatchHandler;
-
- WatchItem *watchItem(const QModelIndex &) const;
- QModelIndex watchIndex(const WatchItem *needle) const;
- QModelIndex watchIndexHelper(const WatchItem *needle,
- const WatchItem *parentItem, const QModelIndex &parentIndex) const;
void insertDataItem(const WatchData &data, bool destructive);
void reinsertAllData();
void reinsertAllDataHelper(WatchItem *item, QList<WatchData> *data);
- bool ancestorChanged(const QSet<QByteArray> &parentINames, WatchItem *item) const;
void insertBulkData(const QList<WatchData> &data);
QString displayForAutoTest(const QByteArray &iname) const;
void reinitialize(bool includeInspectData = false);
- void destroyItem(WatchItem *item); // With model notification.
- void destroyChildren(WatchItem *item); // With model notification.
- void destroyHelper(const WatchItems &items); // Without model notification.
- void emitDataChanged(int column,
- const QModelIndex &parentIndex = QModelIndex());
friend QDebug operator<<(QDebug d, const WatchModel &m);
- void dump();
- void dumpHelper(WatchItem *item);
- void emitAllChanged();
-
void showInEditorHelper(QString *contents, WatchItem *item, int level);
void setCurrentItem(const QByteArray &iname);
- QString displayType(const WatchData &typeIn) const;
- QString displayName(const WatchItem *item) const;
- QString displayValue(const WatchData &data) const;
- QString formattedValue(const WatchData &data) const;
QString removeNamespaces(QString str) const;
- void formatRequests(QByteArray *out, const WatchItem *item) const;
DebuggerEngine *engine() const;
- int itemFormat(const WatchData &data) const;
bool contentIsValid() const;
WatchHandler *m_handler; // Not owned.
- WatchItem *m_root; // Owned.
+ WatchItem *root() const { return static_cast<WatchItem *>(rootItem()); }
WatchItem *m_localsRoot; // Not owned.
WatchItem *m_inspectorRoot; // Not owned.
WatchItem *m_watchRoot; // Not owned.
@@ -312,110 +227,51 @@ private:
WatchItem *m_tooltipRoot; // Not owned.
QSet<QByteArray> m_expandedINames;
- QSet<QByteArray> m_fetchTriggered;
TypeFormatList builtinTypeFormatList(const WatchData &data) const;
QStringList dumperTypeFormatList(const WatchData &data) const;
DumperTypeFormats m_reportedTypeFormats;
WatchItem *createItem(const QByteArray &iname);
- WatchItem *createItem(const WatchData &data);
- void assignData(WatchItem *item, const WatchData &data);
WatchItem *findItem(const QByteArray &iname) const;
friend class WatchItem;
- typedef QHash<QByteArray, WatchItem *> Cache;
- Cache m_cache;
typedef QHash<QByteArray, QString> ValueCache;
ValueCache m_valueCache;
- #if USE_EXPENSIVE_CHECKS
- QHash<const WatchItem *, QByteArray> m_cache2;
- void checkTree();
- void checkItem(const WatchItem *item) const;
- void checkTree(WatchItem *item, QSet<QByteArray> *inames);
- #endif
- void checkIndex(const QModelIndex &index) const;
+ void insertItem(WatchItem *item);
+ void reexpandItems();
};
WatchModel::WatchModel(WatchHandler *handler)
: m_handler(handler)
{
setObjectName(QLatin1String("WatchModel"));
- m_root = createItem(QByteArray(), tr("Root"), 0);
- // Note: Needs to stay
- m_localsRoot = createItem("local", tr("Locals"), m_root);
- m_inspectorRoot = createItem("inspect", tr("Inspector"), m_root);
- m_watchRoot = createItem("watch", tr("Expressions"), m_root);
- m_returnRoot = createItem("return", tr("Return Value"), m_root);
- m_tooltipRoot = createItem("tooltip", tr("Tooltip"), m_root);
-
- connect(action(SortStructMembers), &Utils::SavedAction::valueChanged,
+
+ setHeader(QStringList() << tr("Name") << tr("Value") << tr("Type"));
+ auto root = new WatchItem;
+ root->appendChild(m_localsRoot = new WatchItem("local", tr("Locals")));
+ root->appendChild(m_inspectorRoot = new WatchItem("inspect", tr("Inspector")));
+ root->appendChild(m_watchRoot = new WatchItem("watch", tr("Expressions")));
+ root->appendChild(m_returnRoot = new WatchItem("return", tr("Return Value")));
+ root->appendChild(m_tooltipRoot = new WatchItem("tooltip", tr("Tooltip")));
+ setRootItem(root);
+
+ connect(action(SortStructMembers), &SavedAction::valueChanged,
this, &WatchModel::reinsertAllData);
- connect(action(ShowStdNamespace), &Utils::SavedAction::valueChanged,
+ connect(action(ShowStdNamespace), &SavedAction::valueChanged,
this, &WatchModel::reinsertAllData);
- connect(action(ShowQtNamespace), &Utils::SavedAction::valueChanged,
+ connect(action(ShowQtNamespace), &SavedAction::valueChanged,
this, &WatchModel::reinsertAllData);
}
-WatchModel::~WatchModel()
-{
- CHECK(checkItem(m_root));
- destroyChildren(m_root);
- itemDestructor(this, m_root);
- QTC_CHECK(m_cache.isEmpty());
-}
-
-WatchItem *itemConstructor(WatchModel *model, const QByteArray &iname)
-{
- QTC_CHECK(!model->m_cache.contains(iname));
- WatchItem *item = new WatchItem();
- item->iname = iname;
- model->m_cache[iname] = item;
- CHECK(model->m_cache2[item] = iname);
- CHECK(model->checkItem(item));
- return item;
-}
-
-void itemDestructor(WatchModel *model, WatchItem *item)
-{
- QTC_ASSERT(model->m_cache.value(item->iname) == item, return);
- CHECK(model->checkItem(item));
- CHECK(model->m_cache2.remove(item));
- model->m_cache.remove(item->iname);
- delete item;
-}
-
-WatchItem *WatchModel::createItem(const QByteArray &iname, const QString &name, WatchItem *parent)
-{
- WatchItem *item = itemConstructor(this, iname);
- item->name = name;
- item->hasChildren = true; // parent == 0;
- item->state = 0;
- item->parent = parent;
- if (parent)
- parent->children.append(item);
- return item;
-}
-
void WatchModel::reinitialize(bool includeInspectData)
{
- CHECK(checkTree());
- //MODEL_DEBUG("REMOVING " << n << " CHILDREN OF " << m_root->iname);
- QTC_CHECK(m_root->children.size() == 5);
- destroyChildren(m_localsRoot);
- destroyChildren(m_watchRoot);
- destroyChildren(m_returnRoot);
- destroyChildren(m_tooltipRoot);
- if (includeInspectData) {
- destroyChildren(m_inspectorRoot);
- QTC_CHECK(m_cache.size() == 6);
- }
- CHECK(checkTree());
-}
-
-void WatchModel::emitAllChanged()
-{
- emit layoutChanged();
+ m_localsRoot->removeChildren();
+ m_watchRoot->removeChildren();
+ m_returnRoot->removeChildren();
+ m_tooltipRoot->removeChildren();
+ if (includeInspectData)
+ m_inspectorRoot->removeChildren();
}
DebuggerEngine *WatchModel::engine() const
@@ -423,122 +279,40 @@ DebuggerEngine *WatchModel::engine() const
return m_handler->m_engine;
}
-void WatchModel::dump()
-{
- qDebug() << "\n";
- foreach (WatchItem *child, m_root->children)
- dumpHelper(child);
-}
-
-void WatchModel::dumpHelper(WatchItem *item)
-{
- qDebug() << "ITEM: " << item->iname
- << (item->parent ? item->parent->iname : "<none>");
- foreach (WatchItem *child, item->children)
- dumpHelper(child);
-}
-
-void WatchModel::destroyHelper(const WatchItems &items)
-{
- for (int i = items.size(); --i >= 0; ) {
- WatchItem *item = items.at(i);
- destroyHelper(item->children);
- itemDestructor(this, item);
- }
-}
-
-void WatchModel::destroyItem(WatchItem *item)
-{
- const QByteArray iname = item->iname;
- CHECK(checkTree());
- QTC_ASSERT(m_cache.contains(iname), return);
-
- // Deregister from model and parent.
- // It's sufficient to do this non-recursively.
- WatchItem *parent = item->parent;
- QTC_ASSERT(parent, return);
- QModelIndex parentIndex = watchIndex(parent);
- checkIndex(parentIndex);
- const int i = parent->children.indexOf(item);
- //MODEL_DEBUG("NEED TO REMOVE: " << item->iname << "AT" << n);
- beginRemoveRows(parentIndex, i, i);
- parent->children.removeAt(i);
- endRemoveRows();
-
- // Destroy contents.
- destroyHelper(item->children);
- itemDestructor(this, item);
- QTC_ASSERT(!m_cache.contains(iname), return);
- CHECK(checkTree());
-}
-
-void WatchModel::destroyChildren(WatchItem *item)
-{
- CHECK(checkTree());
- QTC_ASSERT(m_cache.contains(item->iname), return);
- if (item->children.isEmpty())
- return;
-
- WatchItems items = item->children;
-
- // Deregister from model and parent.
- // It's sufficient to do this non-recursively.
- QModelIndex idx = watchIndex(item);
- checkIndex(idx);
- beginRemoveRows(idx, 0, items.size() - 1);
- item->children.clear();
- endRemoveRows();
-
- // Destroy contents.
- destroyHelper(items);
- CHECK(checkTree());
-}
-
WatchItem *WatchModel::findItem(const QByteArray &iname) const
{
- return m_cache.value(iname, 0);
+ return root()->findItem(iname);
}
-void WatchModel::checkIndex(const QModelIndex &index) const
+WatchItem *WatchItem::findItem(const QByteArray &iname)
{
- if (index.isValid()) {
- QTC_CHECK(index.model() == this);
- } else {
- QTC_CHECK(index.model() == 0);
+ if (d.iname == iname)
+ return this;
+ foreach (TreeItem *child, children()) {
+ auto witem = static_cast<WatchItem *>(child);
+ if (witem->d.iname == iname)
+ return witem;
+ if (witem->d.isAncestorOf(iname))
+ return witem->findItem(iname);
}
-}
-
-WatchItem *WatchModel::createItem(const WatchData &data)
-{
- WatchItem *item = itemConstructor(this, data.iname);
- static_cast<WatchData &>(*item) = data;
- return item;
-}
-
-void WatchModel::assignData(WatchItem *item, const WatchData &data)
-{
- CHECK(checkItem(item));
- QTC_ASSERT(data.iname == item->iname,
- m_cache.remove(item->iname);
- m_cache[data.iname] = item);
- static_cast<WatchData &>(*item) = data;
- CHECK(checkItem(item));
+ return 0;
}
void WatchModel::reinsertAllData()
{
QList<WatchData> list;
- reinsertAllDataHelper(m_root, &list);
+ foreach (TreeItem *child, rootItem()->children())
+ reinsertAllDataHelper(static_cast<WatchItem *>(child), &list);
reinitialize(true);
insertBulkData(list);
}
void WatchModel::reinsertAllDataHelper(WatchItem *item, QList<WatchData> *data)
{
- data->append(*item);
+ data->append(item->d);
data->back().setAllUnneeded();
- foreach (WatchItem *child, item->children)
- reinsertAllDataHelper(child, data);
+ foreach (TreeItem *child, item->children())
+ reinsertAllDataHelper(static_cast<WatchItem *>(child), data);
}
static QByteArray parentName(const QByteArray &iname)
@@ -714,68 +488,66 @@ static QString translate(const QString &str)
return quoteUnprintable(str);
}
-QString WatchModel::formattedValue(const WatchData &data) const
+QString WatchItem::formattedValue() const
{
- const QString &value = data.value;
-
- if (data.type == "bool") {
- if (value == QLatin1String("0"))
+ if (d.type == "bool") {
+ if (d.value == QLatin1String("0"))
return QLatin1String("false");
- if (value == QLatin1String("1"))
+ if (d.value == QLatin1String("1"))
return QLatin1String("true");
- return value;
+ return d.value;
}
- const int format = itemFormat(data);
+ const int format = itemFormat();
// Append quoted, printable character also for decimal.
- if (data.type.endsWith("char") || data.type.endsWith("QChar")) {
+ if (d.type.endsWith("char") || d.type.endsWith("QChar")) {
bool ok;
- const int code = value.toInt(&ok);
- return ok ? reformatCharacter(code, format) : value;
+ const int code = d.value.toInt(&ok);
+ return ok ? reformatCharacter(code, format) : d.value;
}
if (format == HexadecimalIntegerFormat
|| format == DecimalIntegerFormat
|| format == OctalIntegerFormat
|| format == BinaryIntegerFormat) {
- bool isSigned = value.startsWith(QLatin1Char('-'));
- quint64 raw = isSigned ? quint64(value.toLongLong()): value.toULongLong();
- return reformatInteger(raw, format, data.size, isSigned);
+ bool isSigned = d.value.startsWith(QLatin1Char('-'));
+ quint64 raw = isSigned ? quint64(d.value.toLongLong()) : d.value.toULongLong();
+ return reformatInteger(raw, format, d.size, isSigned);
}
if (format == ScientificFloatFormat) {
- double d = value.toDouble();
- return QString::number(d, 'e');
+ double dd = d.value.toDouble();
+ return QString::number(dd, 'e');
}
if (format == CompactFloatFormat) {
- double d = value.toDouble();
- return QString::number(d, 'g');
+ double dd = d.value.toDouble();
+ return QString::number(dd, 'g');
}
- if (data.type == "va_list")
- return value;
+ if (d.type == "va_list")
+ return d.value;
- if (!isPointerType(data.type) && !data.isVTablePointer()) {
+ if (!isPointerType(d.type) && !d.isVTablePointer()) {
bool ok = false;
- qulonglong integer = value.toULongLong(&ok, 0);
+ qulonglong integer = d.value.toULongLong(&ok, 0);
if (ok) {
- const int format = itemFormat(data);
- return reformatInteger(integer, format, data.size, false);
+ const int format = itemFormat();
+ return reformatInteger(integer, format, d.size, false);
}
}
- if (data.elided) {
- QString v = value;
+ if (d.elided) {
+ QString v = d.value;
v.chop(1);
v = translate(v);
- QString len = data.elided > 0 ? QString::number(data.elided)
+ QString len = d.elided > 0 ? QString::number(d.elided)
: QLatin1String("unknown length");
return v + QLatin1String("\"... (") + len + QLatin1Char(')');
}
- return translate(value);
+ return translate(d.value);
}
// Get a pointer address from pointer values reported by the debugger.
@@ -791,7 +563,7 @@ static inline quint64 pointerValue(QString data)
}
// Return the type used for editing
-static inline int editType(const WatchData &d)
+int WatchItem::editType() const
{
if (d.type == "bool")
return QVariant::Bool;
@@ -806,9 +578,9 @@ static inline int editType(const WatchData &d)
}
// Convert to editable (see above)
-static inline QVariant editValue(const WatchData &d)
+QVariant WatchItem::editValue() const
{
- switch (editType(d)) {
+ switch (editType()) {
case QVariant::Bool:
return d.value != QLatin1String("0") && d.value != QLatin1String("false");
case QVariant::ULongLong:
@@ -836,161 +608,28 @@ static inline QVariant editValue(const WatchData &d)
return QVariant(translate(stringValue));
}
-bool WatchModel::canFetchMore(const QModelIndex &idx) const
+bool WatchItem::canFetchMore() const
{
- if (!idx.isValid())
+ if (!d.hasChildren)
return false;
- WatchItem *item = watchItem(idx);
- QTC_ASSERT(item, return false);
- if (!contentIsValid() && !item->isInspect())
+ if (!watchModel())
return false;
- if (!item->iname.contains('.'))
+ if (!watchModel()->contentIsValid() && !d.isInspect())
return false;
- return !m_fetchTriggered.contains(item->iname);
+ return !fetchTriggered;
}
-void WatchModel::fetchMore(const QModelIndex &idx)
+void WatchItem::fetchMore()
{
- checkIndex(idx);
- if (!idx.isValid())
- return; // Triggered by ModelTester.
- WatchItem *item = watchItem(idx);
- QTC_ASSERT(item, return);
- QTC_ASSERT(!m_fetchTriggered.contains(item->iname), return);
- m_expandedINames.insert(item->iname);
- m_fetchTriggered.insert(item->iname);
- if (item->children.isEmpty()) {
- WatchData data = *item;
- data.setChildrenNeeded();
+ QTC_ASSERT(!fetchTriggered, return);
+ watchModel()->m_expandedINames.insert(d.iname);
+ fetchTriggered = true;
+ if (children().isEmpty()) {
+ d.setChildrenNeeded();
WatchUpdateFlags flags;
flags.tryIncremental = true;
- engine()->updateWatchData(data, flags);
- }
-}
-
-QModelIndex WatchModel::index(int row, int column, const QModelIndex &parent) const
-{
- checkIndex(parent);
- if (!hasIndex(row, column, parent))
- return QModelIndex();
-
- const WatchItem *item = watchItem(parent);
- QTC_ASSERT(item, return QModelIndex());
- if (row >= item->children.size())
- return QModelIndex();
- return createIndex(row, column, (void*)(item->children.at(row)));
-}
-
-QModelIndex WatchModel::parent(const QModelIndex &idx) const
-{
- checkIndex(idx);
- if (!idx.isValid())
- return QModelIndex();
-
- const WatchItem *item = watchItem(idx);
- const WatchItem *parent = item->parent;
- if (!parent || parent == m_root)
- return QModelIndex();
-
- const WatchItem *grandparent = parent->parent;
- if (!grandparent)
- return QModelIndex();
-
- const auto &uncles = grandparent->children;
- for (int i = 0, n = uncles.size(); i < n; ++i)
- if (uncles.at(i) == parent)
- return createIndex(i, 0, (void*) parent);
-
- return QModelIndex();
-}
-
-int WatchModel::rowCount(const QModelIndex &idx) const
-{
- checkIndex(idx);
- if (!idx.isValid())
- return m_root->children.size();
- if (idx.column() > 0)
- return 0;
- return watchItem(idx)->children.size();
-}
-
-int WatchModel::columnCount(const QModelIndex &idx) const
-{
- checkIndex(idx);
- return 3;
-}
-
-bool WatchModel::hasChildren(const QModelIndex &parent) const
-{
- checkIndex(parent);
- WatchItem *item = watchItem(parent);
- return !item || item->hasChildren;
-}
-
-WatchItem *WatchModel::watchItem(const QModelIndex &idx) const
-{
- checkIndex(idx);
- WatchItem *item = idx.isValid()
- ? static_cast<WatchItem*>(idx.internalPointer()) : m_root;
- CHECK(checkItem(item));
- return item;
-}
-
-QModelIndex WatchModel::watchIndex(const WatchItem *item) const
-{
- CHECK(checkItem(item));
- return watchIndexHelper(item, m_root, QModelIndex());
-}
-
-QModelIndex WatchModel::watchIndexHelper(const WatchItem *needle,
- const WatchItem *parentItem, const QModelIndex &parentIndex) const
-{
- checkIndex(parentIndex);
- if (needle == parentItem)
- return parentIndex;
- for (int i = parentItem->children.size(); --i >= 0; ) {
- const WatchItem *childItem = parentItem->children.at(i);
- QModelIndex childIndex = index(i, 0, parentIndex);
- QModelIndex idx = watchIndexHelper(needle, childItem, childIndex);
- checkIndex(idx);
- if (idx.isValid())
- return idx;
+ watchModel()->engine()->updateWatchData(d, flags);
}
- return QModelIndex();
-}
-
-void WatchModel::emitDataChanged(int column, const QModelIndex &parentIndex)
-{
- checkIndex(parentIndex);
- QModelIndex idx1 = index(0, column, parentIndex);
- QModelIndex idx2 = index(rowCount(parentIndex) - 1, column, parentIndex);
- if (idx1.isValid() && idx2.isValid())
- emit dataChanged(idx1, idx2);
- //qDebug() << "CHANGING:\n" << idx1 << "\n" << idx2 << "\n"
- // << data(parentIndex, INameRole).toString();
- checkIndex(idx1);
- checkIndex(idx2);
- for (int i = rowCount(parentIndex); --i >= 0; )
- emitDataChanged(column, index(i, 0, parentIndex));
-}
-
-void WatchModel::invalidateAll(const QModelIndex &parentIndex)
-{
- checkIndex(parentIndex);
- QModelIndex idx1 = index(0, 0, parentIndex);
- QModelIndex idx2 = index(rowCount(parentIndex) - 1, columnCount(parentIndex) - 1, parentIndex);
- checkIndex(idx1);
- checkIndex(idx2);
- if (idx1.isValid() && idx2.isValid())
- emit dataChanged(idx1, idx2);
-}
-
-void WatchModel::resetValueCacheRecursively(WatchItem *item)
-{
- m_valueCache[item->iname] = item->value;
- const WatchItems &items = item->children;
- for (int i = items.size(); --i >= 0; )
- resetValueCacheRecursively(items.at(i));
}
// Truncate value for item view, maintaining quotes.
@@ -1005,12 +644,12 @@ static QString truncateValue(QString v)
return v;
}
-int WatchModel::itemFormat(const WatchData &data) const
+int WatchItem::itemFormat() const
{
- const int individualFormat = theIndividualFormats.value(data.iname, AutomaticFormat);
+ const int individualFormat = theIndividualFormats.value(d.iname, AutomaticFormat);
if (individualFormat != AutomaticFormat)
return individualFormat;
- return theTypeFormats.value(stripForFormat(data.type), AutomaticFormat);
+ return theTypeFormats.value(stripForFormat(d.type), AutomaticFormat);
}
bool WatchModel::contentIsValid() const
@@ -1022,57 +661,32 @@ bool WatchModel::contentIsValid() const
return m_handler->m_contentsValid;
}
-#if USE_EXPENSIVE_CHECKS
-void WatchModel::checkTree()
-{
- QSet<QByteArray> inames;
- checkTree(m_root, &inames);
- QSet<QByteArray> current = m_cache.keys().toSet();
- Q_ASSERT(inames == current);
-}
-
-void WatchModel::checkTree(WatchItem *item, QSet<QByteArray> *inames)
-{
- checkItem(item);
- inames->insert(item->iname);
- for (int i = 0, n = item->children.size(); i != n; ++i)
- checkTree(item->children.at(i), inames);
-}
-
-void WatchModel::checkItem(const WatchItem *item) const
-{
- Q_ASSERT(item->children.size() < 1000 * 1000);
- Q_ASSERT(m_cache2.contains(item));
- Q_ASSERT(m_cache2.value(item) == item->iname);
- Q_ASSERT(m_cache.value(item->iname) == item);
-}
-#endif
-
-static QString expression(const WatchItem *item)
+QString WatchItem::expression() const
{
- if (!item->exp.isEmpty())
- return QString::fromLatin1(item->exp);
- if (item->address && !item->type.isEmpty()) {
+ if (!d.exp.isEmpty())
+ return QString::fromLatin1(d.exp);
+ if (d.address && !d.type.isEmpty()) {
return QString::fromLatin1("*(%1*)%2").
- arg(QLatin1String(item->type), QLatin1String(item->hexAddress()));
+ arg(QLatin1String(d.type), QLatin1String(d.hexAddress()));
}
- if (const WatchItem *parent = item->parent) {
- if (!parent->exp.isEmpty())
- return QString::fromLatin1("(%1).%2")
- .arg(QString::fromLatin1(parent->exp), item->name);
+ if (const WatchItem *p = parentItem()) {
+ if (!p->d.exp.isEmpty())
+ return QString::fromLatin1("(%1).%2").arg(QString::fromLatin1(p->d.exp), d.name);
}
return QString();
}
-QString WatchModel::displayName(const WatchItem *item) const
+QString WatchItem::displayName() const
{
QString result;
- if (item->parent == m_returnRoot)
- result = tr("returned value");
- else if (item->name == QLatin1String("*"))
- result = QLatin1Char('*') + item->parent->name;
+ if (!parentItem())
+ return result;
+ if (d.iname.startsWith("return"))
+ result = WatchModel::tr("returned value");
+ else if (parentItem()->d.name == QLatin1String("*"))
+ result = QLatin1Char('*') + parentItem()->d.name;
else
- result = removeNamespaces(item->name);
+ result = watchModel()->removeNamespaces(d.name);
// Simplyfy names that refer to base classes.
if (result.startsWith(QLatin1Char('['))) {
@@ -1084,144 +698,142 @@ QString WatchModel::displayName(const WatchItem *item) const
return result;
}
-QString WatchModel::displayValue(const WatchData &data) const
+QString WatchItem::displayValue() const
{
- QString result = removeNamespaces(truncateValue(formattedValue(data)));
- if (result.isEmpty() && data.address)
- result += QString::fromLatin1("@0x" + QByteArray::number(data.address, 16));
-// if (data.origaddr)
-// result += QString::fromLatin1(" (0x" + QByteArray::number(data.origaddr, 16) + ')');
+ 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) + ')');
return result;
}
-QString WatchModel::displayType(const WatchData &data) const
+QString WatchItem::displayType() const
{
- QString result = data.displayedType.isEmpty()
- ? niceTypeHelper(data.type)
- : data.displayedType;
- if (data.bitsize)
- result += QString::fromLatin1(":%1").arg(data.bitsize);
+ QString result = d.displayedType.isEmpty()
+ ? niceTypeHelper(d.type)
+ : d.displayedType;
+ if (d.bitsize)
+ result += QString::fromLatin1(":%1").arg(d.bitsize);
result.remove(QLatin1Char('\''));
- result = removeNamespaces(result);
+ result = watchModel()->removeNamespaces(result);
return result;
}
-QVariant WatchModel::data(const QModelIndex &idx, int role) const
+QColor WatchItem::color() const
{
- checkIndex(idx);
- if (!idx.isValid())
- return QVariant(); // Triggered by ModelTester.
-
- const WatchItem *item = watchItem(idx);
- const WatchItem &data = *item;
+ static const QColor red(200, 0, 0);
+ static const QColor gray(140, 140, 140);
+ if (watchModel()) {
+ if (!d.valueEnabled)
+ return gray;
+ if (!watchModel()->contentIsValid() && !d.isInspect())
+ return gray;
+ if (d.value.isEmpty()) // This might still show 0x...
+ return gray;
+ if (d.value != watchModel()->m_valueCache.value(d.iname))
+ return red;
+ }
+ return QColor();
+}
+QVariant WatchItem::data(int column, int role) const
+{
switch (role) {
case LocalsEditTypeRole:
- return QVariant(editType(data));
+ return QVariant(editType());
case LocalsNameRole:
- return QVariant(data.name);
+ return QVariant(d.name);
case LocalsIntegerBaseRole:
- if (isPointerType(data.type)) // Pointers using 0x-convention
+ if (isPointerType(d.type)) // Pointers using 0x-convention
return QVariant(16);
- return QVariant(formatToIntegerBase(itemFormat(data)));
+ return QVariant(formatToIntegerBase(itemFormat()));
case Qt::EditRole: {
- switch (idx.column()) {
+ switch (column) {
case 0:
- return QVariant(expression(item));
+ return QVariant(expression());
case 1:
- return editValue(data);
+ return editValue();
case 2:
// FIXME:: To be tested: Can debuggers handle those?
- if (!data.displayedType.isEmpty())
- return data.displayedType;
- return QString::fromUtf8(data.type);
+ if (!d.displayedType.isEmpty())
+ return d.displayedType;
+ return QString::fromUtf8(d.type);
}
}
case Qt::DisplayRole: {
- switch (idx.column()) {
+ switch (column) {
case 0:
- return displayName(item);
+ return displayName();
case 1:
- return displayValue(data);
+ return displayValue();
case 2:
- return displayType(data);
+ return displayType();
}
}
case Qt::ToolTipRole:
return boolSetting(UseToolTipsInLocalsView)
- ? data.toToolTip() : QVariant();
-
- case Qt::ForegroundRole: {
- static const QVariant red(QColor(200, 0, 0));
- static const QVariant gray(QColor(140, 140, 140));
- if (idx.column() == 1) {
- if (!data.valueEnabled)
- return gray;
- if (!contentIsValid() && !data.isInspect())
- return gray;
- if (data.value.isEmpty()) // This might still show 0x...
- return gray;
- if (data.value != m_valueCache.value(data.iname))
- return red;
- }
- break;
- }
+ ? d.toToolTip() : QVariant();
+
+ case Qt::ForegroundRole:
+ if (column == 1)
+ return color();
case LocalsExpressionRole:
- return QVariant(expression(item));
+ return QVariant(expression());
case LocalsRawExpressionRole:
- return data.exp;
+ return d.exp;
case LocalsINameRole:
- return data.iname;
+ return d.iname;
case LocalsExpandedRole:
- return m_expandedINames.contains(data.iname);
+ return watchModel()->m_expandedINames.contains(d.iname);
case LocalsTypeFormatListRole:
- return QVariant::fromValue(typeFormatList(data));
+ return QVariant::fromValue(watchModel()->typeFormatList(d));
case LocalsTypeRole:
- return removeNamespaces(displayType(data));
+ return watchModel()->removeNamespaces(displayType());
case LocalsRawTypeRole:
- return QString::fromLatin1(data.type);
+ return QString::fromLatin1(d.type);
case LocalsTypeFormatRole:
- return theTypeFormats.value(stripForFormat(data.type), AutomaticFormat);
+ return theTypeFormats.value(stripForFormat(d.type), AutomaticFormat);
case LocalsIndividualFormatRole:
- return theIndividualFormats.value(data.iname, AutomaticFormat);
+ return theIndividualFormats.value(d.iname, AutomaticFormat);
case LocalsRawValueRole:
- return data.value;
+ return d.value;
case LocalsObjectAddressRole:
- return data.address;
+ return d.address;
case LocalsPointerAddressRole:
- return data.origaddr;
+ return d.origaddr;
case LocalsIsWatchpointAtObjectAddressRole: {
BreakpointParameters bp(WatchpointAtAddress);
- bp.address = data.address;
- return engine()->breakHandler()->findWatchpoint(bp) != 0;
+ bp.address = d.address;
+ return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0;
}
case LocalsSizeRole:
- return QVariant(data.size);
+ return QVariant(d.size);
case LocalsIsWatchpointAtPointerAddressRole:
- if (isPointerType(data.type)) {
+ if (isPointerType(d.type)) {
BreakpointParameters bp(WatchpointAtAddress);
- bp.address = pointerValue(data.value);
- return engine()->breakHandler()->findWatchpoint(bp) != 0;
+ bp.address = pointerValue(d.value);
+ return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0;
}
return false;
@@ -1233,12 +845,12 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role)
{
- checkIndex(idx);
-
if (!idx.isValid())
return false; // Triggered by ModelTester.
- WatchItem &data = *watchItem(idx);
+ WatchItem *item = static_cast<WatchItem *>(itemFromIndex(idx));
+ QTC_ASSERT(item, return false);
+ const WatchData &data = item->d;
switch (role) {
case Qt::EditRole:
@@ -1246,10 +858,10 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role
case 0: // Watch expression: See delegate.
break;
case 1: // Change value
- engine()->assignValueInDebugger(&data, expression(&data), value);
+ engine()->assignValueInDebugger(&data, item->expression(), value);
break;
case 2: // TODO: Implement change type.
- engine()->assignValueInDebugger(&data, expression(&data), value);
+ engine()->assignValueInDebugger(&data, item->expression(), value);
break;
}
case LocalsExpandedRole:
@@ -1283,66 +895,46 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role
return true;
}
-Qt::ItemFlags WatchModel::flags(const QModelIndex &idx) const
+Qt::ItemFlags WatchItem::flags(int column) const
{
- checkIndex(idx);
- if (!idx.isValid())
- return Qt::ItemFlags();
-
- WatchItem *item = watchItem(idx);
- QTC_ASSERT(item, return Qt::ItemFlags());
- const WatchData &data = *item;
- if (!contentIsValid() && !data.isInspect())
+ QTC_ASSERT(model(), return Qt::ItemFlags());
+ if (!watchModel()->contentIsValid() && !d.isInspect())
return Qt::ItemFlags();
// Enabled, editable, selectable, checkable, and can be used both as the
// source of a drag and drop operation and as a drop target.
- static const Qt::ItemFlags notEditable
- = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
- static const Qt::ItemFlags editable = notEditable | Qt::ItemIsEditable;
+ const Qt::ItemFlags notEditable = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+ const Qt::ItemFlags editable = notEditable | Qt::ItemIsEditable;
// Disable editing if debuggee is positively running except for Inspector data
- const bool isRunning = engine() && engine()->state() == InferiorRunOk;
- if (isRunning && engine() && !engine()->hasCapability(AddWatcherWhileRunningCapability) &&
- !data.isInspect())
+ DebuggerEngine *engine = watchModel()->engine();
+ const bool isRunning = engine && engine->state() == InferiorRunOk;
+ if (isRunning && engine && !engine->hasCapability(AddWatcherWhileRunningCapability) &&
+ !d.isInspect())
return notEditable;
- if (data.isWatcher()) {
- if (idx.column() == 0 && data.iname.count('.') == 1)
+ if (d.isWatcher()) {
+ if (column == 0 && d.iname.count('.') == 1)
return editable; // Watcher names are editable.
- if (!data.name.isEmpty()) {
+ if (!d.name.isEmpty()) {
// FIXME: Forcing types is not implemented yet.
//if (idx.column() == 2)
// return editable; // Watcher types can be set by force.
- if (idx.column() == 1 && data.valueEditable)
+ if (column == 1 && d.valueEditable)
return editable; // Watcher values are sometimes editable.
}
- } else if (data.isLocal()) {
- if (idx.column() == 1 && data.valueEditable)
+ } else if (d.isLocal()) {
+ if (column == 1 && d.valueEditable)
return editable; // Locals values are sometimes editable.
- } else if (data.isInspect()) {
- if (idx.column() == 1 && data.valueEditable)
+ } else if (d.isInspect()) {
+ if (column == 1 && d.valueEditable)
return editable; // Inspector values are sometimes editable.
}
return notEditable;
}
-QVariant WatchModel::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Vertical)
- return QVariant();
- if (role == Qt::DisplayRole) {
- switch (section) {
- case 0: return QString(tr("Name") + QLatin1String(" "));
- case 1: return QString(tr("Value") + QLatin1String(" "));
- case 2: return QString(tr("Type") + QLatin1String(" "));
- }
- }
- return QVariant();
-}
-
static inline QString msgArrayFormat(int n)
{
return WatchModel::tr("Array of %n items", 0, n);
@@ -1486,148 +1078,85 @@ inline bool operator<(const WatchDataSortKey &k1, const WatchDataSortKey &k2)
return watchDataLessThan(k1.iname, k1.sortId, k2.iname, k2.sortId);
}
-bool watchItemSorter(const WatchItem *item1, const WatchItem *item2)
+bool watchItemSorter(const TreeItem *item1, const TreeItem *item2)
{
- return watchDataLessThan(item1->iname, item1->sortId, item2->iname, item2->sortId);
+ 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);
}
-static int findInsertPosition(const QList<WatchItem *> &list, const WatchItem *item)
+static int findInsertPosition(const QVector<TreeItem *> &list, const WatchItem *item)
{
sortWatchDataAlphabetically = boolSetting(SortStructMembers);
- const QList<WatchItem *>::const_iterator it =
- qLowerBound(list.begin(), list.end(), item, watchItemSorter);
+ const auto it = qLowerBound(list.begin(), list.end(), item, watchItemSorter);
return it - list.begin();
}
void WatchModel::insertDataItem(const WatchData &data, bool destructive)
{
-#if USE_WATCH_MODEL_TEST
- (void) new ModelTest(this, this);
-#endif
- m_fetchTriggered.remove(data.iname);
- CHECK(checkTree());
-
QTC_ASSERT(!data.iname.isEmpty(), qDebug() << data.toString(); return);
if (WatchItem *item = findItem(data.iname)) {
// Remove old children.
+ item->fetchTriggered = false;
if (destructive)
- destroyChildren(item);
+ item->removeChildren();
// Overwrite old entry.
- assignData(item, data);
- QModelIndex idx = watchIndex(item);
- checkIndex(idx);
- emit dataChanged(idx, idx.sibling(idx.row(), 2));
+ item->d = data;
+ item->update();
} else {
// Add new entry.
WatchItem *parent = findItem(parentName(data.iname));
QTC_ASSERT(parent, return);
- WatchItem *newItem = createItem(data);
- newItem->parent = parent;
- const int row = findInsertPosition(parent->children, newItem);
- QModelIndex idx = watchIndex(parent);
- checkIndex(idx);
- beginInsertRows(idx, row, row);
- parent->children.insert(row, newItem);
- endInsertRows();
- if (m_expandedINames.contains(parent->iname))
- emit itemIsExpanded(idx);
+ 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));
+ }
}
}
-// Identify items that have to be removed, i.e. current items that
-// have an ancestor in the list, but do not appear in the list themselves.
-bool WatchModel::ancestorChanged(const QSet<QByteArray> &inames, WatchItem *item) const
-{
- if (item == m_root)
- return false;
- WatchItem *parent = item->parent;
- if (inames.contains(parent->iname))
- return true;
- return ancestorChanged(inames, parent);
-}
-
void WatchModel::insertBulkData(const QList<WatchData> &list)
{
-#if 1
for (int i = 0, n = list.size(); i != n; ++i) {
const WatchData &data = list.at(i);
insertDataItem(data, true);
m_handler->showEditValue(data);
}
-#else
- // Destroy unneeded items.
- QSet<QByteArray> inames;
- for (int i = list.size(); --i >= 0; )
- inames.insert(list.at(i).iname);
-
- QList<QByteArray> toDestroy;
- for (Cache::const_iterator it = m_cache.begin(), et = m_cache.end(); it != et; ++it)
- if (!inames.contains(it.key()) && ancestorChanged(inames, it.value()))
- toDestroy.append(it.key());
-
- for (int i = 0, n = toDestroy.size(); i != n; ++i) {
- // Can be destroyed as child of a previous item.
- WatchItem *item = findItem(toDestroy.at(i));
- if (item)
- destroyItem(item);
- }
-
- // All remaining items are changed or new.
- for (int i = 0, n = list.size(); i != n; ++i)
- insertDataItem(list.at(i), false);
-#endif
- CHECK(checkTree());
emit columnAdjustmentRequested();
}
-static void debugRecursion(QDebug &d, const WatchItem *item, int depth)
-{
- d << QString(2 * depth, QLatin1Char(' ')) << item->toString() << '\n';
- foreach (const WatchItem *child, item->children)
- debugRecursion(d, child, depth + 1);
-}
-
-QDebug operator<<(QDebug d, const WatchModel &m)
+int WatchItem::requestedFormat() const
{
- QDebug nospace = d.nospace();
- if (m.m_root)
- debugRecursion(nospace, m.m_root, 0);
- return d;
-}
-
-void WatchModel::formatRequests(QByteArray *out, const WatchItem *item) const
-{
- int format = theIndividualFormats.value(item->iname, AutomaticFormat);
+ int format = theIndividualFormats.value(d.iname, AutomaticFormat);
if (format == AutomaticFormat)
- format = theTypeFormats.value(stripForFormat(item->type), AutomaticFormat);
- if (format != AutomaticFormat)
- *out += item->iname + ":format=" + QByteArray::number(format) + ',';
- foreach (const WatchItem *child, item->children)
- formatRequests(out, child);
+ format = theTypeFormats.value(stripForFormat(d.type), AutomaticFormat);
+ return format;
}
-void WatchModel::showInEditorHelper(QString *contents, WatchItem *item, int depth)
+void WatchItem::showInEditorHelper(QString *contents, int depth) const
{
const QChar tab = QLatin1Char('\t');
const QChar nl = QLatin1Char('\n');
contents->append(QString(depth, tab));
- contents->append(item->name);
+ contents->append(d.name);
contents->append(tab);
- contents->append(item->value);
+ contents->append(d.value);
contents->append(tab);
- contents->append(QString::fromLatin1(item->type));
+ contents->append(QString::fromLatin1(d.type));
contents->append(nl);
- foreach (WatchItem *child, item->children)
- showInEditorHelper(contents, child, depth + 1);
+ foreach (const TreeItem *child, children())
+ static_cast<const WatchItem *>(child)->showInEditorHelper(contents, depth + 1);
}
void WatchModel::setCurrentItem(const QByteArray &iname)
{
if (WatchItem *item = findItem(iname)) {
- QModelIndex idx = watchIndex(item);
- checkIndex(idx);
+ QModelIndex idx = indexFromItem(item);
emit currentIndexRequested(idx);
}
}
@@ -1664,7 +1193,6 @@ void WatchHandler::cleanup()
m_model->m_expandedINames.clear();
theWatcherNames.remove(QByteArray());
m_model->reinitialize();
- m_model->m_fetchTriggered.clear();
m_separatedView->hide();
}
@@ -1698,6 +1226,32 @@ void WatchHandler::insertIncompleteData(const WatchData &data)
}
}
+void WatchHandler::insertItem(WatchItem *item)
+{
+ m_model->insertItem(item);
+}
+
+void WatchModel::insertItem(WatchItem *item)
+{
+ WatchItem *existing = findItem(item->d.iname);
+ if (existing)
+ removeItem(existing);
+
+ WatchItem *parent = findItem(parentName(item->d.iname));
+ QTC_ASSERT(parent, return);
+ const int row = findInsertPosition(parent->children(), item);
+ parent->insertChild(row, item);
+}
+
+void WatchModel::reexpandItems()
+{
+ foreach (const QByteArray &iname, m_expandedINames) {
+ WatchItem *item = findItem(iname);
+ emit itemIsExpanded(indexFromItem(item));
+ emit inameIsExpanded(iname);
+ }
+}
+
void WatchHandler::insertData(const WatchData &data)
{
QList<WatchData> list;
@@ -1722,7 +1276,24 @@ void WatchHandler::removeAllData(bool includeInspectData)
void WatchHandler::resetValueCache()
{
m_model->m_valueCache.clear();
- m_model->resetValueCacheRecursively(m_model->m_root);
+ 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;
+ });
+}
+
+void WatchHandler::purgeOutdatedItems(const QSet<QByteArray> &inames)
+{
+ foreach (const QByteArray &iname, inames) {
+ WatchItem *item = findItem(iname);
+ m_model->removeItem(item);
+ }
+
+ m_model->layoutChanged();
+ m_model->reexpandItems();
+ m_contentsValid = true;
+ updateWatchersWindow();
}
void WatchHandler::removeData(const QByteArray &iname)
@@ -1730,11 +1301,12 @@ void WatchHandler::removeData(const QByteArray &iname)
WatchItem *item = m_model->findItem(iname);
if (!item)
return;
- if (item->isWatcher()) {
- theWatcherNames.remove(item->exp);
+ if (item->d.isWatcher()) {
+ theWatcherNames.remove(item->d.exp);
saveWatchers();
}
- m_model->destroyItem(item);
+ m_model->removeItem(item);
+ delete item;
updateWatchersWindow();
}
@@ -1742,7 +1314,7 @@ void WatchHandler::removeChildren(const QByteArray &iname)
{
WatchItem *item = m_model->findItem(iname);
if (item)
- m_model->destroyChildren(item);
+ item->removeChildren();
updateWatchersWindow();
}
@@ -1883,7 +1455,15 @@ void WatchHandler::clearWatches()
{
if (theWatcherNames.isEmpty())
return;
- m_model->destroyChildren(m_model->m_watchRoot);
+
+ const QDialogButtonBox::StandardButton ret = CheckableMessageBox::doNotAskAgainQuestion(
+ Core::ICore::mainWindow(), tr("Remove All Expression Evaluators"),
+ tr("Are you sure you want to remove all expression evaluators?"),
+ Core::ICore::settings(), QLatin1String("RemoveAllWatchers"));
+ if (ret != QDialogButtonBox::Yes)
+ return;
+
+ m_model->m_watchRoot->removeChildren();
theWatcherNames.clear();
m_watcherCounter = 0;
updateWatchersWindow();
@@ -1895,8 +1475,8 @@ void WatchHandler::updateWatchersWindow()
// Force show/hide of watchers and return view.
static int previousShowWatch = -1;
static int previousShowReturn = -1;
- int showWatch = !m_model->m_watchRoot->children.isEmpty();
- int showReturn = !m_model->m_returnRoot->children.isEmpty();
+ int showWatch = !m_model->m_watchRoot->children().isEmpty();
+ int showReturn = !m_model->m_returnRoot->children().isEmpty();
if (showWatch == previousShowWatch && showReturn == previousShowReturn)
return;
previousShowWatch = showWatch;
@@ -1981,7 +1561,7 @@ void WatchHandler::loadSessionData()
theWatcherNames.clear();
m_watcherCounter = 0;
QVariant value = sessionValue("Watchers");
- m_model->destroyChildren(m_model->m_watchRoot);
+ m_model->m_watchRoot->removeChildren();
foreach (const QString &exp, value.toStringList())
watchExpression(exp);
}
@@ -1993,18 +1573,25 @@ WatchModelBase *WatchHandler::model() const
const WatchData *WatchHandler::watchData(const QModelIndex &idx) const
{
- return m_model->watchItem(idx);
+ TreeItem *item = m_model->itemFromIndex(idx);
+ return item ? &static_cast<WatchItem *>(item)->d : 0;
}
void WatchHandler::fetchMore(const QByteArray &iname) const
{
- QModelIndex idx = m_model->watchIndex(m_model->findItem(iname));
- m_model->checkIndex(idx);
- model()->fetchMore(idx);
+ WatchItem *item = m_model->findItem(iname);
+ if (item)
+ 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);
}
@@ -2035,36 +1622,20 @@ void WatchHandler::setFormat(const QByteArray &type0, int format)
else
theTypeFormats[type] = format;
saveFormats();
- m_model->emitDataChanged(1);
+ m_model->reinsertAllData();
}
int WatchHandler::format(const QByteArray &iname) const
{
int result = AutomaticFormat;
- if (const WatchData *item = m_model->findItem(iname)) {
- int result = theIndividualFormats.value(item->iname, AutomaticFormat);
+ if (const WatchItem *item = m_model->findItem(iname)) {
+ int result = theIndividualFormats.value(item->d.iname, AutomaticFormat);
if (result == AutomaticFormat)
- result = theTypeFormats.value(stripForFormat(item->type), AutomaticFormat);
+ result = theTypeFormats.value(stripForFormat(item->d.type), AutomaticFormat);
}
return result;
}
-QByteArray WatchHandler::expansionRequests() const
-{
- QByteArray ba;
- m_model->formatRequests(&ba, m_model->m_root);
- if (!m_model->m_expandedINames.isEmpty()) {
- QSetIterator<QByteArray> jt(m_model->m_expandedINames);
- while (jt.hasNext()) {
- QByteArray iname = jt.next();
- ba.append(iname);
- ba.append(',');
- }
- ba.chop(1);
- }
- return ba;
-}
-
QByteArray WatchHandler::typeFormatRequests() const
{
QByteArray ba;
@@ -2105,6 +1676,55 @@ QByteArray WatchHandler::individualFormatRequests() const
return ba;
}
+void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
+{
+ cmd->beginList("expanded");
+ QSetIterator<QByteArray> jt(m_model->m_expandedINames);
+ while (jt.hasNext()) {
+ QByteArray iname = jt.next();
+ //WatchItem *item = m_model->findItem(iname);
+ cmd->arg(iname);
+ //cmd->arg("format", item->requestedFormat());
+ }
+ cmd->endList();
+
+ cmd->beginGroup("typeformats");
+ QHashIterator<QByteArray, int> it(theTypeFormats);
+ while (it.hasNext()) {
+ it.next();
+ const int format = it.value();
+ if (format >= RawFormat && format < ArtificialFormatBase)
+ cmd->arg(it.key(), format);
+ }
+ cmd->endGroup();
+
+ cmd->beginGroup("formats");
+ QHashIterator<QByteArray, int> it2(theIndividualFormats);
+ while (it2.hasNext()) {
+ it2.next();
+ const int format = it2.value();
+ if (format >= RawFormat && format < ArtificialFormatBase)
+ cmd->arg(it2.key(), format);
+ }
+ cmd->endGroup();
+}
+
+void WatchHandler::addDumpers(const GdbMi &dumpers)
+{
+ foreach (const GdbMi &dumper, dumpers.children()) {
+ QStringList formats(tr("Raw structure"));
+ foreach (const QByteArray &format, dumper["formats"].data().split(',')) {
+ if (format == "Normal")
+ formats.append(tr("Normal"));
+ else if (format == "Displayed")
+ formats.append(tr("Displayed"));
+ else if (!format.isEmpty())
+ formats.append(QString::fromLatin1(format));
+ }
+ addTypeFormats(dumper["type"].data(), formats);
+ }
+}
+
void WatchHandler::addTypeFormats(const QByteArray &type, const QStringList &formats)
{
m_model->m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats);
@@ -2113,7 +1733,7 @@ void WatchHandler::addTypeFormats(const QByteArray &type, const QStringList &for
QString WatchHandler::editorContents()
{
QString contents;
- m_model->showInEditorHelper(&contents, m_model->m_root, 0);
+ m_model->root()->showInEditorHelper(&contents, 0);
return contents;
}
@@ -2152,16 +1772,7 @@ void WatchHandler::scheduleResetLocation()
void WatchHandler::resetLocation()
{
- if (m_resetLocationScheduled) {
- m_resetLocationScheduled = false;
- //m_model->invalidateAll(); FIXME
- }
-}
-
-bool WatchHandler::isValidToolTip(const QByteArray &iname) const
-{
- WatchItem *item = m_model->findItem(iname);
- return item && !item->type.trimmed().isEmpty();
+ m_resetLocationScheduled = false;
}
void WatchHandler::setCurrentItem(const QByteArray &iname)
@@ -2177,7 +1788,7 @@ QHash<QByteArray, int> WatchHandler::watcherNames()
void WatchHandler::setUnprintableBase(int base)
{
theUnprintableBase = base;
- m_model->emitAllChanged();
+ m_model->layoutChanged();
}
int WatchHandler::unprintableBase()
@@ -2219,6 +1830,83 @@ TypeFormatItem TypeFormatList::find(int format) const
return TypeFormatItem();
}
+////////////////////////////////////////////////////////////////////
+//
+// WatchItem
+//
+////////////////////////////////////////////////////////////////////
+
+WatchItem::WatchItem()
+ : fetchTriggered(false)
+{}
+
+WatchItem::WatchItem(const QByteArray &i, const QString &n)
+{
+ fetchTriggered = false;
+ d.iname = i;
+ d.name = n;
+}
+
+WatchItem::WatchItem(const WatchData &data)
+ : d(data), fetchTriggered(false)
+{
+}
+
+WatchItem::WatchItem(const GdbMi &data)
+ : fetchTriggered(false)
+{
+ d.iname = data["iname"].data();
+
+ GdbMi wname = data["wname"];
+ if (wname.isValid()) // Happens (only) for watched expressions.
+ d.name = QString::fromUtf8(QByteArray::fromHex(wname.data()));
+ else
+ d.name = QString::fromLatin1(data["name"].data());
+
+ parseWatchData(data);
+
+ if (wname.isValid())
+ d.exp = d.name.toUtf8();
+}
+
+WatchItem *WatchItem::parentItem() const
+{
+ return dynamic_cast<WatchItem *>(parent());
+}
+
+const WatchModel *WatchItem::watchModel() const
+{
+ return static_cast<const WatchModel *>(model());
+}
+
+WatchModel *WatchItem::watchModel()
+{
+ return static_cast<WatchModel *>(model());
+}
+
+void WatchItem::parseWatchData(const GdbMi &input)
+{
+ auto itemHandler = [this](const WatchData &data) {
+ d = data;
+ };
+ auto childHandler = [this](const WatchData &innerData, const GdbMi &innerInput) {
+ WatchItem *item = new WatchItem(innerData);
+ item->parseWatchData(innerInput);
+ appendChild(item);
+ };
+
+ auto itemAdder = [this](const WatchData &data) {
+ appendChild(new WatchItem(data));
+ };
+
+ auto arrayDecoder = [itemAdder](const WatchData &childTemplate,
+ const QByteArray &encodedData, int encoding) {
+ decodeArrayData(itemAdder, childTemplate, encodedData, encoding);
+ };
+
+ parseChildrenData(d, input, itemHandler, childHandler, arrayDecoder);
+}
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index e5f5f9b9a4..444bef881f 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -33,16 +33,58 @@
#include "watchdata.h"
-#include <QAbstractItemModel>
+#include <utils/treemodel.h>
+
#include <QPointer>
#include <QVector>
namespace Debugger {
namespace Internal {
+class DebuggerCommand;
class SeparatedView;
class WatchModel;
+class WatchItem : public Utils::TreeItem
+{
+public:
+ WatchItem();
+ WatchItem(const QByteArray &i, const QString &n);
+ 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;
+ QString displayType() const;
+ QString displayValue() const;
+ QString formattedValue() const;
+ QString expression() const;
+
+ int itemFormat() const;
+
+ QVariant editValue() const;
+ int editType() const;
+ QColor color() const;
+
+ int requestedFormat() const;
+ void showInEditorHelper(QString *contents, int depth) const;
+ WatchItem *findItem(const QByteArray &iname);
+ void parseWatchData(const GdbMi &input);
+
+public:
+ WatchData d;
+ bool fetchTriggered;
+};
+
// Special formats. Keep in sync with dumper.py.
enum DisplayFormat
{
@@ -108,25 +150,22 @@ public:
Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList)
namespace Debugger {
+namespace Internal {
class DebuggerEngine;
-namespace Internal {
-
class UpdateParameters
{
public:
- UpdateParameters() { tryPartial = tooltipOnly = false; }
+ UpdateParameters() { tryPartial = false; }
bool tryPartial;
- bool tooltipOnly;
QByteArray varList;
- QString tooltipExpression;
};
typedef QHash<QString, QStringList> DumperTypeFormats; // Type name -> Dumper Formats
-class WatchModelBase : public QAbstractItemModel
+class WatchModelBase : public Utils::TreeModel
{
Q_OBJECT
@@ -136,6 +175,7 @@ public:
signals:
void currentIndexRequested(const QModelIndex &idx);
void itemIsExpanded(const QModelIndex &idx);
+ void inameIsExpanded(const QByteArray &iname);
void columnAdjustmentRequested();
};
@@ -159,6 +199,7 @@ public:
const WatchData *watchData(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;
bool hasItem(const QByteArray &iname) const;
@@ -171,12 +212,12 @@ public:
static QStringList watchedExpressions();
static QHash<QByteArray, int> watcherNames();
- QByteArray expansionRequests() const;
QByteArray typeFormatRequests() const;
QByteArray individualFormatRequests() const;
int format(const QByteArray &iname) const;
+ void addDumpers(const GdbMi &dumpers);
void addTypeFormats(const QByteArray &type, const QStringList &formats);
void setTypeFormats(const DumperTypeFormats &typeFormats);
DumperTypeFormats typeFormats() const;
@@ -190,18 +231,20 @@ public:
void scheduleResetLocation();
void resetLocation();
- bool isValidToolTip(const QByteArray &iname) const;
void setCurrentItem(const QByteArray &iname);
void updateWatchersWindow();
+ void appendFormatRequests(DebuggerCommand *cmd);
void insertData(const WatchData &data); // Convenience.
void insertData(const QList<WatchData> &list);
void insertIncompleteData(const WatchData &data);
+ void insertItem(WatchItem *item);
void removeData(const QByteArray &iname);
void removeChildren(const QByteArray &iname);
void removeAllData(bool includeInspectData = false);
void resetValueCache();
+ void purgeOutdatedItems(const QSet<QByteArray> &inames);
private:
friend class WatchModel;
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index 55b2e7da4e..2ea8632e58 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -44,9 +44,12 @@
#include <texteditor/syntaxhighlighter.h>
+#include <coreplugin/messagebox.h>
+
+#include <utils/fancylineedit.h>
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
-#include <utils/fancylineedit.h>
+#include <utils/treemodel.h>
#include <QApplication>
#include <QClipboard>
@@ -55,11 +58,11 @@
#include <QInputDialog>
#include <QItemDelegate>
#include <QMenu>
-#include <QMessageBox>
#include <QMetaProperty>
#include <QMimeData>
#include <QScrollBar>
#include <QTimer>
+#include <QTextStream>
// For InputDialog, move to Utils?
#include <coreplugin/helpmanager.h>
@@ -68,14 +71,6 @@
#include <QButtonGroup>
#include <QDialogButtonBox>
-//#define USE_WATCH_MODEL_TEST 1
-
-#if USE_WATCH_MODEL_TEST
-#include <modeltest.h>
-#endif
-
-Q_DECLARE_METATYPE(QModelIndex)
-
/////////////////////////////////////////////////////////////////////
//
// WatchDelegate
@@ -85,8 +80,6 @@ Q_DECLARE_METATYPE(QModelIndex)
namespace Debugger {
namespace Internal {
-const char CurrentIndex[] = "CurrentIndex";
-
class WatchDelegate : public QItemDelegate
{
public:
@@ -177,21 +170,6 @@ static inline uint sizeOf(const QModelIndex &m)
return m.data(LocalsSizeRole).toUInt();
}
-// Create a map of value->name for register markup.
-typedef QMap<quint64, QString> RegisterMap;
-typedef RegisterMap::const_iterator RegisterMapConstIt;
-
-RegisterMap registerMap(const DebuggerEngine *engine)
-{
- RegisterMap result;
- foreach (const Register &reg, engine->registerHandler()->registers()) {
- const QVariant v = reg.editValue();
- if (v.type() == QVariant::ULongLong)
- result.insert(v.toULongLong(), QString::fromLatin1(reg.name));
- }
- return result;
-}
-
// Helper functionality to indicate the area of a member variable in
// a vector representing the memory area by a unique color
// number and tooltip. Parts of it will be overwritten when recursing
@@ -313,13 +291,12 @@ static MemoryMarkupList
if (sizeIsEstimate && !childCount)
return result; // Fixme: Exact size not known, no point in filling if no children.
// Punch in registers as 1-byte markers on top.
- const RegisterMapConstIt regcEnd = registerMap.constEnd();
- for (RegisterMapConstIt it = registerMap.constBegin(); it != regcEnd; ++it) {
+ for (auto it = registerMap.constBegin(), end = registerMap.constEnd(); it != end; ++it) {
if (it.key() >= address) {
const quint64 offset = it.key() - address;
if (offset < size) {
ranges[offset] = ColorNumberToolTip(registerColorNumber,
- WatchTreeView::tr("Register <i>%1</i>").arg(it.value()));
+ WatchTreeView::tr("Register <i>%1</i>").arg(QString::fromUtf8(it.value())));
} else {
break; // Sorted.
}
@@ -380,27 +357,27 @@ static void addVariableMemoryView(DebuggerEngine *engine, bool separateView,
const QPoint &p, QWidget *parent)
{
const QColor background = parent->palette().color(QPalette::Normal, QPalette::Base);
- const quint64 address = atPointerAddress ? pointerAddressOf(m) : addressOf(m);
+ MemoryViewSetupData data;
+ data.startAddress = atPointerAddress ? pointerAddressOf(m) : addressOf(m);
+ if (!data.startAddress)
+ return;
// Fixme: Get the size of pointee (see variableMemoryMarkup())?
const QString rootToolTip = variableToolTip(nameOf(m), typeOf(m), 0);
const quint64 typeSize = sizeOf(m);
const bool sizeIsEstimate = atPointerAddress || !typeSize;
const quint64 size = sizeIsEstimate ? 1024 : typeSize;
- if (!address)
- return;
- const QList<MemoryMarkup> markup =
- variableMemoryMarkup(m.model(), m, nameOf(m), rootToolTip,
- address, size,
- registerMap(engine),
+ data.markup = variableMemoryMarkup(m.model(), m, nameOf(m), rootToolTip,
+ data.startAddress, size,
+ engine->registerHandler()->registerMap(),
sizeIsEstimate, background);
- const unsigned flags = separateView
- ? DebuggerEngine::MemoryView|DebuggerEngine::MemoryReadOnly : 0;
- const QString title = atPointerAddress
+ data.flags = separateView ? DebuggerEngine::MemoryView|DebuggerEngine::MemoryReadOnly : 0;
+ QString pat = atPointerAddress
? WatchTreeView::tr("Memory at Pointer's Address \"%1\" (0x%2)")
- .arg(nameOf(m)).arg(address, 0, 16)
- : WatchTreeView::tr("Memory at Object's Address \"%1\" (0x%2)")
- .arg(nameOf(m)).arg(address, 0, 16);
- engine->openMemoryView(address, flags, markup, p, title, parent);
+ : WatchTreeView::tr("Memory at Object's Address \"%1\" (0x%2)");
+ data.title = pat.arg(nameOf(m)).arg(data.startAddress, 0, 16);
+ data.pos = p;
+ data.parent = parent;
+ engine->openMemoryView(data);
}
// Add a memory view of the stack layout showing local variables
@@ -436,16 +413,15 @@ static void addStackLayoutMemoryView(DebuggerEngine *engine, bool separateView,
end += 8 - remainder;
// Anything found and everything in a sensible range (static data in-between)?
if (end <= start || end - start > 100 * 1024) {
- QMessageBox::information(parent,
+ Core::AsynchronousMessageBox::information(
WatchTreeView::tr("Cannot Display Stack Layout"),
WatchTreeView::tr("Could not determine a suitable address range."));
return;
}
// Take a look at the register values. Extend the range a bit if suitable
// to show stack/stack frame pointers.
- const RegisterMap regMap = registerMap(engine);
- const RegisterMapConstIt regcEnd = regMap.constEnd();
- for (RegisterMapConstIt it = regMap.constBegin(); it != regcEnd; ++it) {
+ const RegisterMap regMap = engine->registerHandler()->registerMap();
+ for (auto it = regMap.constBegin(), cend = regMap.constEnd(); it != cend; ++it) {
const quint64 value = it.key();
if (value < start && start - value < 512)
start = value;
@@ -453,16 +429,18 @@ static void addStackLayoutMemoryView(DebuggerEngine *engine, bool separateView,
end = value + 1;
}
// Indicate all variables.
+ MemoryViewSetupData data;
const QColor background = parent->palette().color(QPalette::Normal, QPalette::Base);
- const MemoryMarkupList markup =
- variableMemoryMarkup(m, localsIndex, QString(),
+ data.startAddress = start;
+ data.markup = variableMemoryMarkup(m, localsIndex, QString(),
QString(), start, end - start,
regMap, true, background);
- const unsigned flags = separateView
+ data.flags = separateView
? (DebuggerEngine::MemoryView|DebuggerEngine::MemoryReadOnly) : 0;
- const QString title =
- WatchTreeView::tr("Memory Layout of Local Variables at 0x%1").arg(start, 0, 16);
- engine->openMemoryView(start, flags, markup, p, title, parent);
+ data.title = WatchTreeView::tr("Memory Layout of Local Variables at 0x%1").arg(start, 0, 16);
+ data.pos = p;
+ data.parent = parent;
+ engine->openMemoryView(data);
}
/////////////////////////////////////////////////////////////////////
@@ -484,10 +462,8 @@ WatchTreeView::WatchTreeView(WatchType type)
setAcceptDrops(true);
setDropIndicatorShown(true);
- connect(this, SIGNAL(expanded(QModelIndex)),
- SLOT(expandNode(QModelIndex)));
- connect(this, SIGNAL(collapsed(QModelIndex)),
- SLOT(collapseNode(QModelIndex)));
+ connect(this, &QTreeView::expanded, this, &WatchTreeView::expandNode);
+ connect(this, &QTreeView::collapsed, this, &WatchTreeView::collapseNode);
}
void WatchTreeView::expandNode(const QModelIndex &idx)
@@ -615,28 +591,23 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
formatMenu->addAction(tr("Treat All Characters as Printable"));
showUnprintableUnicode->setCheckable(true);
showUnprintableUnicode->setChecked(unprintableBase == 0);
- showUnprintableUnicode->setData(0);
showUnprintableEscape =
formatMenu->addAction(tr("Show Unprintable Characters as Escape Sequences"));
showUnprintableEscape->setCheckable(true);
showUnprintableEscape->setChecked(unprintableBase == -1);
- showUnprintableEscape->setData(-1);
showUnprintableOctal =
formatMenu->addAction(tr("Show Unprintable Characters as Octal"));
showUnprintableOctal->setCheckable(true);
showUnprintableOctal->setChecked(unprintableBase == 8);
- showUnprintableOctal->setData(8);
showUnprintableHexadecimal =
formatMenu->addAction(tr("Show Unprintable Characters as Hexadecimal"));
showUnprintableHexadecimal->setCheckable(true);
showUnprintableHexadecimal->setChecked(unprintableBase == 16);
- showUnprintableHexadecimal->setData(16);
-
- connect(showUnprintableUnicode, SIGNAL(triggered()), SLOT(onShowUnprintable()));
- connect(showUnprintableEscape, SIGNAL(triggered()), SLOT(onShowUnprintable()));
- connect(showUnprintableOctal, SIGNAL(triggered()), SLOT(onShowUnprintable()));
- connect(showUnprintableHexadecimal, SIGNAL(triggered()), SLOT(onShowUnprintable()));
+ connect(showUnprintableUnicode, &QAction::triggered, [this] { showUnprintable(0); });
+ connect(showUnprintableEscape, &QAction::triggered, [this] { showUnprintable(-1); });
+ connect(showUnprintableOctal, &QAction::triggered, [this] { showUnprintable(8); });
+ connect(showUnprintableHexadecimal, &QAction::triggered, [this] { showUnprintable(16); });
const QString spacer = QLatin1String(" ");
formatMenu->addSeparator();
@@ -651,19 +622,22 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
QAction *clearIndividualFormatAction = formatMenu->addAction(spacer + msg);
clearIndividualFormatAction->setCheckable(true);
clearIndividualFormatAction->setChecked(individualFormat == AutomaticFormat);
- connect(clearIndividualFormatAction, SIGNAL(triggered()),
- SLOT(onClearIndividualFormat()));
+ connect(clearIndividualFormatAction, &QAction::triggered, [this] {
+ const QModelIndexList active = activeRows();
+ foreach (const QModelIndex &idx, active)
+ setModelData(LocalsIndividualFormatRole, AutomaticFormat, idx);
+ });
for (int i = 0; i != alternativeFormats.size(); ++i) {
const QString display = spacer + alternativeFormats.at(i).display;
const int format = alternativeFormats.at(i).format;
QAction *act = new QAction(display, formatMenu);
- act->setData(format);
act->setCheckable(true);
act->setChecked(format == individualFormat);
- act->setProperty(CurrentIndex, QVariant::fromValue(mi));
formatMenu->addAction(act);
- connect(act, SIGNAL(triggered()), SLOT(onIndividualFormatChange()));
+ connect(act, &QAction::triggered, [this, act, format, mi] {
+ setModelData(LocalsIndividualFormatRole, format, mi);
+ });
}
formatMenu->addSeparator();
@@ -673,58 +647,30 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
QAction *clearTypeFormatAction = formatMenu->addAction(spacer + tr("Automatic"));
clearTypeFormatAction->setCheckable(true);
clearTypeFormatAction->setChecked(typeFormat == AutomaticFormat);
- connect(clearTypeFormatAction, SIGNAL(triggered()), SLOT(onClearTypeFormat()));
+ connect(clearTypeFormatAction, &QAction::triggered, [this] {
+ const QModelIndexList active = activeRows();
+ foreach (const QModelIndex &idx, active)
+ setModelData(LocalsTypeFormatRole, AutomaticFormat, idx);
+ });
for (int i = 0; i != alternativeFormats.size(); ++i) {
const QString display = spacer + alternativeFormats.at(i).display;
QAction *act = new QAction(display, formatMenu);
const int format = alternativeFormats.at(i).format;
- act->setData(format);
act->setCheckable(true);
act->setChecked(format == typeFormat);
- act->setProperty(CurrentIndex, QVariant::fromValue(mi));
formatMenu->addAction(act);
- connect(act, SIGNAL(triggered()), SLOT(onTypeFormatChange()));
+ connect(act, &QAction::triggered, [this, act, format, mi] {
+ setModelData(LocalsTypeFormatRole, format, mi);
+ });
}
}
-void WatchTreeView::onClearTypeFormat()
+void WatchTreeView::showUnprintable(int base)
{
- const QModelIndexList active = activeRows();
- foreach (const QModelIndex &idx, active)
- setModelData(LocalsTypeFormatRole, AutomaticFormat, idx);
-}
-
-void WatchTreeView::onClearIndividualFormat()
-{
- const QModelIndexList active = activeRows();
- foreach (const QModelIndex &idx, active)
- setModelData(LocalsIndividualFormatRole, AutomaticFormat, idx);
-}
-
-void WatchTreeView::onShowUnprintable()
-{
- QAction *act = qobject_cast<QAction *>(sender());
- QTC_ASSERT(act, return);
DebuggerEngine *engine = currentEngine();
WatchHandler *handler = engine->watchHandler();
- handler->setUnprintableBase(act->data().toInt());
-}
-
-void WatchTreeView::onTypeFormatChange()
-{
- QAction *act = qobject_cast<QAction *>(sender());
- QTC_ASSERT(act, return);
- QModelIndex idx = act->property(CurrentIndex).value<QModelIndex>();
- setModelData(LocalsTypeFormatRole, act->data(), idx);
-}
-
-void WatchTreeView::onIndividualFormatChange()
-{
- QAction *act = qobject_cast<QAction *>(sender());
- QTC_ASSERT(act, return);
- QModelIndex idx = act->property(CurrentIndex).value<QModelIndex>();
- setModelData(LocalsIndividualFormatRole, act->data(), idx);
+ handler->setUnprintableBase(base);
}
void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev)
@@ -810,11 +756,16 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev)
break;
p = pp;
}
+
+ bool showExpressionActions = (canHandleWatches || state == DebuggerNotReady) && m_type == WatchersType;
+
QString removeExp = p.data(LocalsExpressionRole).toString();
QAction actRemoveWatchExpression(removeWatchActionText(removeExp), 0);
- actRemoveWatchExpression.setEnabled(
- (canHandleWatches || state == DebuggerNotReady)
- && !exp.isEmpty() && m_type == WatchersType);
+ actRemoveWatchExpression.setEnabled(showExpressionActions && !exp.isEmpty());
+
+ QAction actRemoveAllWatchExpression(tr("Remove All Expression Evaluators"), 0);
+ actRemoveAllWatchExpression.setEnabled(showExpressionActions
+ && !handler->watchedExpressions().isEmpty());
QMenu formatMenu(tr("Change Local Display Format..."));
if (mi0.isValid())
@@ -891,6 +842,7 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev)
menu.addAction(&actInsertNewWatchItem);
menu.addAction(&actWatchExpression);
menu.addAction(&actRemoveWatchExpression);
+ menu.addAction(&actRemoveAllWatchExpression);
menu.addAction(&actSelectWidgetToWatch);
menu.addSeparator();
@@ -929,8 +881,11 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev)
AddressDialog dialog;
if (address)
dialog.setAddress(address);
- if (dialog.exec() == QDialog::Accepted)
- currentEngine()->openMemoryView(dialog.address(), false, MemoryMarkupList(), QPoint());
+ if (dialog.exec() == QDialog::Accepted) {
+ MemoryViewSetupData data;
+ data.startAddress = dialog.address();
+ currentEngine()->openMemoryView(data);
+ }
} else if (act == &actOpenMemoryViewAtObjectAddress) {
addVariableMemoryView(currentEngine(), true, mi0, false, ev->globalPos(), this);
} else if (act == &actOpenMemoryViewAtPointerAddress) {
@@ -950,8 +905,20 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev)
watchExpression(exp, name);
} else if (act == &actRemoveWatchExpression) {
handler->removeData(p.data(LocalsINameRole).toByteArray());
+ } else if (act == &actRemoveAllWatchExpression) {
+ handler->clearWatches();
} else if (act == &actCopy) {
- copyToClipboard(DebuggerToolTipManager::treeModelClipboardContents(model()));
+ QString text;
+ QTextStream str(&text);
+ handler->model()->rootItem()->walkTree([&str](Utils::TreeItem *item) {
+ str << QString(item->level(), QLatin1Char('\t'))
+ << item->data(0, Qt::DisplayRole).toString() << '\t'
+ << item->data(1, Qt::DisplayRole).toString() << '\t'
+ << item->data(2, Qt::DisplayRole).toString() << '\n';
+ });
+ QClipboard *clipboard = QApplication::clipboard();
+ clipboard->setText(text, QClipboard::Selection);
+ clipboard->setText(text, QClipboard::Clipboard);
} else if (act == &actCopyValue) {
copyToClipboard(mi1.data().toString());
} else if (act == &actShowInEditor) {
@@ -995,14 +962,14 @@ void WatchTreeView::setModel(QAbstractItemModel *model)
header()->hide();
}
- connect(model, SIGNAL(layoutChanged()), SLOT(resetHelper()));
- connect(model, SIGNAL(currentIndexRequested(QModelIndex)),
- SLOT(setCurrentIndex(QModelIndex)));
- connect(model, SIGNAL(itemIsExpanded(QModelIndex)),
- SLOT(handleItemIsExpanded(QModelIndex)));
-#if USE_WATCH_MODEL_TEST
- (void) new ModelTest(&m_filter, this);
-#endif
+ auto watchModel = qobject_cast<WatchModelBase *>(model);
+ QTC_ASSERT(watchModel, return);
+ connect(model, &QAbstractItemModel::layoutChanged,
+ this, &WatchTreeView::resetHelper);
+ connect(watchModel, &WatchModelBase::currentIndexRequested,
+ this, &QAbstractItemView::setCurrentIndex);
+ connect(watchModel, &WatchModelBase::itemIsExpanded,
+ this, &WatchTreeView::handleItemIsExpanded);
}
void WatchTreeView::rowActivated(const QModelIndex &index)
@@ -1046,8 +1013,10 @@ void WatchTreeView::resetHelper()
void WatchTreeView::reset()
{
BaseTreeView::reset();
- setRootIndex(model()->index(m_type, 0));
- resetHelper();
+ if (model()) {
+ setRootIndex(model()->index(m_type, 0));
+ resetHelper();
+ }
}
void WatchTreeView::doItemsLayout()
@@ -1106,8 +1075,8 @@ public:
setLayout(layout);
connect(m_buttons, SIGNAL(accepted()), m_lineEdit, SLOT(onEditingFinished()));
- connect(m_buttons, SIGNAL(accepted()), SLOT(accept()));
- connect(m_buttons, SIGNAL(rejected()), SLOT(reject()));
+ connect(m_buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(m_buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(m_hint, SIGNAL(linkActivated(QString)),
Core::HelpManager::instance(), SLOT(handleHelpRequest(QString)));
}
diff --git a/src/plugins/debugger/watchwindow.h b/src/plugins/debugger/watchwindow.h
index 21bc41c607..8ba2a76ab9 100644
--- a/src/plugins/debugger/watchwindow.h
+++ b/src/plugins/debugger/watchwindow.h
@@ -67,20 +67,13 @@ public slots:
signals:
void currentIndexChanged(const QModelIndex &currentIndex);
-private slots:
+private:
void resetHelper();
void expandNode(const QModelIndex &idx);
void collapseNode(const QModelIndex &idx);
- void adjustSlider();
-
- void onClearIndividualFormat();
- void onClearTypeFormat();
- void onShowUnprintable();
+ Q_SLOT void adjustSlider(); // Used by single-shot timer.
- void onTypeFormatChange();
- void onIndividualFormatChange();
-
-private:
+ void showUnprintable(int base);
void doItemsLayout();
void keyPressEvent(QKeyEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);