cutter/src/widgets/DebugActions.cpp

200 lines
8.3 KiB
C++
Raw Normal View History

2018-12-21 20:36:40 +00:00
#include "DebugActions.h"
#include "core/MainWindow.h"
#include "dialogs/AttachProcDialog.h"
2018-06-12 08:43:14 +00:00
#include <QAction>
#include <QPainter>
#include <QMenu>
2018-10-03 11:30:12 +00:00
#include <QList>
2018-07-25 08:59:40 +00:00
#include <QFileInfo>
2018-12-21 20:36:40 +00:00
#include <QToolBar>
#include <QToolButton>
2018-06-12 08:43:14 +00:00
2018-12-21 20:36:40 +00:00
DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) :
QObject(main),
2018-06-12 08:43:14 +00:00
main(main)
{
2018-12-21 20:36:40 +00:00
setObjectName("DebugActions");
// setIconSize(QSize(16, 16));
2018-10-03 11:30:12 +00:00
// define icons
QIcon startDebugIcon = QIcon(":/img/icons/play_light_debug.svg");
QIcon startEmulIcon = QIcon(":/img/icons/play_light_emul.svg");
QIcon startAttachIcon = QIcon(":/img/icons/play_light_attach.svg");
QIcon stopIcon = QIcon(":/img/icons/media-stop_light.svg");
2018-06-12 08:43:14 +00:00
QIcon continueIcon = QIcon(":/img/icons/media-skip-forward_light.svg");
QIcon continueUntilMainIcon = QIcon(":/img/icons/continue_until_main.svg");
QIcon continueUntilCallIcon = QIcon(":/img/icons/continue_until_call.svg");
QIcon continueUntilSyscallIcon = QIcon(":/img/icons/continue_until_syscall.svg");
2018-06-12 08:43:14 +00:00
QIcon stepIcon = QIcon(":/img/icons/step_light.svg");
QIcon stepOverIcon = QIcon(":/img/icons/step_over_light.svg");
QIcon stepOutIcon = QIcon(":/img/icons/step_out_light.svg");
2018-10-03 11:30:12 +00:00
QIcon restartIcon = QIcon(":/img/icons/spin_light.svg");
2018-06-12 08:43:14 +00:00
// define action labels
QString startDebugLabel = tr("Start debug");
QString startEmulLabel = tr("Start emulation");
QString startAttachLabel = tr("Attach to process");
QString stopDebugLabel = tr("Stop debug");
QString stopEmulLabel = tr("Stop emulation");
QString restartDebugLabel = tr("Restart program");
QString restartEmulLabel = tr("Restart emulation");
QString continueLabel = tr("Continue");
QString continueUMLabel = tr("Continue until main");
QString continueUCLabel = tr("Continue until call");
QString continueUSLabel = tr("Continue until syscall");
QString stepLabel = tr("Step");
QString stepOverLabel = tr("Step over");
QString stepOutLabel = tr("Step out");
2018-10-03 11:30:12 +00:00
// define actions
2018-12-21 20:36:40 +00:00
actionStart = new QAction(startDebugIcon, startDebugLabel, this);
actionStart->setShortcut(QKeySequence(Qt::Key_F9));
2018-12-21 20:36:40 +00:00
actionStartEmul = new QAction(startEmulIcon, startEmulLabel, this);
actionAttach = new QAction(startAttachIcon, startAttachLabel, this);
actionStop = new QAction(stopIcon, stopDebugLabel, this);
actionContinue = new QAction(continueIcon, continueLabel, this);
actionContinue->setShortcut(QKeySequence(Qt::Key_F5));
2018-12-21 20:36:40 +00:00
actionContinueUntilMain = new QAction(continueUntilMainIcon, continueUMLabel, this);
actionContinueUntilCall = new QAction(continueUntilCallIcon, continueUCLabel, this);
actionContinueUntilSyscall = new QAction(continueUntilSyscallIcon, continueUSLabel, this);
actionStep = new QAction(stepIcon, stepLabel, this);
actionStep->setShortcut(QKeySequence(Qt::Key_F7));
2018-12-21 20:36:40 +00:00
actionStepOver = new QAction(stepOverIcon, stepOverLabel, this);
actionStepOver->setShortcut(QKeySequence(Qt::Key_F8));
2018-12-21 20:36:40 +00:00
actionStepOut = new QAction(stepOutIcon, stepOutLabel, this);
actionStepOut->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F8));
QToolButton *startButton = new QToolButton;
startButton->setPopupMode(QToolButton::MenuButtonPopup);
connect(startButton, &QToolButton::triggered, startButton, &QToolButton::setDefaultAction);
QMenu *startMenu = new QMenu;
2018-10-03 11:30:12 +00:00
// only emulation is currently allowed
2018-07-26 09:46:17 +00:00
// startMenu->addAction(actionStart);
// startMenu->addAction(actionAttach);
// startButton->setDefaultAction(actionStart);
2018-10-03 11:30:12 +00:00
startMenu->addAction(actionStartEmul);
2018-07-26 09:46:17 +00:00
startButton->setDefaultAction(actionStartEmul);
startButton->setMenu(startMenu);
QToolButton *continueUntilButton = new QToolButton;
continueUntilButton->setPopupMode(QToolButton::MenuButtonPopup);
2018-09-30 20:00:53 +00:00
connect(continueUntilButton, &QToolButton::triggered, continueUntilButton,
&QToolButton::setDefaultAction);
QMenu *continueUntilMenu = new QMenu;
continueUntilMenu->addAction(actionContinueUntilMain);
continueUntilMenu->addAction(actionContinueUntilCall);
continueUntilMenu->addAction(actionContinueUntilSyscall);
continueUntilButton->setMenu(continueUntilMenu);
continueUntilButton->setDefaultAction(actionContinueUntilMain);
2018-10-03 11:30:12 +00:00
// define toolbar widgets and actions
2018-12-21 20:36:40 +00:00
toolBar->addWidget(startButton);
toolBar->addAction(actionContinue);
toolBar->addAction(actionStop);
actionAllContinues = toolBar->addWidget(continueUntilButton);
toolBar->addAction(actionStep);
toolBar->addAction(actionStepOver);
toolBar->addAction(actionStepOut);
2018-06-12 08:43:14 +00:00
2018-10-03 11:30:12 +00:00
allActions = {actionStop, actionAllContinues, actionContinue, actionContinueUntilCall, actionContinueUntilMain, actionContinueUntilSyscall, actionStep, actionStepOut, actionStepOver};
// hide allactions
setAllActionsVisible(false);
connect(actionStop, &QAction::triggered, Core(), &CutterCore::stopDebug);
2018-09-30 20:00:53 +00:00
connect(actionStop, &QAction::triggered, [ = ]() {
actionStart->setVisible(true);
actionStartEmul->setVisible(true);
actionAttach->setVisible(true);
actionStop->setText(stopDebugLabel);
actionStart->setText(startDebugLabel);
2018-10-03 11:30:12 +00:00
actionStart->setIcon(startDebugIcon);
actionStartEmul->setText(startEmulLabel);
2018-10-03 11:30:12 +00:00
actionStartEmul->setIcon(startEmulIcon);
setAllActionsVisible(false);
});
connect(actionStep, &QAction::triggered, Core(), &CutterCore::stepDebug);
2018-10-03 11:30:12 +00:00
connect(actionStart, &QAction::triggered, [ = ]() {
// check if file is executable before starting debug
QString filename = Core()->getConfig("file.path").split(" ").first();
2018-07-25 08:59:40 +00:00
QFileInfo info(filename);
if (!Core()->currentlyDebugging && !info.isExecutable()) {
2018-07-25 08:59:40 +00:00
QMessageBox msgBox;
msgBox.setText(tr("File '%1' does not have executable permissions.").arg(filename));
2018-07-25 08:59:40 +00:00
msgBox.exec();
return;
}
setAllActionsVisible(true);
actionAttach->setVisible(false);
actionStartEmul->setVisible(false);
actionStart->setText(restartDebugLabel);
2018-10-03 11:30:12 +00:00
actionStart->setIcon(restartIcon);
2018-07-25 08:59:40 +00:00
Core()->startDebug();
});
2018-10-03 11:30:12 +00:00
2018-12-21 20:36:40 +00:00
connect(actionAttach, &QAction::triggered, this, &DebugActions::attachProcessDialog);
connect(actionStartEmul, &QAction::triggered, Core(), &CutterCore::startEmulation);
2018-09-30 20:00:53 +00:00
connect(actionStartEmul, &QAction::triggered, [ = ]() {
2018-10-03 11:30:12 +00:00
setAllActionsVisible(true);
actionStart->setVisible(false);
actionAttach->setVisible(false);
actionContinueUntilMain->setVisible(false);
actionStepOut->setVisible(false);
continueUntilButton->setDefaultAction(actionContinueUntilSyscall);
actionStartEmul->setText(restartEmulLabel);
2018-10-03 11:30:12 +00:00
actionStartEmul->setIcon(restartIcon);
actionStop->setText(stopEmulLabel);
});
connect(actionStepOver, &QAction::triggered, Core(), &CutterCore::stepOverDebug);
connect(actionStepOut, &QAction::triggered, Core(), &CutterCore::stepOutDebug);
connect(actionContinue, &QAction::triggered, Core(), &CutterCore::continueDebug);
2018-12-21 20:36:40 +00:00
connect(actionContinueUntilMain, &QAction::triggered, this, &DebugActions::continueUntilMain);
connect(actionContinueUntilCall, &QAction::triggered, Core(), &CutterCore::continueUntilCall);
connect(actionContinueUntilSyscall, &QAction::triggered, Core(), &CutterCore::continueUntilSyscall);
2018-06-12 08:43:14 +00:00
}
2018-12-21 20:36:40 +00:00
void DebugActions::continueUntilMain()
2018-06-12 08:43:14 +00:00
{
Core()->continueUntilDebug("main");
}
2018-12-21 20:36:40 +00:00
void DebugActions::attachProcessDialog()
{
AttachProcDialog dialog(main);
bool success = false;
while (!success) {
success = true;
if (dialog.exec()) {
int pid = dialog.getPID();
if (pid >= 0) {
attachProcess(pid);
} else {
success = false;
QMessageBox msgBox;
msgBox.setText(tr("Error attaching. No process selected!"));
msgBox.exec();
}
}
}
}
2018-12-21 20:36:40 +00:00
void DebugActions::attachProcess(int pid)
{
QString stopAttachLabel = tr("Detach from process");
// hide unwanted buttons
2018-10-03 11:30:12 +00:00
setAllActionsVisible(true);
actionStart->setVisible(false);
actionStartEmul->setVisible(false);
actionStop->setText(stopAttachLabel);
// attach
Core()->attachDebug(pid);
2018-10-03 11:30:12 +00:00
}
2018-12-21 20:36:40 +00:00
void DebugActions::setAllActionsVisible(bool visible)
2018-10-03 11:30:12 +00:00
{
for (QAction *action : allActions) {
action->setVisible(visible);
}
2018-10-04 13:37:12 +00:00
}