aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-1.3.01
-rw-r--r--src/plugins/bineditor/bineditor.cpp9
-rw-r--r--src/plugins/bineditor/bineditor.h17
-rw-r--r--src/plugins/bineditor/bineditorplugin.h2
-rw-r--r--src/plugins/debugger/debugger.pro8
-rw-r--r--src/plugins/debugger/debuggeractions.h13
-rw-r--r--src/plugins/debugger/debuggeragents.cpp73
-rw-r--r--src/plugins/debugger/debuggeragents.h80
-rw-r--r--src/plugins/debugger/debuggerdialogs.h1
-rw-r--r--src/plugins/debugger/debuggermanager.cpp7
-rw-r--r--src/plugins/debugger/debuggermanager.h11
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp4
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp35
-rw-r--r--src/plugins/debugger/gdb/gdbengine.h3
-rw-r--r--src/plugins/debugger/idebuggerengine.h3
-rw-r--r--src/plugins/debugger/watchhandler.cpp10
-rw-r--r--src/plugins/debugger/watchhandler.h3
-rw-r--r--src/plugins/debugger/watchwindow.cpp84
-rw-r--r--src/plugins/debugger/watchwindow.h5
19 files changed, 312 insertions, 57 deletions
diff --git a/dist/changes-1.3.0 b/dist/changes-1.3.0
index 4206ab0f400..dbdca175f2a 100644
--- a/dist/changes-1.3.0
+++ b/dist/changes-1.3.0
@@ -39,6 +39,7 @@ Debugging
* CDB: Fixed thread handling
* CDB: Added internal dumpers for string types for debuggee crashes
* Improved QObject dumping, print out QRect/QSize, enumerations and flags
+ * Use the BinEditor plugin to show raw memory
Designer
* Added support for rearranging and floating form editor tools
diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditor.cpp
index 69da9ef1329..d84bc3f3d29 100644
--- a/src/plugins/bineditor/bineditor.cpp
+++ b/src/plugins/bineditor/bineditor.cpp
@@ -32,14 +32,13 @@
#include <texteditor/fontsettings.h>
#include <texteditor/texteditorconstants.h>
-#include <QtGui/QScrollBar>
+#include <QtCore/QByteArrayMatcher>
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
#include <QtGui/QFontMetrics>
#include <QtGui/QPainter>
#include <QtGui/QScrollBar>
#include <QtGui/QWheelEvent>
-#include <QtGui/QApplication>
-#include <QtGui/QClipboard>
-#include <QtCore/QByteArrayMatcher>
using namespace BINEditor;
@@ -794,7 +793,7 @@ void BinEditor::paintEvent(QPaintEvent *e)
}
}
- if (cursor >= 0) {
+ if (cursor >= 0 && !printable.isEmpty()) {
QRect cursorRect(text_x + painter.fontMetrics().width(printable.left(cursor)),
y-m_ascent,
painter.fontMetrics().width(printable.at(cursor)),
diff --git a/src/plugins/bineditor/bineditor.h b/src/plugins/bineditor/bineditor.h
index 3349ad3e04c..86b0e9d1ca9 100644
--- a/src/plugins/bineditor/bineditor.h
+++ b/src/plugins/bineditor/bineditor.h
@@ -30,12 +30,13 @@
#ifndef BINEDITOR_H
#define BINEDITOR_H
-#include <QtGui/qabstractscrollarea.h>
-#include <QtCore/qbasictimer.h>
-#include <QtCore/qstack.h>
-#include <QtCore/qset.h>
-#include <QtGui/qtextdocument.h>
-#include <QtGui/qtextformat.h>
+#include <QtCore/QBasicTimer>
+#include <QtCore/QSet>
+#include <QtCore/QStack>
+
+#include <QtGui/QAbstractScrollArea>
+#include <QtGui/QTextDocument>
+#include <QtGui/QTextFormat>
namespace Core {
class IEditor;
@@ -63,9 +64,9 @@ public:
inline int dataSize() const { return m_size; }
inline bool inLazyMode() const { return m_inLazyMode; }
- void setLazyData(int cursorPosition, int size, int blockSize = 4096);
+ Q_INVOKABLE void setLazyData(int cursorPosition, int size, int blockSize = 4096);
inline int lazyDataBlockSize() const { return m_blockSize; }
- void addLazyData(int block, const QByteArray &data);
+ Q_INVOKABLE void addLazyData(int block, const QByteArray &data);
bool applyModifications(QByteArray &data) const;
void zoomIn(int range = 1);
diff --git a/src/plugins/bineditor/bineditorplugin.h b/src/plugins/bineditor/bineditorplugin.h
index 1935f65834a..09424606aed 100644
--- a/src/plugins/bineditor/bineditorplugin.h
+++ b/src/plugins/bineditor/bineditorplugin.h
@@ -33,7 +33,7 @@
#include <extensionsystem/iplugin.h>
#include <coreplugin/editormanager/ieditorfactory.h>
-#include <QtCore/qplugin.h>
+#include <QtCore/QtPlugin>
#include <QtCore/QPointer>
#include <QtCore/QStringList>
#include <QtGui/QAction>
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index 25b7c355f07..f6b56bb66dd 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -6,11 +6,11 @@ TARGET = Debugger
# CONFIG += single
include(../../qtcreatorplugin.pri)
-include(../../plugins/projectexplorer/projectexplorer.pri)
-include(../../plugins/find/find.pri)
include(../../plugins/coreplugin/coreplugin.pri)
-include(../../plugins/texteditor/texteditor.pri)
include(../../plugins/cpptools/cpptools.pri)
+include(../../plugins/find/find.pri)
+include(../../plugins/projectexplorer/projectexplorer.pri)
+include(../../plugins/texteditor/texteditor.pri)
include(../../libs/cplusplus/cplusplus.pri)
include(../../libs/utils/utils.pri)
INCLUDEPATH += $$PWD/../../libs/utils
@@ -20,6 +20,7 @@ QT += gui network script
HEADERS += \
breakhandler.h \
breakwindow.h \
+ debuggeragents.h \
debuggeractions.h \
debuggerconstants.h \
debuggerdialogs.h \
@@ -50,6 +51,7 @@ SOURCES += \
breakhandler.cpp \
breakwindow.cpp \
breakwindow.h \
+ debuggeragents.cpp \
debuggeractions.cpp \
debuggerdialogs.cpp \
debuggermanager.cpp \
diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h
index 5f953b6d10e..a0ccf46c005 100644
--- a/src/plugins/debugger/debuggeractions.h
+++ b/src/plugins/debugger/debuggeractions.h
@@ -37,6 +37,7 @@
QT_BEGIN_NAMESPACE
class QActionGroup;
QT_END_NAMESPACE
+
namespace Debugger {
namespace Internal {
@@ -80,6 +81,12 @@ enum DebuggerActionCode
LockView,
LogTimeStamps,
+ RecheckDebuggingHelpers,
+ UseDebuggingHelpers,
+ UseCustomDebuggingHelperLocation,
+ CustomDebuggingHelperLocation,
+ DebugDebuggingHelpers,
+
// Gdb
GdbLocation,
GdbEnvironment,
@@ -99,12 +106,6 @@ enum DebuggerActionCode
AssignValue,
AssignType,
- RecheckDebuggingHelpers,
- UseDebuggingHelpers,
- UseCustomDebuggingHelperLocation,
- CustomDebuggingHelperLocation,
- DebugDebuggingHelpers,
-
// Source List
ListSourceFiles,
diff --git a/src/plugins/debugger/debuggeragents.cpp b/src/plugins/debugger/debuggeragents.cpp
new file mode 100644
index 00000000000..e221ee15277
--- /dev/null
+++ b/src/plugins/debugger/debuggeragents.cpp
@@ -0,0 +1,73 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+**
+**************************************************************************/
+
+#include "debuggeragents.h"
+#include "idebuggerengine.h"
+
+#include <coreplugin/editormanager/editormanager.h>
+
+namespace Debugger {
+namespace Internal {
+
+MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, quint64 addr)
+ : QObject(manager), m_engine(manager->currentEngine())
+{
+ Core::EditorManager *editorManager = Core::EditorManager::instance();
+ QString titlePattern = "Memory $";
+ m_editor = editorManager->openEditorWithContents(
+ Core::Constants::K_DEFAULT_BINARY_EDITOR,
+ &titlePattern);
+ connect(m_editor->widget(), SIGNAL(lazyDataRequested(int,bool)),
+ this, SLOT(fetchLazyData(int,bool)));
+ editorManager->activateEditor(m_editor);
+ QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
+ Q_ARG(int, addr), Q_ARG(int, INT_MAX), Q_ARG(int, BinBlockSize));
+}
+
+MemoryViewAgent::~MemoryViewAgent()
+{
+ m_editor->deleteLater();
+}
+
+void MemoryViewAgent::fetchLazyData(int block, bool sync)
+{
+ Q_UNUSED(sync); // FIXME: needed support for incremental searching
+ m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
+}
+
+void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
+{
+ QMetaObject::invokeMethod(m_editor->widget(), "addLazyData",
+ Q_ARG(int, addr / BinBlockSize), Q_ARG(QByteArray, ba));
+}
+
+
+} // namespace Internal
+} // namespace Debugger
+
diff --git a/src/plugins/debugger/debuggeragents.h b/src/plugins/debugger/debuggeragents.h
new file mode 100644
index 00000000000..f4a5bf1c54d
--- /dev/null
+++ b/src/plugins/debugger/debuggeragents.h
@@ -0,0 +1,80 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_AGENTS_H
+#define DEBUGGER_AGENTS_H
+
+#include "debuggermanager.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/editormanager/ieditor.h>
+
+#include <utils/qtcassert.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QDebug>
+#include <QtCore/QPointer>
+#include <QtGui/QAction>
+
+namespace Debugger {
+namespace Internal {
+
+class DebuggerManager;
+
+// Object form this class are created in response to user actions in
+// the Gui for showing raw memory from the inferior. After creation
+// it handles communication between the engine and the bineditor.
+
+class MemoryViewAgent : public QObject
+{
+ Q_OBJECT
+
+public:
+ // Called from Gui
+ MemoryViewAgent(DebuggerManager *manager, quint64 startaddr);
+ ~MemoryViewAgent();
+
+ enum { BinBlockSize = 1024 };
+
+public slots:
+ // Called from Engine
+ void addLazyData(quint64 addr, const QByteArray &data);
+ // Called from Editor
+ void fetchLazyData(int block, bool sync);
+
+public:
+ QPointer<IDebuggerEngine> m_engine;
+ QPointer<Core::IEditor> m_editor;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // DEBUGGER_WATCHWINDOW_H
diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h
index 74dc720e817..ee42ca6cea3 100644
--- a/src/plugins/debugger/debuggerdialogs.h
+++ b/src/plugins/debugger/debuggerdialogs.h
@@ -171,6 +171,7 @@ private:
Ui::StartRemoteDialog *m_ui;
};
+
} // namespace Debugger
} // namespace Internal
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 23a1ae83cda..02907cc5fc2 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -226,9 +226,9 @@ void DebuggerManager::init()
m_stackWindow = new StackWindow;
m_sourceFilesWindow = new SourceFilesWindow;
m_threadsWindow = new ThreadsWindow;
- m_localsWindow = new WatchWindow(WatchWindow::LocalsType);
- m_watchersWindow = new WatchWindow(WatchWindow::WatchersType);
- //m_tooltipWindow = new WatchWindow(WatchWindow::TooltipType);
+ m_localsWindow = new WatchWindow(WatchWindow::LocalsType, this);
+ m_watchersWindow = new WatchWindow(WatchWindow::WatchersType, this);
+ //m_tooltipWindow = new WatchWindow(WatchWindow::TooltipType, this);
m_statusTimer = new QTimer(this);
m_mainWindow = new Core::Utils::FancyMainWindow;
@@ -1497,7 +1497,6 @@ bool DebuggerManager::isReverseDebugging() const
return m_reverseDirectionAction->isChecked();
}
-
//////////////////////////////////////////////////////////////////////
//
// Testing
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 406a8403971..fe9e4bce17f 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -251,8 +251,7 @@ private:
// DebuggerManager
//
-class DebuggerManager : public QObject,
- public IDebuggerManagerAccessForEngines
+class DebuggerManager : public QObject, public IDebuggerManagerAccessForEngines
{
Q_OBJECT
@@ -265,9 +264,11 @@ public:
IDebuggerManagerAccessForEngines *engineInterface();
Core::Utils::FancyMainWindow *mainWindow() const { return m_mainWindow; }
QLabel *statusLabel() const { return m_statusLabel; }
+ IDebuggerEngine *currentEngine() const { return m_engine; }
public slots:
- void startNewDebugger(DebuggerRunControl *runControl, const QSharedPointer<DebuggerStartParameters> &startParameters);
+ void startNewDebugger(DebuggerRunControl *runControl,
+ const QSharedPointer<DebuggerStartParameters> &startParameters);
void exitDebugger();
virtual QSharedPointer<DebuggerStartParameters> startParameters() const;
@@ -297,6 +298,7 @@ public slots:
void setBreakpoint(const QString &fileName, int lineNumber);
void activateFrame(int index);
void selectThread(int index);
+ void fetchMemory(quint64 addr, quint64 length);
void stepExec();
void stepOutExec();
@@ -406,15 +408,12 @@ signals:
void gotoLocationRequested(const QString &file, int line, bool setLocationMarker);
void resetLocationRequested();
void currentTextEditorRequested(QString *fileName, int *lineNumber, QObject **ob);
- void currentMainWindowRequested(QWidget **);
void sessionValueRequested(const QString &name, QVariant *value);
void setSessionValueRequested(const QString &name, const QVariant &value);
void configValueRequested(const QString &name, QVariant *value);
void setConfigValueRequested(const QString &name, const QVariant &value);
void applicationOutputAvailable(const QString &output);
-public:
-
private:
void init();
void runTest(const QString &fileName);
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 3539ef2008e..6b4610e49f8 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -88,6 +88,8 @@
#include <QtGui/QTextCursor>
#include <QtGui/QMessageBox>
+#include <climits>
+
using namespace Core;
using namespace Debugger::Constants;
using namespace Debugger::Internal;
@@ -407,6 +409,7 @@ void DebuggingHelperOptionPage::updateState()
} // namespace Internal
} // namespace Debugger
+
///////////////////////////////////////////////////////////////////////
//
// DebuggerPlugin
@@ -1114,6 +1117,7 @@ void DebuggerPlugin::gotoLocation(const QString &fileName, int lineNumber,
}
}
+
void DebuggerPlugin::changeStatus(int status)
{
bool startIsContinue = (status == DebuggerInferiorStopped);
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 7881c026595..006b1420dbd 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -34,6 +34,7 @@
#include "watchutils.h"
#include "debuggeractions.h"
+#include "debuggeragents.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include "debuggertooltip.h"
@@ -3987,6 +3988,40 @@ void GdbEngine::handleWatchPoint(const GdbResultRecord &record, const QVariant &
}
}
+void GdbEngine::handleFetchMemory(const GdbResultRecord &record,
+ const QVariant &cookie)
+{
+ // ^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"]}]
+ bool ok = true;
+ MemoryViewAgent *agent = (MemoryViewAgent *)cookie.toULongLong(&ok);
+ QTC_ASSERT(ok, return);
+ QTC_ASSERT(agent, return);
+ QByteArray ba;
+ GdbMi memory = record.data.findChild("memory");
+ QTC_ASSERT(memory.children().size() == 1, return);
+ GdbMi memory0 = memory.children().at(0); // we asked for only one 'row'
+ quint64 addr = memory0.findChild("addr").data().toULongLong(&ok, 0);
+ QTC_ASSERT(ok, return);
+ GdbMi data = memory0.findChild("data");
+ foreach (const GdbMi &child, data.children()) {
+ unsigned char c = child.data().toUInt(&ok, 0);
+ QTC_ASSERT(ok, return);
+ ba.append(c);
+ }
+ //qDebug() << "GDB READ MEMORY" << agent << addr << data.data() << ba.size();
+ agent->addLazyData(addr, ba);
+}
+
+void GdbEngine::fetchMemory(MemoryViewAgent *agent, quint64 addr, quint64 length)
+{
+ //qDebug() << "GDB MEMORY FETCH" << addr << length;
+ postCommand(_("-data-read-memory %1 x 1 1 %2").arg(addr).arg(length),
+ NeedsStop, CB(handleFetchMemory), QVariant(quint64(agent)));
+}
+
IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts)
{
opts->push_back(new GdbOptionsPage);
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index c8ff6a6698d..7fb115ce967 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -122,6 +122,9 @@ private:
void loadAllSymbols();
virtual QList<Symbol> moduleSymbols(const QString &moduleName);
+ void fetchMemory(MemoryViewAgent *agent, quint64 addr, quint64 length);
+ void handleFetchMemory(const GdbResultRecord &record, const QVariant &cookie);
+
Q_SLOT void setDebugDebuggingHelpers(const QVariant &on);
Q_SLOT void setUseDebuggingHelpers(const QVariant &on);
diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h
index dbbdb143143..0ca38a14b0c 100644
--- a/src/plugins/debugger/idebuggerengine.h
+++ b/src/plugins/debugger/idebuggerengine.h
@@ -49,6 +49,7 @@ namespace Internal {
class Symbol;
class WatchData;
struct DebuggerStartParameters;
+class MemoryViewAgent;
class IDebuggerEngine : public QObject
{
@@ -95,6 +96,8 @@ public:
virtual void reloadFullStack() = 0;
virtual void watchPoint(const QPoint &) {}
+ virtual void fetchMemory(MemoryViewAgent *, quint64 addr, quint64 length)
+ { Q_UNUSED(addr); Q_UNUSED(length); }
};
} // namespace Internal
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index fad2dfa77f4..f902ed3d1d1 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -690,6 +690,16 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
return m_handler->m_typeFormats[data.type];
return format;
}
+
+ case AddressRole: {
+ if (!data.addr.isEmpty())
+ return data.addr;
+ bool ok;
+ (void) data.value.toULongLong(&ok, 0);
+ if (ok)
+ return data.value;
+ return QVariant();
+ }
default:
break;
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 0778ec25451..f1da9d96f6d 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -146,7 +146,8 @@ enum WatchRoles
ActiveDataRole, // used for tooltip
TypeFormatListRole,
TypeFormatRole, // used to communicate alternative formats to the view
- IndividualFormatRole
+ IndividualFormatRole,
+ AddressRole, // some memory address related to the object
};
enum IntegerFormat
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index 571e8ac4b9b..d024582739a 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -31,6 +31,7 @@
#include "watchhandler.h"
#include "debuggeractions.h"
+#include "debuggeragents.h"
#include <utils/qtcassert.h>
@@ -39,8 +40,11 @@
#include <QtGui/QAction>
#include <QtGui/QContextMenuEvent>
+#include <QtGui/QDialog>
+#include <QtGui/QHBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QItemDelegate>
+#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QMenu>
#include <QtGui/QResizeEvent>
@@ -111,8 +115,9 @@ public:
//
/////////////////////////////////////////////////////////////////////
-WatchWindow::WatchWindow(Type type, QWidget *parent)
- : QTreeView(parent), m_alwaysResizeColumnsToContents(true), m_type(type)
+WatchWindow::WatchWindow(Type type, DebuggerManager *manager, QWidget *parent)
+ : QTreeView(parent), m_alwaysResizeColumnsToContents(true), m_type(type),
+ m_manager(manager)
{
m_grabbing = false;
@@ -237,28 +242,44 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
}
QMenu menu;
- QAction *act1 = new QAction(tr("Adjust column widths to contents"), &menu);
- QAction *act2 = new QAction(tr("Always adjust column widths to contents"), &menu);
-
- act2->setCheckable(true);
- act2->setChecked(m_alwaysResizeColumnsToContents);
-
- //QAction *act4 = theDebuggerAction(WatchExpressionInWindow);
- //menu.addAction(act4);
-
- QAction *act3 = new QAction(tr("Insert new watch item"), &menu);
- QAction *act4 = new QAction(tr("Select widget to watch"), &menu);
-
- menu.addAction(act1);
- menu.addAction(act2);
+ QAction *actAdjustColumnWidths =
+ new QAction(tr("Adjust column widths to contents"), &menu);
+
+ QAction *actAlwaysAdjustColumnWidth =
+ new QAction(tr("Always adjust column widths to contents"), &menu);
+ actAlwaysAdjustColumnWidth->setCheckable(true);
+ actAlwaysAdjustColumnWidth->setChecked(m_alwaysResizeColumnsToContents);
+
+ //QAction *actWatchExpressionInWindow
+ // = theDebuggerAction(WatchExpressionInWindow);
+ //menu.addAction(actWatchExpressionInWindow);
+
+ QAction *actInsertNewWatchItem =
+ new QAction(tr("Insert new watch item"), &menu);
+
+ QAction *actSelectWidgetToWatch =
+ new QAction(tr("Select widget to watch"), &menu);
+
+ QString address = model()->data(mi0, AddressRole).toString();
+ QAction *actWatchKnownMemory = 0;
+ QAction *actWatchUnknownMemory = 0;
+ if (address.isEmpty())
+ actWatchUnknownMemory = new QAction(tr("Open memory editor"), &menu);
+ else
+ actWatchKnownMemory =
+ new QAction(tr("Open memory editor at %1").arg(address), &menu);
+
+ menu.addAction(actAdjustColumnWidths);
+ menu.addAction(actAlwaysAdjustColumnWidth);
menu.addSeparator();
int atype = (m_type == LocalsType) ? WatchExpression : RemoveWatchExpression;
menu.addAction(theDebuggerAction(atype)->updatedAction(exp));
- menu.addAction(act3);
- menu.addAction(act4);
+ menu.addAction(actInsertNewWatchItem);
+ menu.addAction(actSelectWidgetToWatch);
menu.addMenu(&typeFormatMenu);
menu.addMenu(&individualFormatMenu);
+ menu.addAction(actWatchKnownMemory ? actWatchKnownMemory : actWatchUnknownMemory);
menu.addSeparator();
menu.addAction(theDebuggerAction(RecheckDebuggingHelpers));
@@ -268,14 +289,33 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *act = menu.exec(ev->globalPos());
- if (act == act1) {
+ if (act == actAdjustColumnWidths) {
resizeColumnsToContents();
- } else if (act == act2) {
+ } else if (act == actAlwaysAdjustColumnWidth) {
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
- } else if (act == act3) {
+ } else if (act == actInsertNewWatchItem) {
theDebuggerAction(WatchExpression)
->trigger(WatchHandler::watcherEditPlaceHolder());
- } else if (act == act4) {
+ } else if (act == actWatchKnownMemory) {
+ bool ok = true;
+ uint addr = address.toUInt(&ok, 0);
+ (void) new MemoryViewAgent(m_manager, addr);
+ } else if (act == actWatchUnknownMemory) {
+ QLabel *label = new QLabel("Enter an address: ");
+ QLineEdit *lineEdit = new QLineEdit;
+ QHBoxLayout *layout = new QHBoxLayout;
+ layout->addWidget(label);
+ layout->addWidget(lineEdit);
+ QDialog dialog(this);
+ dialog.setWindowTitle("Select start address");
+ dialog.setLayout(layout);
+ connect(lineEdit, SIGNAL(returnPressed()), &dialog, SLOT(accept()));
+ if (dialog.exec() == QDialog::Accepted) {
+ bool ok = true;
+ uint addr = lineEdit->text().toUInt(&ok, 0);
+ (void) new MemoryViewAgent(m_manager, addr);
+ }
+ } else if (act == actSelectWidgetToWatch) {
grabMouse(Qt::CrossCursor);
m_grabbing = true;
} else {
diff --git a/src/plugins/debugger/watchwindow.h b/src/plugins/debugger/watchwindow.h
index e937139276d..105af278b30 100644
--- a/src/plugins/debugger/watchwindow.h
+++ b/src/plugins/debugger/watchwindow.h
@@ -41,6 +41,8 @@ namespace Internal {
//
/////////////////////////////////////////////////////////////////////
+class DebuggerManager;
+
class WatchWindow : public QTreeView
{
Q_OBJECT
@@ -48,7 +50,7 @@ class WatchWindow : public QTreeView
public:
enum Type { LocalsType, TooltipType, WatchersType };
- WatchWindow(Type type, QWidget *parent = 0);
+ WatchWindow(Type type, DebuggerManager *manager, QWidget *parent = 0);
void setType(Type type) { m_type = type; }
Type type() const { return m_type; }
@@ -75,6 +77,7 @@ private:
bool m_alwaysResizeColumnsToContents;
Type m_type;
+ DebuggerManager *m_manager;
bool m_grabbing;
};