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.
This commit is contained in:
Friedemann Kleint
2010-11-04 11:46:16 +01:00
parent 4ad493c958
commit 3d1f23b78b
5 changed files with 131 additions and 84 deletions

View File

@@ -204,7 +204,6 @@ bool CommandHandler::setData(const QModelIndex &, const QVariant &value, int rol
return true; return true;
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// //
// DebuggerEnginePrivate // DebuggerEnginePrivate
@@ -282,6 +281,8 @@ public slots:
private slots: private slots:
void slotEditBreakpoint(); void slotEditBreakpoint();
void slotRunToLine();
void slotJumpToLine();
public: public:
DebuggerState state() const { return m_state; } DebuggerState state() const { return m_state; }
@@ -316,18 +317,63 @@ public:
bool m_isSlaveEngine; 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() void DebuggerEnginePrivate::breakpointSetRemoveMarginActionTriggered()
{ {
QAction *act = qobject_cast<QAction *>(sender()); QString fileName;
QTC_ASSERT(act, return); int lineNumber;
QList<QVariant> list = act->data().toList(); quint64 address;
QTC_ASSERT(list.size() >= 3, qDebug() << list; return); if (positionFromContextActionData(sender(), &fileName, &lineNumber, &address))
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); 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() void DebuggerEnginePrivate::slotEditBreakpoint()
{ {
const QAction *act = qobject_cast<QAction *>(sender()); const QAction *act = qobject_cast<QAction *>(sender());
@@ -338,24 +384,13 @@ void DebuggerEnginePrivate::slotEditBreakpoint()
BreakWindow::editBreakpoint(breakPointData, ICore::instance()->mainWindow()); 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 &parameters) void DebuggerEnginePrivate::handleContextMenuRequest(const QVariant &parameters)
{ {
const QList<QVariant> list = parameters.toList(); const QList<QVariant> list = parameters.toList();
QTC_ASSERT(list.size() == 3, qDebug() << list; return); QTC_ASSERT(list.size() == 3, qDebug() << list; return);
TextEditor::ITextEditor *editor = TextEditor::ITextEditor *editor =
(TextEditor::ITextEditor *)(list.at(0).value<quint64>()); (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>()); QMenu *menu = (QMenu *)(list.at(2).value<quint64>());
BreakpointData *data = 0; BreakpointData *data = 0;
@@ -428,6 +463,25 @@ void DebuggerEnginePrivate::handleContextMenuRequest(const QVariant &parameters)
SLOT(breakpointSetRemoveMarginActionTriggered())); SLOT(breakpointSetRemoveMarginActionTriggered()));
menu->addAction(act); 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(); 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() void DebuggerEngine::executeRunToLine()
{ {
ITextEditor *textEditor = currentTextEditor(); QString fileName;
QTC_ASSERT(textEditor, return); int lineNumber;
QString fileName = textEditor->file()->fileName(); if (currentTextEditorPosition(&fileName, &lineNumber)) {
if (fileName.isEmpty())
return;
int lineNumber = textEditor->currentLine();
resetLocation(); resetLocation();
executeRunToLine(fileName, lineNumber); executeRunToLine(fileName, lineNumber);
} }
}
void DebuggerEngine::executeRunToFunction() void DebuggerEngine::executeRunToFunction()
{ {
ITextEditor *textEditor = currentTextEditor(); ITextEditor *textEditor = currentTextEditor();
QTC_ASSERT(textEditor, return); QTC_ASSERT(textEditor, return);
QString fileName = textEditor->file()->fileName();
QPlainTextEdit *ed = qobject_cast<QPlainTextEdit*>(textEditor->widget()); QPlainTextEdit *ed = qobject_cast<QPlainTextEdit*>(textEditor->widget());
if (!ed) if (!ed)
return; return;
@@ -931,12 +973,9 @@ void DebuggerEngine::executeRunToFunction()
void DebuggerEngine::executeJumpToLine() void DebuggerEngine::executeJumpToLine()
{ {
ITextEditor *textEditor = currentTextEditor(); QString fileName;
QTC_ASSERT(textEditor, return); int lineNumber;
QString fileName = textEditor->file()->fileName(); if (currentTextEditorPosition(&fileName, &lineNumber))
int lineNumber = textEditor->currentLine();
if (fileName.isEmpty())
return;
executeJumpToLine(fileName, lineNumber); executeJumpToLine(fileName, lineNumber);
} }

View File

@@ -818,11 +818,9 @@ struct DebuggerActions
QAction *resetAction; // FIXME: Should not be needed in a stable release QAction *resetAction; // FIXME: Should not be needed in a stable release
QAction *stepAction; QAction *stepAction;
QAction *stepOutAction; QAction *stepOutAction;
QAction *runToLineAction1; // in the Debug menu QAction *runToLineAction; // Debug menu
QAction *runToLineAction2; // in the text editor context menu
QAction *runToFunctionAction; QAction *runToFunctionAction;
QAction *jumpToLineAction1; // in the Debug menu QAction *jumpToLineAction; // in the Debug menu
QAction *jumpToLineAction2; // in the text editor context menu
QAction *returnFromFunctionAction; QAction *returnFromFunctionAction;
QAction *nextAction; QAction *nextAction;
QAction *snapshotAction; QAction *snapshotAction;
@@ -1196,10 +1194,8 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, QString *er
m_actions.stepOutAction->setIcon( m_actions.stepOutAction->setIcon(
QIcon(__(":/debugger/images/debugger_stepout_small.png"))); QIcon(__(":/debugger/images/debugger_stepout_small.png")));
m_actions.runToLineAction1 = new QAction(tr("Run to Line"), this); m_actions.runToLineAction = new QAction(tr("Run to Line"), this);
m_actions.runToLineAction1->setProperty(Role, RequestExecRunToLineRole); m_actions.runToLineAction->setProperty(Role, RequestExecRunToLineRole);
m_actions.runToLineAction2 = new QAction(tr("Run to Line"), this);
m_actions.runToLineAction2->setProperty(Role, RequestExecRunToLineRole);
m_actions.runToFunctionAction = m_actions.runToFunctionAction =
new QAction(tr("Run to Outermost Function"), this); 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); new QAction(tr("Immediately Return From Inner Function"), this);
m_actions.returnFromFunctionAction->setProperty(Role, RequestExecReturnFromFunctionRole); m_actions.returnFromFunctionAction->setProperty(Role, RequestExecReturnFromFunctionRole);
m_actions.jumpToLineAction1 = new QAction(tr("Jump to Line"), this); m_actions.jumpToLineAction = new QAction(tr("Jump to Line"), this);
m_actions.jumpToLineAction1->setProperty(Role, RequestExecJumpToLineRole); m_actions.jumpToLineAction->setProperty(Role, RequestExecJumpToLineRole);
m_actions.jumpToLineAction2 = new QAction(tr("Jump to Line"), this);
m_actions.jumpToLineAction2->setProperty(Role, RequestExecJumpToLineRole);
m_actions.breakAction = new QAction(tr("Toggle Breakpoint"), this); 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.nextAction, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.stepAction, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.stepAction, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.stepOutAction, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.stepOutAction, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.runToLineAction1, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.runToLineAction, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.runToLineAction2, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.runToFunctionAction, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.runToFunctionAction, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.jumpToLineAction1, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.jumpToLineAction, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.jumpToLineAction2, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.returnFromFunctionAction, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.returnFromFunctionAction, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.watchAction1, SIGNAL(triggered()), SLOT(onAction())); connect(m_actions.watchAction1, SIGNAL(triggered()), SLOT(onAction()));
connect(m_actions.watchAction2, 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); m_uiSwitcher->addMenuAction(cmd, CppLanguage);
cmd = am->registerAction(m_actions.runToLineAction1, cmd = am->registerAction(m_actions.runToLineAction,
Constants::RUN_TO_LINE1, cppDebuggercontext); Constants::RUN_TO_LINE1, cppDebuggercontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY)); cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY));
cmd->setAttribute(Command::CA_Hide); cmd->setAttribute(Command::CA_Hide);
@@ -1485,7 +1477,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, QString *er
m_uiSwitcher->addMenuAction(cmd, CppLanguage); m_uiSwitcher->addMenuAction(cmd, CppLanguage);
cmd = am->registerAction(m_actions.jumpToLineAction1, cmd = am->registerAction(m_actions.jumpToLineAction,
Constants::JUMP_TO_LINE1, cppDebuggercontext); Constants::JUMP_TO_LINE1, cppDebuggercontext);
cmd->setAttribute(Command::CA_Hide); cmd->setAttribute(Command::CA_Hide);
m_uiSwitcher->addMenuAction(cmd, CppLanguage); m_uiSwitcher->addMenuAction(cmd, CppLanguage);
@@ -1564,18 +1556,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, QString *er
editorContextMenu->addAction(cmd); editorContextMenu->addAction(cmd);
cmd->setAttribute(Command::CA_Hide); 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); m_plugin->addAutoReleasedObject(new CommonOptionsPage);
QList<Core::IOptionsPage *> engineOptionPages; QList<Core::IOptionsPage *> engineOptionPages;
if (cmdLineEnabledEngines & GdbEngineType) if (cmdLineEnabledEngines & GdbEngineType)
@@ -2259,12 +2239,10 @@ void DebuggerPluginPrivate::setInitialState()
m_actions.stepAction->setEnabled(false); m_actions.stepAction->setEnabled(false);
m_actions.stepOutAction->setEnabled(false); m_actions.stepOutAction->setEnabled(false);
m_actions.runToLineAction1->setEnabled(false); m_actions.runToLineAction->setEnabled(false);
m_actions.runToLineAction2->setEnabled(false);
m_actions.runToFunctionAction->setEnabled(false); m_actions.runToFunctionAction->setEnabled(false);
m_actions.returnFromFunctionAction->setEnabled(false); m_actions.returnFromFunctionAction->setEnabled(false);
m_actions.jumpToLineAction1->setEnabled(false); m_actions.jumpToLineAction->setEnabled(false);
m_actions.jumpToLineAction2->setEnabled(false);
m_actions.nextAction->setEnabled(false); m_actions.nextAction->setEnabled(false);
theDebuggerAction(AutoDerefPointers)->setEnabled(true); theDebuggerAction(AutoDerefPointers)->setEnabled(true);
@@ -2391,15 +2369,13 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
m_actions.stepAction->setEnabled(stopped); m_actions.stepAction->setEnabled(stopped);
m_actions.stepOutAction->setEnabled(stopped); m_actions.stepOutAction->setEnabled(stopped);
m_actions.runToLineAction1->setEnabled(stopped); m_actions.runToLineAction->setEnabled(stopped);
m_actions.runToLineAction2->setEnabled(stopped);
m_actions.runToFunctionAction->setEnabled(stopped); m_actions.runToFunctionAction->setEnabled(stopped);
m_actions.returnFromFunctionAction-> m_actions.returnFromFunctionAction->
setEnabled(stopped && (caps & ReturnFromFunctionCapability)); setEnabled(stopped && (caps & ReturnFromFunctionCapability));
const bool canJump = stopped && (caps & JumpToLineCapability); const bool canJump = stopped && (caps & JumpToLineCapability);
m_actions.jumpToLineAction1->setEnabled(canJump); m_actions.jumpToLineAction->setEnabled(canJump);
m_actions.jumpToLineAction2->setEnabled(canJump);
m_actions.nextAction->setEnabled(stopped); m_actions.nextAction->setEnabled(stopped);

