From 3d1f23b78b780b5161cd8fe33e8a575f8bd0c671 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Thu, 4 Nov 2010 11:46:16 +0100 Subject: [PATCH] Debugger: Add Run to/Jump to Line to text editor context menu. Remove actions from debugger plugin as they are not directly usable. Create additional actions in context menu. Move some code around to find the current editor. --- src/plugins/debugger/debuggerengine.cpp | 131 +++++++++++++++--------- src/plugins/debugger/debuggerplugin.cpp | 52 +++------- src/plugins/debugger/stackhandler.cpp | 1 + src/plugins/debugger/watchutils.cpp | 27 +++++ src/plugins/debugger/watchutils.h | 4 + 5 files changed, 131 insertions(+), 84 deletions(-) diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 5b9d29dedeb..c2bb02489c0 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -204,7 +204,6 @@ bool CommandHandler::setData(const QModelIndex &, const QVariant &value, int rol return true; } - ////////////////////////////////////////////////////////////////////// // // DebuggerEnginePrivate @@ -282,6 +281,8 @@ public slots: private slots: void slotEditBreakpoint(); + void slotRunToLine(); + void slotJumpToLine(); public: DebuggerState state() const { return m_state; } @@ -316,16 +317,61 @@ public: bool m_isSlaveEngine; }; +// Retrieve file name and line and optionally address +// from the data set on the text editor context menu action. +static bool positionFromContextActionData(const QObject *sender, + QString *fileName, + int *lineNumber, + quint64 *address = 0) +{ + if (const QAction *action = qobject_cast<const QAction *>(sender)) { + const QVariantList data = action->data().toList(); + if (data.size() >= (address ? 3 : 2)) { + *fileName = data.front().toString(); + *lineNumber = data.at(1).toInt(); + if (address) + *address = data.at(2).toULongLong(); + return true; + } + } + return false; +} + void DebuggerEnginePrivate::breakpointSetRemoveMarginActionTriggered() { - QAction *act = qobject_cast<QAction *>(sender()); - QTC_ASSERT(act, return); - QList<QVariant> list = act->data().toList(); - QTC_ASSERT(list.size() >= 3, qDebug() << list; return); - const QString fileName = list.at(0).toString(); - const int lineNumber = list.at(1).toInt(); - const quint64 address = list.at(2).toULongLong(); - m_engine->breakHandler()->toggleBreakpoint(fileName, lineNumber, address); + QString fileName; + int lineNumber; + quint64 address; + if (positionFromContextActionData(sender(), &fileName, &lineNumber, &address)) + m_engine->breakHandler()->toggleBreakpoint(fileName, lineNumber, address); + } + + +void DebuggerEnginePrivate::slotRunToLine() +{ + // Run to line, file name and line number set as list. + QString fileName; + int lineNumber; + if (positionFromContextActionData(sender(), &fileName, &lineNumber)) { + m_engine->resetLocation(); + m_engine->executeRunToLine(fileName, lineNumber); + } +} + +void DebuggerEnginePrivate::slotJumpToLine() +{ + QString fileName; + int lineNumber; + if (positionFromContextActionData(sender(), &fileName, &lineNumber)) + m_engine->executeJumpToLine(fileName, lineNumber); +} + + void DebuggerEnginePrivate::breakpointEnableDisableMarginActionTriggered() +{ + QString fileName; + int lineNumber; + if (positionFromContextActionData(sender(), &fileName, &lineNumber)) + m_engine->breakHandler()->toggleBreakpointEnabled(fileName, lineNumber); } void DebuggerEnginePrivate::slotEditBreakpoint() @@ -338,24 +384,13 @@ void DebuggerEnginePrivate::slotEditBreakpoint() BreakWindow::editBreakpoint(breakPointData, ICore::instance()->mainWindow()); } -void DebuggerEnginePrivate::breakpointEnableDisableMarginActionTriggered() -{ - QAction *act = qobject_cast<QAction *>(sender()); - QTC_ASSERT(act, return); - QList<QVariant> list = act->data().toList(); - QTC_ASSERT(list.size() == 3, qDebug() << list; return); - const QString fileName = list.at(0).toString(); - const int lineNumber = list.at(1).toInt(); - m_engine->breakHandler()->toggleBreakpointEnabled(fileName, lineNumber); -} - void DebuggerEnginePrivate::handleContextMenuRequest(const QVariant ¶meters) { const QList<QVariant> list = parameters.toList(); QTC_ASSERT(list.size() == 3, qDebug() << list; return); TextEditor::ITextEditor *editor = (TextEditor::ITextEditor *)(list.at(0).value<quint64>()); - int lineNumber = list.at(1).toInt(); + const int lineNumber = list.at(1).toInt(); QMenu *menu = (QMenu *)(list.at(2).value<quint64>()); BreakpointData *data = 0; @@ -428,6 +463,25 @@ void DebuggerEnginePrivate::handleContextMenuRequest(const QVariant ¶meters) SLOT(breakpointSetRemoveMarginActionTriggered())); menu->addAction(act); } + // Run to, jump to line below in stopped state. + if (state() == InferiorStopOk) { + menu->addSeparator(); + const QString runText = DebuggerEngine::tr("Run to Line %1"). + arg(lineNumber); + QAction *runToLineAction = new QAction(runText, menu); + runToLineAction->setData(args); + connect(runToLineAction, SIGNAL(triggered()), this, SLOT(slotRunToLine())); + menu->addAction(runToLineAction); + if (m_engine->debuggerCapabilities() & JumpToLineCapability) { + const QString jumpText = DebuggerEngine::tr("Jump to Line %1"). + arg(lineNumber); + QAction *jumpToLineAction = new QAction(jumpText, menu); + menu->addAction(runToLineAction); + jumpToLineAction->setData(args); + connect(jumpToLineAction, SIGNAL(triggered()), this, SLOT(slotJumpToLine())); + menu->addAction(jumpToLineAction); + } + } } ////////////////////////////////////////////////////////////////////// @@ -875,32 +929,20 @@ void DebuggerEngine::executeReturnX() executeReturn(); } -static TextEditor::ITextEditor *currentTextEditor() -{ - EditorManager *editorManager = EditorManager::instance(); - if (!editorManager) - return 0; - Core::IEditor *editor = editorManager->currentEditor(); - return qobject_cast<ITextEditor*>(editor); -} - void DebuggerEngine::executeRunToLine() { - ITextEditor *textEditor = currentTextEditor(); - QTC_ASSERT(textEditor, return); - QString fileName = textEditor->file()->fileName(); - if (fileName.isEmpty()) - return; - int lineNumber = textEditor->currentLine(); - resetLocation(); - executeRunToLine(fileName, lineNumber); + QString fileName; + int lineNumber; + if (currentTextEditorPosition(&fileName, &lineNumber)) { + resetLocation(); + executeRunToLine(fileName, lineNumber); + } } void DebuggerEngine::executeRunToFunction() { ITextEditor *textEditor = currentTextEditor(); QTC_ASSERT(textEditor, return); - QString fileName = textEditor->file()->fileName(); QPlainTextEdit *ed = qobject_cast<QPlainTextEdit*>(textEditor->widget()); if (!ed) return; @@ -931,13 +973,10 @@ void DebuggerEngine::executeRunToFunction() void DebuggerEngine::executeJumpToLine() { - ITextEditor *textEditor = currentTextEditor(); - QTC_ASSERT(textEditor, return); - QString fileName = textEditor->file()->fileName(); - int lineNumber = textEditor->currentLine(); - if (fileName.isEmpty()) - return; - executeJumpToLine(fileName, lineNumber); + QString fileName; + int lineNumber; + if (currentTextEditorPosition(&fileName, &lineNumber)) + executeJumpToLine(fileName, lineNumber); } void DebuggerEngine::addToWatchWindow() diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 128cc3dfbbe..1f4c9669694 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -818,11 +818,9 @@ struct DebuggerActions QAction *resetAction; // FIXME: Should not be needed in a stable release QAction *stepAction; QAction *stepOutAction; - QAction *runToLineAction1; // in the Debug menu - QAction *runToLineAction2; // in the text editor context menu + QAction *runToLineAction; // Debug menu QAction *runToFunctionAction; - QAction *jumpToLineAction1; // in the Debug menu - QAction *jumpToLineAction2; // in the text editor context menu + QAction *jumpToLineAction; // in the Debug menu QAction *returnFromFunctionAction; QAction *nextAction; QAction *snapshotAction; @@ -1196,10 +1194,8 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, QString *er m_actions.stepOutAction->setIcon( QIcon(__(":/debugger/images/debugger_stepout_small.png"))); - m_actions.runToLineAction1 = new QAction(tr("Run to Line"), this); - m_actions.runToLineAction1->setProperty(Role, RequestExecRunToLineRole); - m_actions.runToLineAction2 = new QAction(tr("Run to Line"), this); - m_actions.runToLineAction2->setProperty(Role, RequestExecRunToLineRole); + m_actions.runToLineAction = new QAction(tr("Run to Line"), this); + m_actions.runToLineAction->setProperty(Role, RequestExecRunToLineRole); m_actions.runToFunctionAction = new QAction(tr("Run to Outermost Function"), this); @@ -1209,10 +1205,8 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, QString *er new QAction(tr("Immediately Return From Inner Function"), this); m_actions.returnFromFunctionAction->setProperty(Role, RequestExecReturnFromFunctionRole); - m_actions.jumpToLineAction1 = new QAction(tr("Jump to Line"), this); - m_actions.jumpToLineAction1->setProperty(Role, RequestExecJumpToLineRole); - m_actions.jumpToLineAction2 = new QAction(tr("Jump to Line"), this); - m_actions.jumpToLineAction2->setProperty(Role, RequestExecJumpToLineRole); + m_actions.jumpToLineAction = new QAction(tr("Jump to Line"), this); + m_actions.jumpToLineAction->setProperty(Role, RequestExecJumpToLineRole); m_actions.breakAction = new QAction(tr("Toggle Breakpoint"), this); @@ -1249,11 +1243,9 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, QString *er connect(m_actions.nextAction, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.stepAction, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.stepOutAction, SIGNAL(triggered()), SLOT(onAction())); - connect(m_actions.runToLineAction1, SIGNAL(triggered()), SLOT(onAction())); - connect(m_actions.runToLineAction2, SIGNAL(triggered()), SLOT(onAction())); + connect(m_actions.runToLineAction, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.runToFunctionAction, SIGNAL(triggered()), SLOT(onAction())); - connect(m_actions.jumpToLineAction1, SIGNAL(triggered()), SLOT(onAction())); - connect(m_actions.jumpToLineAction2, SIGNAL(triggered()), SLOT(onAction())); + connect(m_actions.jumpToLineAction, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.returnFromFunctionAction, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.watchAction1, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.watchAction2, SIGNAL(triggered()), SLOT(onAction())); @@ -1471,7 +1463,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, QString *er m_uiSwitcher->addMenuAction(cmd, CppLanguage); - cmd = am->registerAction(m_actions.runToLineAction1, + cmd = am->registerAction(m_actions.runToLineAction, Constants::RUN_TO_LINE1, cppDebuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY)); cmd->setAttribute(Command::CA_Hide); @@ -1485,7 +1477,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, QString *er m_uiSwitcher->addMenuAction(cmd, CppLanguage); - cmd = am->registerAction(m_actions.jumpToLineAction1, + cmd = am->registerAction(m_actions.jumpToLineAction, Constants::JUMP_TO_LINE1, cppDebuggercontext); cmd->setAttribute(Command::CA_Hide); m_uiSwitcher->addMenuAction(cmd, CppLanguage); @@ -1564,18 +1556,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, QString *er editorContextMenu->addAction(cmd); cmd->setAttribute(Command::CA_Hide); - cmd = am->registerAction(m_actions.runToLineAction2, - Constants::RUN_TO_LINE2, cppDebuggercontext); - cmd->action()->setEnabled(true); - editorContextMenu->addAction(cmd); - cmd->setAttribute(Command::CA_Hide); - - cmd = am->registerAction(m_actions.jumpToLineAction2, - Constants::JUMP_TO_LINE2, cppDebuggercontext); - cmd->action()->setEnabled(true); - editorContextMenu->addAction(cmd); - cmd->setAttribute(Command::CA_Hide); - m_plugin->addAutoReleasedObject(new CommonOptionsPage); QList<Core::IOptionsPage *> engineOptionPages; if (cmdLineEnabledEngines & GdbEngineType) @@ -2259,12 +2239,10 @@ void DebuggerPluginPrivate::setInitialState() m_actions.stepAction->setEnabled(false); m_actions.stepOutAction->setEnabled(false); - m_actions.runToLineAction1->setEnabled(false); - m_actions.runToLineAction2->setEnabled(false); + m_actions.runToLineAction->setEnabled(false); m_actions.runToFunctionAction->setEnabled(false); m_actions.returnFromFunctionAction->setEnabled(false); - m_actions.jumpToLineAction1->setEnabled(false); - m_actions.jumpToLineAction2->setEnabled(false); + m_actions.jumpToLineAction->setEnabled(false); m_actions.nextAction->setEnabled(false); theDebuggerAction(AutoDerefPointers)->setEnabled(true); @@ -2391,15 +2369,13 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_actions.stepAction->setEnabled(stopped); m_actions.stepOutAction->setEnabled(stopped); - m_actions.runToLineAction1->setEnabled(stopped); - m_actions.runToLineAction2->setEnabled(stopped); + m_actions.runToLineAction->setEnabled(stopped); m_actions.runToFunctionAction->setEnabled(stopped); m_actions.returnFromFunctionAction-> setEnabled(stopped && (caps & ReturnFromFunctionCapability)); const bool canJump = stopped && (caps & JumpToLineCapability); - m_actions.jumpToLineAction1->setEnabled(canJump); - m_actions.jumpToLineAction2->setEnabled(canJump); + m_actions.jumpToLineAction->setEnabled(canJump); m_actions.nextAction->setEnabled(stopped); diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index e36d75bae33..9d11caffbed 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -238,5 +238,6 @@ bool StackHandler::isDebuggingDebuggingHelpers() const return false; } + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 7c02512cb95..baf140bcca2 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -40,6 +40,7 @@ #include <texteditor/basetextmark.h> #include <texteditor/itexteditor.h> #include <texteditor/texteditorconstants.h> +#include <coreplugin/editormanager/editormanager.h> #include <cpptools/cppmodelmanagerinterface.h> #include <cpptools/cpptoolsconstants.h> @@ -664,6 +665,14 @@ QString decodeData(const QByteArray &ba, int encoding) return QCoreApplication::translate("Debugger", "<Encoding error>"); } +TextEditor::ITextEditor *currentTextEditor() +{ + if (const Core::EditorManager *editorManager = Core::EditorManager::instance()) + if (Core::IEditor *editor = editorManager->currentEditor()) + return qobject_cast<TextEditor::ITextEditor*>(editor); + return 0; +} + // Editor tooltip support bool isCppEditor(Core::IEditor *editor) { @@ -678,6 +687,24 @@ bool isCppEditor(Core::IEditor *editor) || mimeType == OBJECTIVE_CPP_SOURCE_MIMETYPE; } +bool currentTextEditorPosition(QString *fileNameIn /* = 0 */, + int *lineNumberIn /* = 0 */) +{ + QString fileName; + int lineNumber; + if (TextEditor::ITextEditor *textEditor = currentTextEditor()) { + if (const Core::IFile *file = textEditor->file()) { + fileName = file->fileName(); + lineNumber = textEditor->currentLine(); + } + } + if (fileNameIn) + *fileNameIn = fileName; + if (lineNumberIn) + *lineNumberIn = lineNumber; + return !fileName.isEmpty(); +} + // Return the Cpp expression, and, if desired, the function QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, int *line, int *column, QString *function /* = 0 */) diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h index e1da61a37ab..c2986847260 100644 --- a/src/plugins/debugger/watchutils.h +++ b/src/plugins/debugger/watchutils.h @@ -91,6 +91,10 @@ QString quoteUnprintableLatin1(const QByteArray &ba); bool isCppEditor(Core::IEditor *editor); QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, int *line, int *column, QString *function = 0); +// Editor helpers +TextEditor::ITextEditor *currentTextEditor(); +bool currentTextEditorPosition(QString *fileNameIn = 0, + int *lineNumberIn = 0); // Decode string data as returned by the dumper helpers. QString decodeData(const QByteArray &baIn, int encoding); -- GitLab