summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger/qt/windowqt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/debugger/qt/windowqt.cpp')
-rw-r--r--src/osd/modules/debugger/qt/windowqt.cpp264
1 files changed, 195 insertions, 69 deletions
diff --git a/src/osd/modules/debugger/qt/windowqt.cpp b/src/osd/modules/debugger/qt/windowqt.cpp
index dda9ee64dc7..294871e6d22 100644
--- a/src/osd/modules/debugger/qt/windowqt.cpp
+++ b/src/osd/modules/debugger/qt/windowqt.cpp
@@ -1,104 +1,114 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
-#include <QtWidgets/QMenu>
-#include <QtWidgets/QMenuBar>
-
#include "windowqt.h"
-#include "logwindow.h"
-#include "dasmwindow.h"
-#include "memorywindow.h"
+
#include "breakpointswindow.h"
+#include "dasmwindow.h"
#include "deviceswindow.h"
+#include "logwindow.h"
+#include "memorywindow.h"
+#include "debugger.h"
+#include "debug/debugcon.h"
#include "debug/debugcpu.h"
-bool WindowQt::s_refreshAll = false;
-bool WindowQt::s_hideAll = false;
+#include "util/xmlfile.h"
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QMenuBar>
+
+
+namespace osd::debugger::qt {
// Since all debug windows are intended to be top-level, this inherited
// constructor is always called with a nullptr parent. The passed-in parent widget,
// however, is often used to place each child window & the code to do this can
// be found in most of the inherited classes.
-WindowQt::WindowQt(running_machine* machine, QWidget* parent) :
+WindowQt::WindowQt(DebuggerQt &debugger, QWidget *parent) :
QMainWindow(parent),
- m_machine(machine)
+ m_debugger(debugger),
+ m_machine(debugger.machine())
{
setAttribute(Qt::WA_DeleteOnClose, true);
+ // Subscribe to signals
+ connect(&debugger, &DebuggerQt::exitDebugger, this, &WindowQt::debuggerExit);
+ connect(&debugger, &DebuggerQt::hideAllWindows, this, &WindowQt::hide);
+ connect(&debugger, &DebuggerQt::showAllWindows, this, &WindowQt::show);
+ connect(&debugger, &DebuggerQt::saveConfiguration, this, &WindowQt::saveConfiguration);
+
// The Debug menu bar
- QAction* debugActOpenMemory = new QAction("New &Memory Window", this);
+ QAction *debugActOpenMemory = new QAction("New &Memory Window", this);
debugActOpenMemory->setShortcut(QKeySequence("Ctrl+M"));
connect(debugActOpenMemory, &QAction::triggered, this, &WindowQt::debugActOpenMemory);
- QAction* debugActOpenDasm = new QAction("New &Dasm Window", this);
+ QAction *debugActOpenDasm = new QAction("New &Disassembly Window", this);
debugActOpenDasm->setShortcut(QKeySequence("Ctrl+D"));
connect(debugActOpenDasm, &QAction::triggered, this, &WindowQt::debugActOpenDasm);
- QAction* debugActOpenLog = new QAction("New &Log Window", this);
+ QAction *debugActOpenLog = new QAction("New Error &Log Window", this);
debugActOpenLog->setShortcut(QKeySequence("Ctrl+L"));
connect(debugActOpenLog, &QAction::triggered, this, &WindowQt::debugActOpenLog);
- QAction* debugActOpenPoints = new QAction("New &Break|Watchpoints Window", this);
+ QAction *debugActOpenPoints = new QAction("New (&Break|Watch)points Window", this);
debugActOpenPoints->setShortcut(QKeySequence("Ctrl+B"));
connect(debugActOpenPoints, &QAction::triggered, this, &WindowQt::debugActOpenPoints);
- QAction* debugActOpenDevices = new QAction("New D&evices Window", this);
- debugActOpenDevices->setShortcut(QKeySequence("Shift+Ctrl+D"));
+ QAction *debugActOpenDevices = new QAction("New D&evices Window", this);
connect(debugActOpenDevices, &QAction::triggered, this, &WindowQt::debugActOpenDevices);
- QAction* dbgActRun = new QAction("Run", this);
+ QAction *dbgActRun = new QAction("Run", this);
dbgActRun->setShortcut(Qt::Key_F5);
connect(dbgActRun, &QAction::triggered, this, &WindowQt::debugActRun);
- QAction* dbgActRunAndHide = new QAction("Run And Hide Debugger", this);
+ QAction *dbgActRunAndHide = new QAction("Run And Hide Debugger", this);
dbgActRunAndHide->setShortcut(Qt::Key_F12);
connect(dbgActRunAndHide, &QAction::triggered, this, &WindowQt::debugActRunAndHide);
- QAction* dbgActRunToNextCpu = new QAction("Run to Next CPU", this);
+ QAction *dbgActRunToNextCpu = new QAction("Run to Next CPU", this);
dbgActRunToNextCpu->setShortcut(Qt::Key_F6);
connect(dbgActRunToNextCpu, &QAction::triggered, this, &WindowQt::debugActRunToNextCpu);
- QAction* dbgActRunNextInt = new QAction("Run to Next Interrupt on This CPU", this);
+ QAction *dbgActRunNextInt = new QAction("Run to Next Interrupt on This CPU", this);
dbgActRunNextInt->setShortcut(Qt::Key_F7);
connect(dbgActRunNextInt, &QAction::triggered, this, &WindowQt::debugActRunNextInt);
- QAction* dbgActRunNextVBlank = new QAction("Run to Next VBlank", this);
+ QAction *dbgActRunNextVBlank = new QAction("Run to Next VBlank", this);
dbgActRunNextVBlank->setShortcut(Qt::Key_F8);
connect(dbgActRunNextVBlank, &QAction::triggered, this, &WindowQt::debugActRunNextVBlank);
- QAction* dbgActStepInto = new QAction("Step Into", this);
+ QAction *dbgActStepInto = new QAction("Step Into", this);
dbgActStepInto->setShortcut(Qt::Key_F11);
connect(dbgActStepInto, &QAction::triggered, this, &WindowQt::debugActStepInto);
- QAction* dbgActStepOver = new QAction("Step Over", this);
+ QAction *dbgActStepOver = new QAction("Step Over", this);
dbgActStepOver->setShortcut(Qt::Key_F10);
connect(dbgActStepOver, &QAction::triggered, this, &WindowQt::debugActStepOver);
- QAction* dbgActStepOut = new QAction("Step Out", this);
+ QAction *dbgActStepOut = new QAction("Step Out", this);
dbgActStepOut->setShortcut(QKeySequence("Shift+F11"));
connect(dbgActStepOut, &QAction::triggered, this, &WindowQt::debugActStepOut);
- QAction* dbgActSoftReset = new QAction("Soft Reset", this);
+ QAction *dbgActSoftReset = new QAction("Soft Reset", this);
dbgActSoftReset->setShortcut(Qt::Key_F3);
connect(dbgActSoftReset, &QAction::triggered, this, &WindowQt::debugActSoftReset);
- QAction* dbgActHardReset = new QAction("Hard Reset", this);
+ QAction *dbgActHardReset = new QAction("Hard Reset", this);
dbgActHardReset->setShortcut(QKeySequence("Shift+F3"));
connect(dbgActHardReset, &QAction::triggered, this, &WindowQt::debugActHardReset);
- QAction* dbgActClose = new QAction("Close &Window", this);
+ QAction *dbgActClose = new QAction("Close &Window", this);
dbgActClose->setShortcut(QKeySequence::Close);
connect(dbgActClose, &QAction::triggered, this, &WindowQt::debugActClose);
- QAction* dbgActQuit = new QAction("&Quit", this);
+ QAction *dbgActQuit = new QAction("&Quit", this);
dbgActQuit->setShortcut(QKeySequence::Quit);
connect(dbgActQuit, &QAction::triggered, this, &WindowQt::debugActQuit);
// Construct the menu
- QMenu* debugMenu = menuBar()->addMenu("&Debug");
+ QMenu *debugMenu = menuBar()->addMenu("&Debug");
debugMenu->addAction(debugActOpenMemory);
debugMenu->addAction(debugActOpenDasm);
debugMenu->addAction(debugActOpenLog);
@@ -127,9 +137,10 @@ WindowQt::~WindowQt()
{
}
+
void WindowQt::debugActOpenMemory()
{
- MemoryWindow* foo = new MemoryWindow(m_machine, this);
+ MemoryWindow *foo = new MemoryWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -139,7 +150,7 @@ void WindowQt::debugActOpenMemory()
void WindowQt::debugActOpenDasm()
{
- DasmWindow* foo = new DasmWindow(m_machine, this);
+ DasmWindow *foo = new DasmWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -149,7 +160,7 @@ void WindowQt::debugActOpenDasm()
void WindowQt::debugActOpenLog()
{
- LogWindow* foo = new LogWindow(m_machine, this);
+ LogWindow *foo = new LogWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -159,7 +170,7 @@ void WindowQt::debugActOpenLog()
void WindowQt::debugActOpenPoints()
{
- BreakpointsWindow* foo = new BreakpointsWindow(m_machine, this);
+ BreakpointsWindow *foo = new BreakpointsWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -169,7 +180,7 @@ void WindowQt::debugActOpenPoints()
void WindowQt::debugActOpenDevices()
{
- DevicesWindow* foo = new DevicesWindow(m_machine, this);
+ DevicesWindow *foo = new DevicesWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -179,54 +190,54 @@ void WindowQt::debugActOpenDevices()
void WindowQt::debugActRun()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go();
}
void WindowQt::debugActRunAndHide()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
- hideAll();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go();
+ m_debugger.hideAll();
}
void WindowQt::debugActRunToNextCpu()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_next_device();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go_next_device();
}
void WindowQt::debugActRunNextInt()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go_interrupt();
}
void WindowQt::debugActRunNextVBlank()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_vblank();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go_vblank();
}
void WindowQt::debugActStepInto()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
+ m_machine.debugger().console().get_visible_cpu()->debug()->single_step();
}
void WindowQt::debugActStepOver()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_over();
+ m_machine.debugger().console().get_visible_cpu()->debug()->single_step_over();
}
void WindowQt::debugActStepOut()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_out();
+ m_machine.debugger().console().get_visible_cpu()->debug()->single_step_out();
}
void WindowQt::debugActSoftReset()
{
- m_machine->schedule_soft_reset();
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
+ m_machine.schedule_soft_reset();
+ m_machine.debugger().console().get_visible_cpu()->debug()->single_step();
}
void WindowQt::debugActHardReset()
{
- m_machine->schedule_hard_reset();
+ m_machine.schedule_hard_reset();
}
void WindowQt::debugActClose()
@@ -236,43 +247,158 @@ void WindowQt::debugActClose()
void WindowQt::debugActQuit()
{
- m_machine->schedule_exit();
+ m_machine.schedule_exit();
+}
+
+void WindowQt::debuggerExit()
+{
+ // this isn't called from a Qt event loop, so close() will leak the window object
+ delete this;
+}
+
+
+void WindowQt::restoreConfiguration(util::xml::data_node const &node)
+{
+ QPoint p(geometry().topLeft());
+ p.setX(node.get_attribute_int(ATTR_WINDOW_POSITION_X, p.x()));
+ p.setY(node.get_attribute_int(ATTR_WINDOW_POSITION_Y, p.y()));
+
+ QSize s(size());
+ s.setWidth(node.get_attribute_int(ATTR_WINDOW_WIDTH, s.width()));
+ s.setHeight(node.get_attribute_int(ATTR_WINDOW_HEIGHT, s.height()));
+
+ // TODO: sanity checks, restrict to screen area
+
+ setGeometry(p.x(), p.y(), s.width(), s.height());
+}
+
+
+void WindowQt::saveConfiguration(util::xml::data_node &parentnode)
+{
+ util::xml::data_node *const node = parentnode.add_child(NODE_WINDOW, nullptr);
+ if (node)
+ saveConfigurationToNode(*node);
}
-//=========================================================================
-// WindowQtConfig
-//=========================================================================
-void WindowQtConfig::buildFromQWidget(QWidget* widget)
+void WindowQt::saveConfigurationToNode(util::xml::data_node &node)
{
- m_position.setX(widget->geometry().topLeft().x());
- m_position.setY(widget->geometry().topLeft().y());
- m_size.setX(widget->size().width());
- m_size.setY(widget->size().height());
+ node.set_attribute_int(ATTR_WINDOW_POSITION_X, geometry().topLeft().x());
+ node.set_attribute_int(ATTR_WINDOW_POSITION_Y, geometry().topLeft().y());
+ node.set_attribute_int(ATTR_WINDOW_WIDTH, size().width());
+ node.set_attribute_int(ATTR_WINDOW_HEIGHT, size().height());
}
-void WindowQtConfig::applyToQWidget(QWidget* widget)
+CommandHistory::CommandHistory() :
+ m_history(),
+ m_current(),
+ m_position(-1)
{
- widget->setGeometry(m_position.x(), m_position.y(), m_size.x(), m_size.y());
}
-void WindowQtConfig::addToXmlDataNode(util::xml::data_node &node) const
+CommandHistory::~CommandHistory()
{
- node.set_attribute_int("type", m_type);
- node.set_attribute_int("position_x", m_position.x());
- node.set_attribute_int("position_y", m_position.y());
- node.set_attribute_int("size_x", m_size.x());
- node.set_attribute_int("size_y", m_size.y());
}
-void WindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
+void CommandHistory::add(QString const &entry)
{
- m_size.setX(node.get_attribute_int("size_x", m_size.x()));
- m_size.setY(node.get_attribute_int("size_y", m_size.y()));
- m_position.setX(node.get_attribute_int("position_x", m_position.x()));
- m_position.setY(node.get_attribute_int("position_y", m_position.y()));
- m_type = (WindowQtConfig::WindowType)node.get_attribute_int("type", m_type);
+ if (m_history.empty() || (m_history.front() != entry))
+ {
+ while (m_history.size() >= CAPACITY)
+ m_history.pop_back();
+ m_history.push_front(entry);
+ }
+ m_position = 0;
}
+
+
+QString const *CommandHistory::previous(QString const &current)
+{
+ if ((m_position + 1) < m_history.size())
+ {
+ if (0 > m_position)
+ m_current = std::make_unique<QString>(current);
+ return &m_history[++m_position];
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+
+QString const *CommandHistory::next(QString const &current)
+{
+ if (0 < m_position)
+ {
+ return &m_history[--m_position];
+ }
+ else if (!m_position && m_current && (m_history.front() != *m_current))
+ {
+ --m_position;
+ return m_current.get();
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+
+void CommandHistory::edit()
+{
+ if (!m_position)
+ --m_position;
+}
+
+
+void CommandHistory::reset()
+{
+ m_position = -1;
+ m_current.reset();
+}
+
+
+void CommandHistory::clear()
+{
+ m_position = -1;
+ m_current.reset();
+ m_history.clear();
+}
+
+
+void CommandHistory::restoreConfigurationFromNode(util::xml::data_node const &node)
+{
+ clear();
+ util::xml::data_node const *const historynode = node.get_child(NODE_WINDOW_HISTORY);
+ if (historynode)
+ {
+ util::xml::data_node const *itemnode = historynode->get_child(NODE_HISTORY_ITEM);
+ while (itemnode)
+ {
+ if (itemnode->get_value() && *itemnode->get_value())
+ {
+ while (m_history.size() >= CAPACITY)
+ m_history.pop_back();
+ m_history.push_front(QString::fromUtf8(itemnode->get_value()));
+ }
+ itemnode = itemnode->get_next_sibling(NODE_HISTORY_ITEM);
+ }
+ }
+}
+
+
+void CommandHistory::saveConfigurationToNode(util::xml::data_node &node)
+{
+ util::xml::data_node *const historynode = node.add_child(NODE_WINDOW_HISTORY, nullptr);
+ if (historynode)
+ {
+ for (auto it = m_history.crbegin(); m_history.crend() != it; ++it)
+ historynode->add_child(NODE_HISTORY_ITEM, it->toUtf8().data());
+ }
+}
+
+} // namespace osd::debugger::qt