View File

@@ -238,5 +238,6 @@ bool StackHandler::isDebuggingDebuggingHelpers() const
return false; return false;
} }
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger

View File

@@ -40,6 +40,7 @@
#include <texteditor/basetextmark.h> #include <texteditor/basetextmark.h>
#include <texteditor/itexteditor.h> #include <texteditor/itexteditor.h>
#include <texteditor/texteditorconstants.h> #include <texteditor/texteditorconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <cpptools/cppmodelmanagerinterface.h> #include <cpptools/cppmodelmanagerinterface.h>
#include <cpptools/cpptoolsconstants.h> #include <cpptools/cpptoolsconstants.h>
@@ -664,6 +665,14 @@ QString decodeData(const QByteArray &ba, int encoding)
return QCoreApplication::translate("Debugger", "<Encoding error>"); 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 // Editor tooltip support
bool isCppEditor(Core::IEditor *editor) bool isCppEditor(Core::IEditor *editor)
{ {
@@ -678,6 +687,24 @@ bool isCppEditor(Core::IEditor *editor)
|| mimeType == OBJECTIVE_CPP_SOURCE_MIMETYPE; || 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 // Return the Cpp expression, and, if desired, the function
QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos,
int *line, int *column, QString *function /* = 0 */) int *line, int *column, QString *function /* = 0 */)

View File

@@ -91,6 +91,10 @@ QString quoteUnprintableLatin1(const QByteArray &ba);
bool isCppEditor(Core::IEditor *editor); bool isCppEditor(Core::IEditor *editor);
QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos,
int *line, int *column, QString *function = 0); 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. // Decode string data as returned by the dumper helpers.
QString decodeData(const QByteArray &baIn, int encoding); QString decodeData(const QByteArray &baIn, int encoding);