diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 5b9d29dedebb50694634373bc5abc76b1da68897..c2bb02489c01de0ca3f34d569c4905e0ab528798 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 128cc3dfbbe3672319adadc561c90f405b06d6ed..1f4c96696947e0dfd29ab6b0850359056184a509 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 e36d75bae3324c2bce58d82c0e55f912c4625eff..9d11caffbed71d6639dacece4c151a71edcec5f7 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 7c02512cb9571dd96258a5e223503c3c5fff17fe..baf140bcca2e0299fec37106e4fea6dd4c1a3f0e 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 e1da61a37ab109796aae844402e9a86dfb329177..c298684726013c27d00c86e4d2caf5e97da37a64 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);