Commit ed30a3f7 authored by Friedemann Kleint's avatar Friedemann Kleint

Debugger: Use bin editor widget for standalone-memory views.

Remove MemoryViewWidget/RegisterMemoryViewWidget
in favour of MemoryView/RegisterMemoryView based on the bin
editor widget.
parent ce67924b
......@@ -64,7 +64,7 @@ HEADERS += breakhandler.h \
debuggertooltipmanager.h \
debuggertoolchaincombobox.h \
debuggersourcepathmappingwidget.h \
memoryviewwidget.h
memoryview.h
SOURCES += breakhandler.cpp \
breakpoint.cpp \
......@@ -108,7 +108,7 @@ SOURCES += breakhandler.cpp \
debuggertooltipmanager.cpp \
debuggertoolchaincombobox.cpp \
debuggersourcepathmappingwidget.cpp \
memoryviewwidget.cpp
memoryview.cpp
FORMS += attachexternaldialog.ui \
attachcoredialog.ui \
......
......@@ -1569,14 +1569,11 @@ bool DebuggerEngine::isCppBreakpoint(const BreakpointParameters &p)
&& !p.fileName.endsWith(QLatin1String(".js"), Qt::CaseInsensitive);
}
void DebuggerEngine::openMemoryView(quint64 address)
void DebuggerEngine::openMemoryView(quint64 startAddr, unsigned flags,
const QList<MemoryMarkup> &ml, const QPoint &pos,
const QString &title, QWidget *parent)
{
d->m_memoryAgent.createBinEditor(address);
}
void DebuggerEngine::addMemoryView(Internal::MemoryViewWidget *w)
{
d->m_memoryAgent.addMemoryView(w);
d->m_memoryAgent.createBinEditor(startAddr, flags, ml, pos, title, parent);
}
void DebuggerEngine::updateMemoryViews()
......
......@@ -81,7 +81,7 @@ class WatchHandler;
class BreakpointParameters;
class QmlCppEngine;
class DebuggerToolTipContext;
class MemoryViewWidget;
class MemoryMarkup;
struct WatchUpdateFlags
{
......@@ -156,8 +156,18 @@ public:
virtual void startDebugger(DebuggerRunControl *runControl);
virtual void watchPoint(const QPoint &);
virtual void openMemoryView(quint64 addr);
virtual void addMemoryView(Internal::MemoryViewWidget *w);
enum MemoryViewFlags
{
MemoryReadOnly = 0x1, //!< Read-only.
MemoryTrackRegister = 0x2, //!< Address parameter is register number to track
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 fetchMemory(Internal::MemoryAgent *, QObject *,
quint64 addr, quint64 length);
virtual void changeMemory(Internal::MemoryAgent *, QObject *,
......
......@@ -42,7 +42,7 @@
#include "debuggerrunner.h"
#include "debuggerruncontrolfactory.h"
#include "debuggerstringutils.h"
#include "memoryagent.h"
#include "breakpoint.h"
#include "breakhandler.h"
#include "breakwindow.h"
......@@ -2184,7 +2184,7 @@ void DebuggerPluginPrivate::openMemoryEditor()
{
AddressDialog dialog;
if (dialog.exec() == QDialog::Accepted)
currentEngine()->openMemoryView(dialog.address());
currentEngine()->openMemoryView(dialog.address(), 0, QList<MemoryMarkup>(), QPoint());
}
void DebuggerPluginPrivate::coreShutdown()
......
......@@ -3794,10 +3794,8 @@ void GdbEngine::updateLocals(const QVariant &cookie)
updateLocalsPython(false, QByteArray());
else
updateLocalsClassic(cookie);
updateMemoryViews();
}
// Parse a local variable from GdbMi.
WatchData GdbEngine::localVariable(const GdbMi &item,
const QStringList &uninitializedVariables,
......
This diff is collapsed.
......@@ -33,8 +33,13 @@
#ifndef DEBUGGER_MEMORYAGENT_H
#define DEBUGGER_MEMORYAGENT_H
#include "debuggerconstants.h"
#include <QtCore/QObject>
#include <QtCore/QPointer>
#include <QtCore/QString>
#include <QtCore/QList>
#include <QtGui/QColor>
QT_FORWARD_DECLARE_CLASS(QPoint)
......@@ -51,7 +56,19 @@ namespace Debugger {
class DebuggerEngine;
namespace Internal {
class MemoryViewWidget;
class MemoryView;
class MemoryMarkup
{
public:
MemoryMarkup(quint64 a = 0, quint64 l = 0, QColor c = Qt::yellow,
const QString &tt = QString()) :
address(a), length(l), color(c), toolTip(tt) {}
quint64 address;
quint64 length;
QColor color;
QString toolTip;
};
class MemoryAgent : public QObject
{
......@@ -62,6 +79,8 @@ public:
~MemoryAgent();
enum { BinBlockSize = 1024 };
enum { DataRange = 1024 * 1024 };
bool hasVisibleEditor() const;
static bool isBigEndian(const ProjectExplorer::Abi &a);
......@@ -69,13 +88,16 @@ 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(quint64 startAddr);
// Called by engine to create a tooltip.
void addMemoryView(MemoryViewWidget *w);
// Called by engine to trigger update of contents.
void updateContents();
// Called by engine to pass updated contents.
void addLazyData(QObject *editorToken, quint64 addr, const QByteArray &data);
// On stack frame completed and on request.
void updateContents();
void closeEditors();
void closeViews();
private slots:
void fetchLazyData(Core::IEditor *, quint64 block);
......@@ -85,10 +107,16 @@ private slots:
void handleDataChanged(Core::IEditor *editor, quint64 address,
const QByteArray &data);
void updateMemoryView(quint64 address, quint64 length);
void openMemoryView(quint64 address, quint64 length, const QPoint &pos);
void engineStateChanged(Debugger::DebuggerState s);
private:
void connectBinEditorWidget(QWidget *w);
bool doCreateBinEditor(quint64 startAddr, unsigned flags,
const QList<MemoryMarkup> &ml, const QPoint &pos,
QString title, QWidget *parent);
QList<QPointer<Core::IEditor> > m_editors;
QList<QPointer<MemoryView> > m_views;
QPointer<DebuggerEngine> m_engine;
};
......
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "memoryview.h"
#include "registerhandler.h"
#include "memoryagent.h"
#include <bineditor/markup.h>
#include <QtGui/QVBoxLayout>
#include <QtCore/QModelIndex>
#include <QtCore/QDebug>
namespace Debugger {
namespace Internal {
/*!
\class Debugger::Internal::MemoryView
\brief Base class for memory view tool windows
Small tool-window that stays on top and displays a chunk of memory
based on the widget provided by the Bin editor plugin.
Provides static functionality for handling a Bin Editor Widget
(soft dependency) via QMetaObject invocation.
\sa Debugger::Internal::MemoryAgent, Debugger::DebuggerEngine
*/
MemoryView::MemoryView(QWidget *binEditor, QWidget *parent) :
QWidget(parent, Qt::Tool|Qt::WindowStaysOnTopHint), m_binEditor(binEditor)
{
setAttribute(Qt::WA_DeleteOnClose);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(binEditor);
setMinimumWidth(400);
}
void MemoryView::setBinEditorRange(QWidget *w, quint64 address, int range, int blockSize)
{
QMetaObject::invokeMethod(w, "setSizes",
Q_ARG(quint64, address), Q_ARG(int, range), Q_ARG(int, blockSize));
}
void MemoryView::setBinEditorReadOnly(QWidget *w, bool readOnly)
{
w->setProperty("readOnly", QVariant(readOnly));
}
void MemoryView::setBinEditorNewWindowRequestAllowed(QWidget *w, bool a)
{
w->setProperty("newWindowRequestAllowed", QVariant(a));
}
void MemoryView::setBinEditorMarkup(QWidget *w, const QList<MemoryMarkup> &ml)
{
// Convert into bin editor markup and set.
QList<BINEditor::Markup> bml;
foreach (const MemoryMarkup &m, ml)
bml.push_back(BINEditor::Markup(m.address, m.length, m.color, m.toolTip));
w->setProperty("markup", qVariantFromValue(bml));
}
void MemoryView::binEditorUpdateContents(QWidget *w)
{
QMetaObject::invokeMethod(w, "updateContents");
}
void MemoryView::binEditorSetCursorPosition(QWidget *w, int p)
{
QMetaObject::invokeMethod(w, "setCursorPosition", Q_ARG(int, p));
}
void MemoryView::binEditorAddData(QWidget *w, quint64 addr, const QByteArray &ba)
{
QMetaObject::invokeMethod(w, "addData",
Q_ARG(quint64, addr / MemoryAgent::BinBlockSize),
Q_ARG(QByteArray, ba));
}
void MemoryView::setAddress(quint64 a)
{
setBinEditorRange(m_binEditor, a, MemoryAgent::DataRange, MemoryAgent::BinBlockSize);
}
void MemoryView::updateContents()
{
binEditorUpdateContents(m_binEditor);
}
void MemoryView::setMarkup(const QList<MemoryMarkup> &m)
{
MemoryView::setBinEditorMarkup(m_binEditor, m);
}
/*!
\class Debugger::Internal::RegisterMemoryView
\brief Memory view that shows the memory around the contents of a register
(such as stack pointer, program counter),
tracking changes of the register value.
Connects to Debugger::Internal::RegisterHandler to listen for changes
of the register value.
\note Some registers might switch to 0 (for example, 'rsi','rbp'
while stepping out of a function with parameters).
This must be handled gracefully.
\sa Debugger::Internal::RegisterHandler, Debugger::Internal::RegisterWindow
\sa Debugger::Internal::MemoryAgent, Debugger::DebuggerEngine
*/
RegisterMemoryView::RegisterMemoryView(QWidget *binEditor, QWidget *parent) :
MemoryView(binEditor, parent),
m_registerIndex(0), m_registerAddress(0)
{
}
void RegisterMemoryView::slotRegisterSet(const QModelIndex &index)
{
if (m_registerIndex != index.row())
return;
const QVariant newAddressV = index.data(Qt::EditRole);
if (newAddressV.type() == QVariant::ULongLong)
setRegisterAddress(newAddressV.toULongLong());
}
QString RegisterMemoryView::title(const QString &registerName, quint64 a)
{
return tr("Memory at Register '%1' (0x%2)").arg(registerName).arg(a, 0, 16);
}
void RegisterMemoryView::setRegisterAddress(quint64 v)
{
if (v == m_registerAddress) {
updateContents();
return;
}
m_registerAddress = v;
setAddress(v);
setWindowTitle(title(m_registerName, v));
if (v)
setMarkup(registerMarkup(v, m_registerName));
}
QList<MemoryMarkup> RegisterMemoryView::registerMarkup(quint64 a, const QString &name)
{
QList<MemoryMarkup> result;
result.push_back(MemoryMarkup(a, 1, QColor(Qt::blue).lighter(),
tr("Register '%1'").arg(name)));
return result;
}
void RegisterMemoryView::init(RegisterHandler *h, int registerIndex)
{
m_registerIndex = registerIndex;
m_registerName = QString::fromAscii(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
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef DEBUGGER_INTERNAL_MEMORYVIEW_H
#define DEBUGGER_INTERNAL_MEMORYVIEW_H
#include <QtGui/QWidget>
QT_FORWARD_DECLARE_CLASS(QModelIndex)
namespace Debugger {
namespace Internal {
class MemoryMarkup;
class RegisterHandler;
class MemoryView : public QWidget
{
Q_OBJECT
public:
explicit MemoryView(QWidget *binEditor, QWidget *parent = 0);
static void setBinEditorRange(QWidget *w, quint64 address, int range, int blockSize);
static void setBinEditorReadOnly(QWidget *w, bool readOnly);
static void setBinEditorNewWindowRequestAllowed(QWidget *w, bool a);
static void setBinEditorMarkup(QWidget *w, const QList<MemoryMarkup> &ml);
static void binEditorSetCursorPosition(QWidget *w, int p);
static void binEditorUpdateContents(QWidget *w);
static void binEditorAddData(QWidget *w, quint64 addr, const QByteArray &a);
public slots:
void updateContents();
protected:
void setAddress(quint64 a);
void setMarkup(const QList<MemoryMarkup> &m);
private:
QWidget *m_binEditor;
};
class RegisterMemoryView : public MemoryView
{
Q_OBJECT
public:
explicit RegisterMemoryView(QWidget *binEditor, 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);
private:
void setRegisterAddress(quint64 v);
int m_registerIndex;
QString m_registerName;
quint64 m_registerAddress;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_INTERNAL_MEMORYVIEW_H
This diff is collapsed.
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef MEMORYTOOLTIP_H
#define MEMORYTOOLTIP_H
#include "debuggerconstants.h"
#include <projectexplorer/abi.h>
#include <QtGui/QTextEdit> // QTextEdit::ExtraSelection
#include <QtCore/QList>
QT_BEGIN_NAMESPACE
class QLabel;
class QModelIndex;
class QPlainTextEdit;
class QToolButton;
class QTextCharFormat;
QT_END_NAMESPACE
namespace Debugger {
class DebuggerEngine;
namespace Internal {
class RegisterHandler;
// Documentation inside.
class MemoryViewWidget : public QWidget
{
Q_OBJECT
public:
// Address range to be marked with special format
struct Markup
{
Markup(quint64 a = 0, quint64 s = 0,
const QTextCharFormat &fmt = QTextCharFormat(),
const QString &toolTip = QString());
bool covers(quint64 a) const { return a >= address && a < (address + size); }
quint64 address;
quint64 size;
QTextCharFormat format;
QString toolTip;
};
explicit MemoryViewWidget(QWidget *parent = 0);
quint64 address() const { return m_address; }
quint64 length() const { return m_length; }
// How read an address used for 'dereference pointer at' context menu action
void setAbi(const ProjectExplorer::Abi &a) { m_abi = a; }
ProjectExplorer::Abi abi() const { return m_abi; }
bool updateOnInferiorStop() const { return m_updateOnInferiorStop; }
void setUpdateOnInferiorStop(bool v) { m_updateOnInferiorStop = v ; }
QTextCharFormat textCharFormat() const;
QList<Markup> markup() const { return m_markup; }
void setMarkup(const QList<Markup> &m) { clearMarkup(); m_markup = m; }
static QString formatData(quint64 address, const QByteArray &d);
static const quint64 defaultLength;
virtual bool eventFilter(QObject *, QEvent *);
signals:
// Fetch memory and use setData().
void memoryRequested(quint64 address, quint64 length);
// Open a (sub) view from context menu
void openViewRequested(quint64 address, quint64 length, const QPoint &pos);
public slots:
void setData(const QByteArray &a); // Set to empty to indicate non-available data
void engineStateChanged(Debugger::DebuggerState s);
void addMarkup(quint64 begin, quint64 size, const QTextCharFormat &,
const QString &toolTip = QString());
void addMarkup(quint64 begin, quint64 size, const QColor &background,
const QString &toolTip = QString());
void clear();
void clearMarkup();
void requestMemory();
void requestMemory(quint64 address, quint64 length);
protected:
virtual void updateTitle();
void setTitle(const QString &);
private slots:
void slotNext();
void slotPrevious();
void slotContextMenuRequested(const QPoint &pos);
private:
void setBrowsingEnabled(bool);
quint64 addressAt(const QPoint &textPos) const;
bool addressToLineColumn(quint64 address, int *line = 0, int *column = 0,
quint64 *lineStart = 0) const;
bool markUpToSelections(const Markup &r,
QList<QTextEdit::ExtraSelection> *extraSelections) const;
int indexOfMarkup(quint64 address) const;
QToolButton *m_previousButton;
QToolButton *m_nextButton;
QPlainTextEdit *m_textEdit;
QLabel *m_content;
quint64 m_address;
quint64 m_length;
quint64 m_requestedAddress;
quint64 m_requestedLength;
ProjectExplorer::Abi m_abi;
QByteArray m_data;
bool m_updateOnInferiorStop;
QList<Markup> m_markup;
};
class LocalsMemoryViewWidget : public MemoryViewWidget
{
Q_OBJECT
public:
explicit LocalsMemoryViewWidget(QWidget *parent = 0);
void init(quint64 variableAddress, quint64 size, const QString &name);
private:
virtual void updateTitle();
quint64 m_variableAddress;
quint64 m_variableSize;