diff options
author | hjk <qtc-committer@nokia.com> | 2009-08-12 10:51:25 +0200 |
---|---|---|
committer | hjk <qtc-committer@nokia.com> | 2009-08-12 14:49:15 +0200 |
commit | 89ffffc183f2fd2fe2070bd25620a9758371ed34 (patch) | |
tree | 4ea34330bf28020d40b6e4aeb99fb5f4907f7ae8 | |
parent | 0c6b754a06e24711ff7b9a5d5d076e010f4a1661 (diff) | |
download | qt-creator-89ffffc183f2fd2fe2070bd25620a9758371ed34.tar.gz |
debugger: use the bineditor to show memory dumps
-rw-r--r-- | dist/changes-1.3.0 | 1 | ||||
-rw-r--r-- | src/plugins/bineditor/bineditor.cpp | 9 | ||||
-rw-r--r-- | src/plugins/bineditor/bineditor.h | 17 | ||||
-rw-r--r-- | src/plugins/bineditor/bineditorplugin.h | 2 | ||||
-rw-r--r-- | src/plugins/debugger/debugger.pro | 8 | ||||
-rw-r--r-- | src/plugins/debugger/debuggeractions.h | 13 | ||||
-rw-r--r-- | src/plugins/debugger/debuggeragents.cpp | 73 | ||||
-rw-r--r-- | src/plugins/debugger/debuggeragents.h | 80 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerdialogs.h | 1 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermanager.cpp | 7 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermanager.h | 11 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerplugin.cpp | 4 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.cpp | 35 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.h | 3 | ||||
-rw-r--r-- | src/plugins/debugger/idebuggerengine.h | 3 | ||||
-rw-r--r-- | src/plugins/debugger/watchhandler.cpp | 10 | ||||
-rw-r--r-- | src/plugins/debugger/watchhandler.h | 3 | ||||
-rw-r--r-- | src/plugins/debugger/watchwindow.cpp | 84 | ||||
-rw-r--r-- | src/plugins/debugger/watchwindow.h | 5 |
19 files changed, 312 insertions, 57 deletions
diff --git a/dist/changes-1.3.0 b/dist/changes-1.3.0 index 4206ab0f40..dbdca175f2 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 69da9ef132..d84bc3f3d2 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 3349ad3e04..86b0e9d1ca 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 1935f65834..09424606ae 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 25b7c355f0..f6b56bb66d 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 5f953b6d10..a0ccf46c00 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 0000000000..e221ee1527 --- /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 0000000000..f4a5bf1c54 --- /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 74dc720e81..ee42ca6cea 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 23a1ae83cd..02907cc5fc 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 406a840397..fe9e4bce17 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 3539ef2008..6b4610e49f 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 7881c02659..006b1420db 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 c8ff6a6698..7fb115ce96 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 dbbdb14314..0ca38a14b0 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 fad2dfa77f..f902ed3d1d 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 0778ec2545..f1da9d96f6 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 571e8ac4b9..d024582739 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 e937139276..105af278b3 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; }; |