summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2022-12-02 02:25:57 +1100
committer Vas Crabb <vas@vastheman.com>2022-12-02 02:25:57 +1100
commit516f6b5d2b84c6f4a9aa447d651f3d5e6d113f6d (patch)
treea803f88585a3019c2b32a714f0e48e6c611f4032
parente46d279454cada2e0a9f2786d382333eacc5a2cd (diff)
-debugger: Improved session save/restore.
* Qt: Save expression for memory and disassembly views. * Qt: Made command history behave more like Cocoa. * Qt: Added expression history and made behaviour more like Cocoa. * Qt: Refactored global notifications to use signals. * Win32: Increased command/expression history size to 100 items. * Cocoa: Save state of device info viewer windows. * Qt/Win32/Cocoa: Save command/expression history. -util/xmlfile.cpp: Fixed bug where copyInto failed to copy nodes.
-rw-r--r--scripts/src/osd/modules.lua8
-rw-r--r--src/lib/util/xmlfile.cpp10
-rw-r--r--src/osd/modules/debugger/debugqt.cpp87
-rw-r--r--src/osd/modules/debugger/osx/debugcommandhistory.h3
-rw-r--r--src/osd/modules/debugger/osx/debugcommandhistory.mm30
-rw-r--r--src/osd/modules/debugger/osx/debugconsole.mm9
-rw-r--r--src/osd/modules/debugger/osx/debugwindowhandler.mm2
-rw-r--r--src/osd/modules/debugger/osx/deviceinfoviewer.mm1
-rw-r--r--src/osd/modules/debugger/qt/breakpointswindow.cpp41
-rw-r--r--src/osd/modules/debugger/qt/breakpointswindow.h26
-rw-r--r--src/osd/modules/debugger/qt/dasmwindow.cpp136
-rw-r--r--src/osd/modules/debugger/qt/dasmwindow.h33
-rw-r--r--src/osd/modules/debugger/qt/debuggerview.cpp40
-rw-r--r--src/osd/modules/debugger/qt/debuggerview.h3
-rw-r--r--src/osd/modules/debugger/qt/deviceinformationwindow.cpp32
-rw-r--r--src/osd/modules/debugger/qt/deviceinformationwindow.h26
-rw-r--r--src/osd/modules/debugger/qt/deviceswindow.cpp26
-rw-r--r--src/osd/modules/debugger/qt/deviceswindow.h24
-rw-r--r--src/osd/modules/debugger/qt/logwindow.cpp24
-rw-r--r--src/osd/modules/debugger/qt/logwindow.h22
-rw-r--r--src/osd/modules/debugger/qt/mainwindow.cpp178
-rw-r--r--src/osd/modules/debugger/qt/mainwindow.h41
-rw-r--r--src/osd/modules/debugger/qt/memorywindow.cpp198
-rw-r--r--src/osd/modules/debugger/qt/memorywindow.h42
-rw-r--r--src/osd/modules/debugger/qt/windowqt.cpp163
-rw-r--r--src/osd/modules/debugger/qt/windowqt.h87
-rw-r--r--src/osd/modules/debugger/win/debugwininfo.h3
-rw-r--r--src/osd/modules/debugger/win/editwininfo.cpp41
-rw-r--r--src/osd/modules/debugger/win/editwininfo.h4
-rw-r--r--src/osd/modules/debugger/xmlconfig.cpp3
-rw-r--r--src/osd/modules/debugger/xmlconfig.h3
31 files changed, 748 insertions, 598 deletions
diff --git a/scripts/src/osd/modules.lua b/scripts/src/osd/modules.lua
index cbc4734cb96..3c0da69f3c6 100644
--- a/scripts/src/osd/modules.lua
+++ b/scripts/src/osd/modules.lua
@@ -319,11 +319,9 @@ function qtdebuggerbuild()
local version = str_to_version(_OPTIONS["gcc_version"])
if _OPTIONS["gcc"]~=nil and (string.find(_OPTIONS["gcc"], "clang") or string.find(_OPTIONS["gcc"], "asmjs")) then
configuration { "gmake or ninja" }
- if (version >= 30600) then
- buildoptions {
- "-Wno-inconsistent-missing-override",
- }
- end
+ buildoptions {
+ "-Wno-error=inconsistent-missing-override",
+ }
configuration { }
end
diff --git a/src/lib/util/xmlfile.cpp b/src/lib/util/xmlfile.cpp
index e1bd1941734..be7bab597ca 100644
--- a/src/lib/util/xmlfile.cpp
+++ b/src/lib/util/xmlfile.cpp
@@ -465,8 +465,14 @@ data_node *data_node::copy_into(data_node &parent) const
}
else
{
- dst = dst->get_parent();
- src = src->get_parent()->get_next_sibling();
+ do
+ {
+ dst = dst->get_parent();
+ src = src->get_parent();
+ next = src->get_next_sibling();
+ }
+ while (!next && (&parent != dst));
+ src = next;
}
}
}
diff --git a/src/osd/modules/debugger/debugqt.cpp b/src/osd/modules/debugger/debugqt.cpp
index c0dc5acb7d6..ae82137f0d8 100644
--- a/src/osd/modules/debugger/debugqt.cpp
+++ b/src/osd/modules/debugger/debugqt.cpp
@@ -45,7 +45,7 @@ bool winwindow_qt_filter(void *message);
namespace {
-class debug_qt : public osd_module, public debug_module
+class debug_qt : public osd_module, public debug_module, protected osd::debugger::qt::DebuggerQt
#if defined(_WIN32) && !defined(SDLMAME_WIN32)
, public QAbstractNativeEventFilter
#endif
@@ -75,6 +75,8 @@ public:
}
#endif
+ virtual running_machine &machine() const override { return *m_machine; }
+
private:
void configuration_load(config_type which_type, config_level level, util::xml::data_node const *parentnode);
void configuration_save(config_type which_type, util::xml::data_node *parentnode);
@@ -102,13 +104,8 @@ char *qtArgv[] = { qtArg0, nullptr };
void debug_qt::exit()
{
// If you've done a hard reset, clear out existing widgets
- if (m_mainwindow)
- {
- m_mainwindow->setExiting();
- QApplication::closeAllWindows();
- qApp->processEvents(QEventLoop::AllEvents, 1);
- m_mainwindow = nullptr;
- }
+ emit exitDebugger();
+ m_mainwindow = nullptr;
}
@@ -145,7 +142,7 @@ void debug_qt::wait_for_debugger(device_t &device, bool firststop)
// Dialog initialization
if (!m_mainwindow)
{
- m_mainwindow = new osd::debugger::qt::MainWindow(*m_machine);
+ m_mainwindow = new osd::debugger::qt::MainWindow(*this);
if (m_config)
{
load_window_configurations(*m_config->get_first_child());
@@ -155,11 +152,7 @@ void debug_qt::wait_for_debugger(device_t &device, bool firststop)
}
// Ensure all top level widgets are visible & bring main window to front
- foreach (QWidget *widget, QApplication::topLevelWidgets())
- {
- if (widget->isWindow() && (widget->windowType() == Qt::Window))
- widget->show();
- }
+ emit showAllWindows();
if (firststop)
{
@@ -167,33 +160,13 @@ void debug_qt::wait_for_debugger(device_t &device, bool firststop)
m_mainwindow->raise();
}
- // Set the main window to display the proper cpu
+ // Set the main window to display the proper CPU
m_mainwindow->setProcessor(&device);
// Run our own QT event loop
osd_sleep(osd_ticks_per_second() / 1000 * 50);
qApp->processEvents(QEventLoop::AllEvents, 1);
- // Refresh everyone if requested
- if (m_mainwindow->wantsRefresh())
- {
- QWidgetList allWidgets = qApp->allWidgets();
- for (int i = 0; i < allWidgets.length(); i++)
- allWidgets[i]->update();
- m_mainwindow->clearRefreshFlag();
- }
-
- // Hide all top level widgets if requested
- if (m_mainwindow->wantsHide())
- {
- foreach (QWidget *widget, QApplication::topLevelWidgets())
- {
- if (widget->isWindow() && (widget->windowType() == Qt::Window))
- widget->hide();
- }
- m_mainwindow->clearHideFlag();
- }
-
#if defined(_WIN32) && !defined(SDLMAME_WIN32)
winwindow_update_cursor_state(*m_machine); // make sure the cursor isn't hidden while in debugger
#endif
@@ -232,18 +205,7 @@ void debug_qt::configuration_save(config_type which_type, util::xml::data_node *
{
// We only save system configuration for now
if ((config_type::SYSTEM == which_type) && parentnode)
- {
- // Loop over all the open windows
- for (QWidget *widget : QApplication::topLevelWidgets())
- {
- if (!widget->isWindow() || (widget->windowType() != Qt::Window))
- continue;
-
- osd::debugger::qt::WindowQt *const win = dynamic_cast<osd::debugger::qt::WindowQt *>(widget);
- if (win)
- win->saveConfiguration(*parentnode);
- }
- }
+ emit saveConfiguration(*parentnode);
}
@@ -251,46 +213,33 @@ void debug_qt::load_window_configurations(util::xml::data_node const &parentnode
{
for (util::xml::data_node const *wnode = parentnode.get_child(osd::debugger::NODE_WINDOW); wnode; wnode = wnode->get_next_sibling(osd::debugger::NODE_WINDOW))
{
- std::unique_ptr<osd::debugger::qt::WindowQtConfig> cfg;
osd::debugger::qt::WindowQt *win = nullptr;
switch (wnode->get_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, -1))
{
case osd::debugger::WINDOW_TYPE_CONSOLE:
- cfg = std::make_unique<osd::debugger::qt::MainWindowQtConfig>();
+ win = m_mainwindow;
break;
case osd::debugger::WINDOW_TYPE_MEMORY_VIEWER:
- cfg = std::make_unique<osd::debugger::qt::MemoryWindowQtConfig>();
- win = new osd::debugger::qt::MemoryWindow(*m_machine);
+ win = new osd::debugger::qt::MemoryWindow(*this);
break;
case osd::debugger::WINDOW_TYPE_DISASSEMBLY_VIEWER:
- cfg = std::make_unique<osd::debugger::qt::DasmWindowQtConfig>();
- win = new osd::debugger::qt::DasmWindow(*m_machine);
+ win = new osd::debugger::qt::DasmWindow(*this);
break;
case osd::debugger::WINDOW_TYPE_ERROR_LOG_VIEWER:
- cfg = std::make_unique<osd::debugger::qt::LogWindowQtConfig>();
- win = new osd::debugger::qt::LogWindow(*m_machine);
+ win = new osd::debugger::qt::LogWindow(*this);
break;
case osd::debugger::WINDOW_TYPE_POINTS_VIEWER:
- cfg = std::make_unique<osd::debugger::qt::BreakpointsWindowQtConfig>();
- win = new osd::debugger::qt::BreakpointsWindow(*m_machine);
+ win = new osd::debugger::qt::BreakpointsWindow(*this);
break;
case osd::debugger::WINDOW_TYPE_DEVICES_VIEWER:
- cfg = std::make_unique<osd::debugger::qt::DevicesWindowQtConfig>();
- win = new osd::debugger::qt::DevicesWindow(*m_machine);
+ win = new osd::debugger::qt::DevicesWindow(*this);
break;
case osd::debugger::WINDOW_TYPE_DEVICE_INFO_VIEWER:
- cfg = std::make_unique<osd::debugger::qt::DeviceInformationWindowQtConfig>();
- win = new osd::debugger::qt::DeviceInformationWindow(*m_machine);
+ win = new osd::debugger::qt::DeviceInformationWindow(*this);
break;
}
- if (cfg)
- {
- cfg->recoverFromXmlNode(*wnode);
- if (win)
- cfg->applyToQWidget(win);
- else if (osd::debugger::WINDOW_TYPE_CONSOLE == cfg->m_type)
- cfg->applyToQWidget(m_mainwindow);
- }
+ if (win)
+ win->restoreConfiguration(*wnode);
}
}
diff --git a/src/osd/modules/debugger/osx/debugcommandhistory.h b/src/osd/modules/debugger/osx/debugcommandhistory.h
index f99767cb4be..cf84ddc50f2 100644
--- a/src/osd/modules/debugger/osx/debugcommandhistory.h
+++ b/src/osd/modules/debugger/osx/debugcommandhistory.h
@@ -32,4 +32,7 @@
- (void)reset;
- (void)clear;
+- (void)saveConfigurationToNode:(util::xml::data_node *)node;
+- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node;
+
@end
diff --git a/src/osd/modules/debugger/osx/debugcommandhistory.mm b/src/osd/modules/debugger/osx/debugcommandhistory.mm
index 74a34904ae7..5b0f05511b7 100644
--- a/src/osd/modules/debugger/osx/debugcommandhistory.mm
+++ b/src/osd/modules/debugger/osx/debugcommandhistory.mm
@@ -54,9 +54,9 @@
- (void)add:(NSString *)entry {
if (([history count] == 0) || ![[history objectAtIndex:0] isEqualToString:entry]) {
- [history insertObject:entry atIndex:0];
- while ([history count] > length)
+ while ([history count] >= length)
[history removeLastObject];
+ [history insertObject:entry atIndex:0];
}
position = 0;
}
@@ -110,4 +110,30 @@
[history removeAllObjects];
}
+
+- (void)saveConfigurationToNode:(util::xml::data_node *)node {
+ util::xml::data_node *const hist = node->add_child(osd::debugger::NODE_WINDOW_HISTORY, nullptr);
+ if (hist) {
+ for (NSInteger i = [history count]; 0 < i; --i)
+ hist->add_child(osd::debugger::NODE_HISTORY_ITEM, [[history objectAtIndex:(i - 1)] UTF8String]);
+ }
+}
+
+
+- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
+ [self clear];
+ util::xml::data_node const *const hist = node->get_child(osd::debugger::NODE_WINDOW_HISTORY);
+ if (hist) {
+ util::xml::data_node const *item = hist->get_child(NODE_HISTORY_ITEM);
+ while (item) {
+ if (item->get_value() && *item->get_value()) {
+ while ([history count] >= length)
+ [history removeLastObject];
+ [history insertObject:[NSString stringWithUTF8String:item->get_value()] atIndex:0];
+ }
+ item = item->get_next_sibling(NODE_HISTORY_ITEM);
+ }
+ }
+}
+
@end
diff --git a/src/osd/modules/debugger/osx/debugconsole.mm b/src/osd/modules/debugger/osx/debugconsole.mm
index f6d01375403..18fe0607bee 100644
--- a/src/osd/modules/debugger/osx/debugconsole.mm
+++ b/src/osd/modules/debugger/osx/debugconsole.mm
@@ -404,8 +404,11 @@
win = [[MAMEDevicesViewer alloc] initWithMachine:*machine console:self];
break;
case osd::debugger::WINDOW_TYPE_DEVICE_INFO_VIEWER:
- // FIXME: needs device info on init, make another variant
- //win = [[MAMEDeviceInfoViewer alloc] initWithMachine:*machine console:self];
+ {
+ // FIXME: feels like a leaky abstraction, but device is needed for init
+ device_t *const device = machine->root_device().subdevice(node->get_attribute_string(osd::debugger::ATTR_WINDOW_DEVICE_TAG, ":"));
+ win = [[MAMEDeviceInfoViewer alloc] initWithDevice:(device ? *device : machine->root_device()) machine:*machine console:self];
+ }
break;
default:
break;
@@ -437,6 +440,7 @@
: NSMaxY([[[dasmSplit subviews] objectAtIndex:0] frame]));
}
[dasmView saveConfigurationToNode:node];
+ [history saveConfigurationToNode:node];
}
@@ -451,6 +455,7 @@
ofDividerAtIndex:0];
}
[dasmView restoreConfigurationFromNode:node];
+ [history restoreConfigurationFromNode:node];
}
diff --git a/src/osd/modules/debugger/osx/debugwindowhandler.mm b/src/osd/modules/debugger/osx/debugwindowhandler.mm
index ebeb1711dc4..ce824080c3d 100644
--- a/src/osd/modules/debugger/osx/debugwindowhandler.mm
+++ b/src/osd/modules/debugger/osx/debugwindowhandler.mm
@@ -494,6 +494,7 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
node->add_child(osd::debugger::NODE_WINDOW_EXPRESSION, [[self expression] UTF8String]);
+ [history saveConfigurationToNode:node];
}
@@ -502,6 +503,7 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
util::xml::data_node const *const expr = node->get_child(osd::debugger::NODE_WINDOW_EXPRESSION);
if (expr && expr->get_value())
[self setExpression:[NSString stringWithUTF8String:expr->get_value()]];
+ [history restoreConfigurationFromNode:node];
}
@end
diff --git a/src/osd/modules/debugger/osx/deviceinfoviewer.mm b/src/osd/modules/debugger/osx/deviceinfoviewer.mm
index e23110308ba..49ab79dedb8 100644
--- a/src/osd/modules/debugger/osx/deviceinfoviewer.mm
+++ b/src/osd/modules/debugger/osx/deviceinfoviewer.mm
@@ -238,6 +238,7 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
node->set_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, osd::debugger::WINDOW_TYPE_DEVICE_INFO_VIEWER);
+ node->set_attribute(osd::debugger::ATTR_WINDOW_DEVICE_TAG, device->tag());
}
@end
diff --git a/src/osd/modules/debugger/qt/breakpointswindow.cpp b/src/osd/modules/debugger/qt/breakpointswindow.cpp
index c108b2b94a3..60ceae6d16f 100644
--- a/src/osd/modules/debugger/qt/breakpointswindow.cpp
+++ b/src/osd/modules/debugger/qt/breakpointswindow.cpp
@@ -17,8 +17,8 @@
namespace osd::debugger::qt {
-BreakpointsWindow::BreakpointsWindow(running_machine &machine, QWidget *parent) :
- WindowQt(machine, nullptr)
+BreakpointsWindow::BreakpointsWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr)
{
setWindowTitle("Debug: All Breakpoints");
@@ -83,6 +83,20 @@ BreakpointsWindow::~BreakpointsWindow()
}
+void BreakpointsWindow::restoreConfiguration(util::xml::data_node const &node)
+{
+ WindowQt::restoreConfiguration(node);
+
+ auto const type = node.get_attribute_int(ATTR_WINDOW_POINTS_TYPE, -1);
+ QActionGroup *typeGroup = findChild<QActionGroup *>("typegroup");
+ if ((0 <= type) && (typeGroup->actions().size() > type))
+ typeGroup->actions()[type]->trigger();
+
+ m_breakpointsView->restoreConfigurationFromNode(node);
+
+}
+
+
void BreakpointsWindow::saveConfigurationToNode(util::xml::data_node &node)
{
WindowQt::saveConfigurationToNode(node);
@@ -105,6 +119,8 @@ void BreakpointsWindow::saveConfigurationToNode(util::xml::data_node &node)
break;
}
}
+
+ m_breakpointsView->saveConfigurationToNode(node);
}
@@ -136,25 +152,4 @@ void BreakpointsWindow::typeChanged(QAction* changedTo)
layout->addWidget(m_breakpointsView);
}
-
-
-//=========================================================================
-// BreakpointsWindowQtConfig
-//=========================================================================
-void BreakpointsWindowQtConfig::applyToQWidget(QWidget* widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- BreakpointsWindow *window = dynamic_cast<BreakpointsWindow *>(widget);
-
- QActionGroup *typeGroup = window->findChild<QActionGroup *>("typegroup");
- typeGroup->actions()[m_bwType]->trigger();
-}
-
-
-void BreakpointsWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- m_bwType = node.get_attribute_int(ATTR_WINDOW_POINTS_TYPE, m_bwType);
-}
-
} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/breakpointswindow.h b/src/osd/modules/debugger/qt/breakpointswindow.h
index 262d416ceff..0a07b4facfb 100644
--- a/src/osd/modules/debugger/qt/breakpointswindow.h
+++ b/src/osd/modules/debugger/qt/breakpointswindow.h
@@ -17,9 +17,11 @@ class BreakpointsWindow : public WindowQt
Q_OBJECT
public:
- BreakpointsWindow(running_machine &machine, QWidget *parent = nullptr);
+ BreakpointsWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~BreakpointsWindow();
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
+
protected:
virtual void saveConfigurationToNode(util::xml::data_node &node) override;
@@ -31,28 +33,6 @@ private:
DebuggerView *m_breakpointsView;
};
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class BreakpointsWindowQtConfig : public WindowQtConfig
-{
-public:
- BreakpointsWindowQtConfig() :
- WindowQtConfig(WINDOW_TYPE_POINTS_VIEWER),
- m_bwType(0)
- {
- }
-
- ~BreakpointsWindowQtConfig() {}
-
- // Settings
- int m_bwType;
-
- void applyToQWidget(QWidget *widget);
- void recoverFromXmlNode(util::xml::data_node const &node);
-};
-
} // namespace osd::debugger::qt
#endif // MAME_DEBUGGER_QT_BREAKPOINTSWINDOW_H
diff --git a/src/osd/modules/debugger/qt/dasmwindow.cpp b/src/osd/modules/debugger/qt/dasmwindow.cpp
index dd7677516eb..d528be04d14 100644
--- a/src/osd/modules/debugger/qt/dasmwindow.cpp
+++ b/src/osd/modules/debugger/qt/dasmwindow.cpp
@@ -10,6 +10,7 @@
#include "util/xmlfile.h"
+#include <QtGui/QKeyEvent>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QAction>
@@ -19,8 +20,9 @@
namespace osd::debugger::qt {
-DasmWindow::DasmWindow(running_machine &machine, QWidget *parent) :
- WindowQt(machine, nullptr)
+DasmWindow::DasmWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr),
+ m_inputHistory()
{
setWindowTitle("Debug: Disassembly View");
@@ -41,6 +43,8 @@ DasmWindow::DasmWindow(running_machine &machine, QWidget *parent) :
// The input edit
m_inputEdit = new QLineEdit(topSubFrame);
connect(m_inputEdit, &QLineEdit::returnPressed, this, &DasmWindow::expressionSubmitted);
+ connect(m_inputEdit, &QLineEdit::textEdited, this, &DasmWindow::expressionEdited);
+ m_inputEdit->installEventFilter(this);
// The cpu combo box
m_cpuComboBox = new QComboBox(topSubFrame);
@@ -124,6 +128,39 @@ DasmWindow::~DasmWindow()
}
+void DasmWindow::restoreConfiguration(util::xml::data_node const &node)
+{
+ WindowQt::restoreConfiguration(node);
+
+ debug_view_disasm &dasmview = *m_dasmView->view<debug_view_disasm>();
+
+ auto const cpu = node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_CPU, m_dasmView->sourceIndex());
+ if ((0 <= cpu) && (m_cpuComboBox->count() > cpu))
+ m_cpuComboBox->setCurrentIndex(cpu);
+
+ auto const rightbar = node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
+ QActionGroup *const rightBarGroup = findChild<QActionGroup *>("rightbargroup");
+ for (QAction *action : rightBarGroup->actions())
+ {
+ if (action->data().toInt() == rightbar)
+ {
+ action->trigger();
+ break;
+ }
+ }
+
+ util::xml::data_node const *const expression = node.get_child(NODE_WINDOW_EXPRESSION);
+ if (expression && expression->get_value())
+ {
+ m_inputEdit->setText(QString::fromUtf8(expression->get_value()));
+ expressionSubmitted();
+ }
+
+ m_dasmView->restoreConfigurationFromNode(node);
+ m_inputHistory.restoreConfigurationFromNode(node);
+}
+
+
void DasmWindow::saveConfigurationToNode(util::xml::data_node &node)
{
WindowQt::saveConfigurationToNode(node);
@@ -134,6 +171,53 @@ void DasmWindow::saveConfigurationToNode(util::xml::data_node &node)
node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_CPU, m_dasmView->sourceIndex());
node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
node.add_child(NODE_WINDOW_EXPRESSION, dasmview.expression());
+
+ m_dasmView->saveConfigurationToNode(node);
+ m_inputHistory.saveConfigurationToNode(node);
+}
+
+
+// Used to intercept the user hitting the up arrow in the input widget
+bool DasmWindow::eventFilter(QObject *obj, QEvent *event)
+{
+ // Only filter keypresses
+ if (event->type() != QEvent::KeyPress)
+ return QObject::eventFilter(obj, event);
+
+ QKeyEvent const &keyEvent = *static_cast<QKeyEvent *>(event);
+
+ // Catch up & down keys
+ if (keyEvent.key() == Qt::Key_Escape)
+ {
+ m_inputEdit->setText(QString::fromUtf8(m_dasmView->view<debug_view_disasm>()->expression()));
+ m_inputEdit->selectAll();
+ m_inputHistory.reset();
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Up)
+ {
+ QString const *const hist = m_inputHistory.previous(m_inputEdit->text());
+ if (hist)
+ {
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
+ }
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Down)
+ {
+ QString const *const hist = m_inputHistory.next(m_inputEdit->text());
+ if (hist)
+ {
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
+ }
+ return true;
+ }
+ else
+ {
+ return QObject::eventFilter(obj, event);
+ }
}
@@ -150,8 +234,18 @@ void DasmWindow::cpuChanged(int index)
void DasmWindow::expressionSubmitted()
{
const QString expression = m_inputEdit->text();
- m_dasmView->view<debug_view_disasm>()->set_expression(expression.toLocal8Bit().data());
- m_dasmView->viewport()->update();
+ m_dasmView->view<debug_view_disasm>()->set_expression(expression.toUtf8().data());
+ m_inputEdit->selectAll();
+
+ // Add history
+ if (!expression.isEmpty())
+ m_inputHistory.add(expression);
+}
+
+
+void DasmWindow::expressionEdited(QString const &text)
+{
+ m_inputHistory.edit();
}
@@ -181,8 +275,6 @@ void DasmWindow::toggleBreakpointAtCursor(bool changedTo)
m_machine.debug_view().update_all();
m_machine.debugger().refresh_display();
}
-
- refreshAll();
}
@@ -205,8 +297,6 @@ void DasmWindow::enableBreakpointAtCursor(bool changedTo)
m_machine.debugger().refresh_display();
}
}
-
- refreshAll();
}
@@ -284,34 +374,4 @@ void DasmWindow::setToCurrentCpu()
}
}
-
-//=========================================================================
-// DasmWindowQtConfig
-//=========================================================================
-
-void DasmWindowQtConfig::applyToQWidget(QWidget *widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- DasmWindow *window = dynamic_cast<DasmWindow *>(widget);
- QComboBox *cpu = window->findChild<QComboBox *>("cpu");
- cpu->setCurrentIndex(m_cpu);
-
- QActionGroup *const rightBarGroup = window->findChild<QActionGroup *>("rightbargroup");
- for (QAction *action : rightBarGroup->actions())
- {
- if (action->data().toInt() == m_rightBar)
- {
- action->trigger();
- break;
- }
- }
-}
-
-void DasmWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- m_cpu = node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_CPU, m_cpu);
- m_rightBar = node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, m_rightBar);
-}
-
} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/dasmwindow.h b/src/osd/modules/debugger/qt/dasmwindow.h
index fda4db188a3..df3fc0699a8 100644
--- a/src/osd/modules/debugger/qt/dasmwindow.h
+++ b/src/osd/modules/debugger/qt/dasmwindow.h
@@ -22,15 +22,21 @@ class DasmWindow : public WindowQt
Q_OBJECT
public:
- DasmWindow(running_machine &machine, QWidget *parent = nullptr);
+ DasmWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~DasmWindow();
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
+
protected:
virtual void saveConfigurationToNode(util::xml::data_node &node) override;
+ // Used to intercept the user hitting the up arrow in the input widget
+ virtual bool eventFilter(QObject *obj, QEvent *event) override;
+
private slots:
void cpuChanged(int index);
void expressionSubmitted();
+ void expressionEdited(QString const &text);
void toggleBreakpointAtCursor(bool changedTo);
void enableBreakpointAtCursor(bool changedTo);
@@ -52,30 +58,9 @@ private:
QAction *m_breakpointToggleAct;
QAction *m_breakpointEnableAct;
QAction *m_runToCursorAct;
-};
-
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class DasmWindowQtConfig : public WindowQtConfig
-{
-public:
- DasmWindowQtConfig() :
- WindowQtConfig(WINDOW_TYPE_DISASSEMBLY_VIEWER),
- m_cpu(0),
- m_rightBar(0)
- {
- }
-
- ~DasmWindowQtConfig() {}
-
- // Settings
- int m_cpu;
- int m_rightBar;
- void applyToQWidget(QWidget *widget);
- void recoverFromXmlNode(util::xml::data_node const &node);
+ // Expression history
+ CommandHistory m_inputHistory;
};
} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/debuggerview.cpp b/src/osd/modules/debugger/qt/debuggerview.cpp
index 3d89670c3af..e50659fcf3a 100644
--- a/src/osd/modules/debugger/qt/debuggerview.cpp
+++ b/src/osd/modules/debugger/qt/debuggerview.cpp
@@ -3,8 +3,12 @@
#include "emu.h"
#include "debuggerview.h"
+#include "../xmlconfig.h"
+
#include "modules/lib/osdobj_common.h"
+#include "xmlfile.h"
+
#include <QtCore/QMimeData>
#include <QtGui/QClipboard>
#include <QtGui/QKeyEvent>
@@ -190,9 +194,43 @@ void DebuggerView::paintEvent(QPaintEvent *event)
}
}
+
+void DebuggerView::restoreConfigurationFromNode(util::xml::data_node const &node)
+{
+ if (m_view->cursor_supported())
+ {
+ util::xml::data_node const *const selection = node.get_child(NODE_WINDOW_SELECTION);
+ if (selection)
+ {
+ debug_view_xy pos = m_view->cursor_position();
+ m_view->set_cursor_visible(0 != selection->get_attribute_int(ATTR_SELECTION_CURSOR_VISIBLE, m_view->cursor_visible() ? 1 : 0));
+ selection->get_attribute_int(ATTR_SELECTION_CURSOR_X, pos.x);
+ selection->get_attribute_int(ATTR_SELECTION_CURSOR_Y, pos.y);
+ m_view->set_cursor_position(pos);
+ }
+ }
+}
+
+
+void DebuggerView::saveConfigurationToNode(util::xml::data_node &node)
+{
+ if (m_view->cursor_supported())
+ {
+ util::xml::data_node *const selection = node.add_child(NODE_WINDOW_SELECTION, nullptr);
+ if (selection)
+ {
+ debug_view_xy const pos = m_view->cursor_position();
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_VISIBLE, m_view->cursor_visible() ? 1 : 0);
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_X, pos.x);
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_Y, pos.y);
+ }
+ }
+}
+
+
void DebuggerView::keyPressEvent(QKeyEvent* event)
{
- if (m_view == nullptr)
+ if (!m_view)
return QWidget::keyPressEvent(event);
Qt::KeyboardModifiers keyMods = QApplication::keyboardModifiers();
diff --git a/src/osd/modules/debugger/qt/debuggerview.h b/src/osd/modules/debugger/qt/debuggerview.h
index 6a78ec7d672..f62c9de877a 100644
--- a/src/osd/modules/debugger/qt/debuggerview.h
+++ b/src/osd/modules/debugger/qt/debuggerview.h
@@ -29,6 +29,9 @@ public:
template <typename T> T *view() { return downcast<T *>(m_view); }
int sourceIndex() const;
+ virtual void restoreConfigurationFromNode(util::xml::data_node const &node);
+ virtual void saveConfigurationToNode(util::xml::data_node &node);
+
signals:
void updated();
diff --git a/src/osd/modules/debugger/qt/deviceinformationwindow.cpp b/src/osd/modules/debugger/qt/deviceinformationwindow.cpp
index 83fad49e418..2e06d8fb1ed 100644
--- a/src/osd/modules/debugger/qt/deviceinformationwindow.cpp
+++ b/src/osd/modules/debugger/qt/deviceinformationwindow.cpp
@@ -12,8 +12,8 @@
namespace osd::debugger::qt {
-DeviceInformationWindow::DeviceInformationWindow(running_machine &machine, device_t *device, QWidget *parent) :
- WindowQt(machine, nullptr),
+DeviceInformationWindow::DeviceInformationWindow(DebuggerQt &debugger, device_t *device, QWidget *parent) :
+ WindowQt(debugger, nullptr),
m_device(device)
{
if (parent)
@@ -32,6 +32,15 @@ DeviceInformationWindow::~DeviceInformationWindow()
}
+void DeviceInformationWindow::restoreConfiguration(util::xml::data_node const &node)
+{
+ WindowQt::restoreConfiguration(node);
+
+ auto const tag = node.get_attribute_string(ATTR_WINDOW_DEVICE_TAG, ":");
+ set_device(tag);
+}
+
+
void DeviceInformationWindow::saveConfigurationToNode(util::xml::data_node &node)
{
WindowQt::saveConfigurationToNode(node);
@@ -114,23 +123,4 @@ void DeviceInformationWindow::set_device(const char *tag)
fill_device_information();
}
-
-//=========================================================================
-// DeviceInformationWindowQtConfig
-//=========================================================================
-
-void DeviceInformationWindowQtConfig::applyToQWidget(QWidget *widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- DeviceInformationWindow *window = dynamic_cast<DeviceInformationWindow *>(widget);
- window->set_device(m_device_tag.c_str());
-}
-
-
-void DeviceInformationWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- m_device_tag = node.get_attribute_string(ATTR_WINDOW_DEVICE_TAG, ":");
-}
-
} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/deviceinformationwindow.h b/src/osd/modules/debugger/qt/deviceinformationwindow.h
index 68ab910fe48..e036a76e782 100644
--- a/src/osd/modules/debugger/qt/deviceinformationwindow.h
+++ b/src/osd/modules/debugger/qt/deviceinformationwindow.h
@@ -18,11 +18,13 @@ class DeviceInformationWindow : public WindowQt
Q_OBJECT
public:
- DeviceInformationWindow(running_machine &machine, device_t *device = nullptr, QWidget* parent=nullptr);
+ DeviceInformationWindow(DebuggerQt &debugger, device_t *device = nullptr, QWidget* parent=nullptr);
virtual ~DeviceInformationWindow();
void set_device(const char *tag);
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
+
protected:
virtual void saveConfigurationToNode(util::xml::data_node &node) override;
@@ -32,28 +34,6 @@ private:
void fill_device_information();
};
-
-
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class DeviceInformationWindowQtConfig : public WindowQtConfig
-{
-public:
- std::string m_device_tag;
-
- DeviceInformationWindowQtConfig() :
- WindowQtConfig(WINDOW_TYPE_DEVICE_INFO_VIEWER)
- {
- }
-
- ~DeviceInformationWindowQtConfig() {}
-
- void applyToQWidget(QWidget *widget);
- void recoverFromXmlNode(util::xml::data_node const &node);
-};
-
} // namespace osd::debugger::qt
#endif // MAME_DEBUGGER_QT_DEVICEINFORMATIONWINDOW_H
diff --git a/src/osd/modules/debugger/qt/deviceswindow.cpp b/src/osd/modules/debugger/qt/deviceswindow.cpp
index 8d51ecccf01..2c39c8cb0e8 100644
--- a/src/osd/modules/debugger/qt/deviceswindow.cpp
+++ b/src/osd/modules/debugger/qt/deviceswindow.cpp
@@ -113,9 +113,9 @@ int DevicesWindowModel::columnCount(const QModelIndex &parent) const
-DevicesWindow::DevicesWindow(running_machine &machine, QWidget *parent) :
- WindowQt(machine, nullptr),
- m_devices_model(machine)
+DevicesWindow::DevicesWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr),
+ m_devices_model(debugger.machine())
{
m_selected_device = nullptr;
@@ -154,7 +154,7 @@ void DevicesWindow::currentRowChanged(const QModelIndex &current, const QModelIn
void DevicesWindow::activated(const QModelIndex &index)
{
device_t *dev = static_cast<device_t *>(index.internalPointer());
- (new DeviceInformationWindow(m_machine, dev, this))->show();
+ (new DeviceInformationWindow(m_debugger, dev, this))->show();
}
@@ -165,22 +165,4 @@ void DevicesWindow::saveConfigurationToNode(util::xml::data_node &node)
node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_DEVICES_VIEWER);
}
-
-
-//=========================================================================
-// DevicesWindowQtConfig
-//=========================================================================
-
-void DevicesWindowQtConfig::applyToQWidget(QWidget *widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- // DevicesWindow *window = dynamic_cast<DevicesWindow *>(widget);
-}
-
-
-void DevicesWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
-}
-
} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/deviceswindow.h b/src/osd/modules/debugger/qt/deviceswindow.h
index 8fe5b7a82c2..d337817fac0 100644
--- a/src/osd/modules/debugger/qt/deviceswindow.h
+++ b/src/osd/modules/debugger/qt/deviceswindow.h
@@ -44,7 +44,7 @@ class DevicesWindow : public WindowQt
Q_OBJECT
public:
- DevicesWindow(running_machine &machine, QWidget *parent = nullptr);
+ DevicesWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~DevicesWindow();
public slots:
@@ -60,28 +60,6 @@ private:
device_t *m_selected_device;
};
-
-
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class DevicesWindowQtConfig : public WindowQtConfig
-{
-public:
- DevicesWindowQtConfig() :
- WindowQtConfig(WINDOW_TYPE_DEVICES_VIEWER)
- {
- }
-
- ~DevicesWindowQtConfig() {}
-
- void buildFromQWidget(QWidget *widget);
- void applyToQWidget(QWidget *widget);
- void addToXmlDataNode(util::xml::data_node &node) const;
- void recoverFromXmlNode(util::xml::data_node const &node);
-};
-
} // namespace osd::debugger::qt
#endif // MAME_DEBUGGER_QT_DEVICESWINDOW_H
diff --git a/src/osd/modules/debugger/qt/logwindow.cpp b/src/osd/modules/debugger/qt/logwindow.cpp
index 669d25081d6..dfbe947caca 100644
--- a/src/osd/modules/debugger/qt/logwindow.cpp
+++ b/src/osd/modules/debugger/qt/logwindow.cpp
@@ -14,8 +14,8 @@
namespace osd::debugger::qt {
-LogWindow::LogWindow(running_machine &machine, QWidget *parent) :
- WindowQt(machine, nullptr)
+LogWindow::LogWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr)
{
setWindowTitle("Debug: Machine Log");
@@ -48,27 +48,21 @@ LogWindow::~LogWindow()
}
-void LogWindow::saveConfigurationToNode(util::xml::data_node &node)
+void LogWindow::restoreConfiguration(util::xml::data_node const &node)
{
- WindowQt::saveConfigurationToNode(node);
+ WindowQt::restoreConfiguration(node);
- node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_ERROR_LOG_VIEWER);
+ m_logView->restoreConfigurationFromNode(node);
}
-//=========================================================================
-// LogWindowQtConfig
-//=========================================================================
-
-void LogWindowQtConfig::applyToQWidget(QWidget *widget)
+void LogWindow::saveConfigurationToNode(util::xml::data_node &node)
{
- WindowQtConfig::applyToQWidget(widget);
-}
+ WindowQt::saveConfigurationToNode(node);
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_ERROR_LOG_VIEWER);
-void LogWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
+ m_logView->saveConfigurationToNode(node);
}
} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/logwindow.h b/src/osd/modules/debugger/qt/logwindow.h
index 813add22749..f85d490ea75 100644
--- a/src/osd/modules/debugger/qt/logwindow.h
+++ b/src/osd/modules/debugger/qt/logwindow.h
@@ -19,9 +19,11 @@ class LogWindow : public WindowQt
Q_OBJECT
public:
- LogWindow(running_machine &machine, QWidget *parent = nullptr);
+ LogWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~LogWindow();
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
+
protected:
virtual void saveConfigurationToNode(util::xml::data_node &node) override;
@@ -30,24 +32,6 @@ private:
DebuggerView *m_logView;
};
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class LogWindowQtConfig : public WindowQtConfig
-{
-public:
- LogWindowQtConfig() :
- WindowQtConfig(WINDOW_TYPE_ERROR_LOG_VIEWER)
- {
- }
-
- ~LogWindowQtConfig() {}
-
- void applyToQWidget(QWidget *widget);
- void recoverFromXmlNode(util::xml::data_node const &node);
-};
-
} // namespace osd::debugger::qt
#endif // MAME_DEBUGGER_QT_LOGWINDOW_H
diff --git a/src/osd/modules/debugger/qt/mainwindow.cpp b/src/osd/modules/debugger/qt/mainwindow.cpp
index a418a543ace..92be2c04b31 100644
--- a/src/osd/modules/debugger/qt/mainwindow.cpp
+++ b/src/osd/modules/debugger/qt/mainwindow.cpp
@@ -21,9 +21,8 @@
namespace osd::debugger::qt {
-MainWindow::MainWindow(running_machine &machine, QWidget *parent) :
- WindowQt(machine, nullptr),
- m_historyIndex(0),
+MainWindow::MainWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr),
m_inputHistory(),
m_exiting(false)
{
@@ -37,6 +36,7 @@ MainWindow::MainWindow(running_machine &machine, QWidget *parent) :
// The input line
m_inputEdit = new QLineEdit(mainWindowFrame);
connect(m_inputEdit, &QLineEdit::returnPressed, this, &MainWindow::executeCommandSlot);
+ connect(m_inputEdit, &QLineEdit::textEdited, this, &MainWindow::commandEditedSlot);
m_inputEdit->installEventFilter(this);
@@ -154,6 +154,30 @@ void MainWindow::setProcessor(device_t *processor)
}
+void MainWindow::restoreConfiguration(util::xml::data_node const &node)
+{
+ WindowQt::restoreConfiguration(node);
+
+ debug_view_disasm &dasmview = *m_dasmFrame->view()->view<debug_view_disasm>();
+
+ restoreState(QByteArray::fromPercentEncoding(node.get_attribute_string("qtwindowstate", "")));
+
+ auto const rightbar = node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
+ QActionGroup *const rightBarGroup = findChild<QActionGroup *>("rightbargroup");
+ for (QAction *action : rightBarGroup->actions())
+ {
+ if (action->data().toInt() == rightbar)
+ {
+ action->trigger();
+ break;
+ }
+ }
+
+ m_dasmFrame->view()->restoreConfigurationFromNode(node);
+ m_inputHistory.restoreConfigurationFromNode(node);
+}
+
+
void MainWindow::saveConfigurationToNode(util::xml::data_node &node)
{
WindowQt::saveConfigurationToNode(node);
@@ -163,6 +187,9 @@ void MainWindow::saveConfigurationToNode(util::xml::data_node &node)
debug_view_disasm &dasmview = *m_dasmFrame->view()->view<debug_view_disasm>();
node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
node.set_attribute("qtwindowstate", saveState().toPercentEncoding().data());
+
+ m_dasmFrame->view()->saveConfigurationToNode(node);
+ m_inputHistory.saveConfigurationToNode(node);
}
@@ -182,46 +209,47 @@ void MainWindow::closeEvent(QCloseEvent *event)
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
// Only filter keypresses
- QKeyEvent *keyEvent = nullptr;
- if (event->type() == QEvent::KeyPress)
- keyEvent = static_cast<QKeyEvent*>(event);
- else
+ if (event->type() != QEvent::KeyPress)
return QObject::eventFilter(obj, event);
+ QKeyEvent const &keyEvent = *static_cast<QKeyEvent *>(event);
+
// Catch up & down keys
- if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)
+ if (keyEvent.key() == Qt::Key_Escape)
{
- if (keyEvent->key() == Qt::Key_Up)
- {
- if (m_historyIndex > 0)
- m_historyIndex--;
- }
- else if (keyEvent->key() == Qt::Key_Down)
- {
- if (m_historyIndex < m_inputHistory.size())
- m_historyIndex++;
- }
-
- // Populate the input edit or clear it if you're at the end
- if (m_historyIndex == m_inputHistory.size())
+ m_inputEdit->clear();
+ m_inputHistory.reset();
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Up)
+ {
+ QString const *const hist = m_inputHistory.previous(m_inputEdit->text());
+ if (hist)
{
- m_inputEdit->setText("");
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
}
- else
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Down)
+ {
+ QString const *const hist = m_inputHistory.next(m_inputEdit->text());
+ if (hist)
{
- m_inputEdit->setText(m_inputHistory[m_historyIndex]);
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
}
+ return true;
}
- else if (keyEvent->key() == Qt::Key_Enter)
+ else if (keyEvent.key() == Qt::Key_Enter)
{
executeCommand(false);
+ return true;
}
else
{
return QObject::eventFilter(obj, event);
}
-
- return true;
}
@@ -243,9 +271,9 @@ void MainWindow::toggleBreakpointAtCursor(bool changedTo)
else
command = string_format("bpclear 0x%X", bp->index());
m_machine.debugger().console().execute_command(command, true);
+ m_machine.debug_view().update_all();
+ m_machine.debugger().refresh_display();
}
-
- refreshAll();
}
@@ -265,10 +293,10 @@ void MainWindow::enableBreakpointAtCursor(bool changedTo)
int32_t const bpindex = bp->index();
std::string command = string_format(bp->enabled() ? "bpdisable 0x%X" : "bpenable 0x%X", bpindex);
m_machine.debugger().console().execute_command(command, true);
+ m_machine.debug_view().update_all();
+ m_machine.debugger().refresh_display();
}
}
-
- refreshAll();
}
@@ -296,33 +324,35 @@ void MainWindow::executeCommandSlot()
executeCommand(true);
}
-void MainWindow::executeCommand(bool withClear)
+void MainWindow::commandEditedSlot(QString const &text)
{
- QString command = m_inputEdit->text();
+ m_inputHistory.edit();
+}
- // A blank command is a "silent step"
+void MainWindow::executeCommand(bool withClear)
+{
+ QString const command = m_inputEdit->text();
if (command == "")
{
+ // A blank command is a "silent step"
m_machine.debugger().console().get_visible_cpu()->debug()->single_step();
- return;
+ m_inputHistory.reset();
}
+ else
+ {
+ // Send along the command
+ m_machine.debugger().console().execute_command(command.toUtf8().data(), true);
- // Send along the command
- m_machine.debugger().console().execute_command(command.toLocal8Bit().data(), true);
-
- // Add history & set the index to be the top of the stack
- addToHistory(command);
+ // Add history
+ m_inputHistory.add(command);
- // Clear out the text and reset the history pointer only if asked
- if (withClear)
- {
- m_inputEdit->clear();
- m_historyIndex = m_inputHistory.size();
+ // Clear out the text and reset the history pointer only if asked
+ if (withClear)
+ {
+ m_inputEdit->clear();
+ m_inputHistory.edit();
+ }
}
-
- // Refresh
- m_consoleView->viewport()->update();
- refreshAll();
}
@@ -335,7 +365,6 @@ void MainWindow::mountImage(bool changedTo)
if (!img)
{
m_machine.debugger().console().printf("Something is wrong with the mount menu.\n");
- refreshAll();
return;
}
@@ -349,7 +378,6 @@ void MainWindow::mountImage(bool changedTo)
if (img->load(filename.toUtf8().data()) != image_init_result::PASS)
{
m_machine.debugger().console().printf("Image could not be mounted.\n");
- refreshAll();
return;
}
@@ -365,7 +393,6 @@ void MainWindow::mountImage(bool changedTo)
parentMenuItem->setTitle(newTitle);
m_machine.debugger().console().printf("Image %s mounted successfully.\n", filename.toUtf8().data());
- refreshAll();
}
@@ -389,7 +416,6 @@ void MainWindow::unmountImage(bool changedTo)
parentMenuItem->setTitle(newTitle);
m_machine.debugger().console().printf("Image successfully unmounted.\n");
- refreshAll();
}
@@ -429,21 +455,10 @@ void MainWindow::debugActClose()
}
-void MainWindow::addToHistory(const QString& command)
+void MainWindow::debuggerExit()
{
- if (command == "")
- return;
-
- // Always push back when there is no previous history
- if (m_inputHistory.empty())
- {
- m_inputHistory.push_back(m_inputEdit->text());
- return;
- }
-
- // If there is previous history, make sure it's not what you just executed
- if (m_inputHistory.back() != m_inputEdit->text())
- m_inputHistory.push_back(m_inputEdit->text());
+ m_exiting = true;
+ close();
}
@@ -481,35 +496,6 @@ void MainWindow::createImagesMenu()
}
-//=========================================================================
-// MainWindowQtConfig
-//=========================================================================
-void MainWindowQtConfig::applyToQWidget(QWidget *widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- MainWindow *window = dynamic_cast<MainWindow *>(widget);
- window->restoreState(m_windowState);
-
- QActionGroup *const rightBarGroup = window->findChild<QActionGroup*>("rightbargroup");
- for (QAction *action : rightBarGroup->actions())
- {
- if (action->data().toInt() == m_rightBar)
- {
- action->trigger();
- break;
- }
- }
-}
-
-
-void MainWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- const char* state = node.get_attribute_string("qtwindowstate", "");
- m_windowState = QByteArray::fromPercentEncoding(state);
- m_rightBar = node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, m_rightBar);
-}
-
DasmDockWidget::~DasmDockWidget()
{
}
diff --git a/src/osd/modules/debugger/qt/mainwindow.h b/src/osd/modules/debugger/qt/mainwindow.h
index 919c016704c..762874b6aee 100644
--- a/src/osd/modules/debugger/qt/mainwindow.h
+++ b/src/osd/modules/debugger/qt/mainwindow.h
@@ -14,7 +14,7 @@
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QComboBox>
-#include <vector>
+#include <deque>
namespace osd::debugger::qt {
@@ -31,21 +31,21 @@ class MainWindow : public WindowQt
Q_OBJECT
public:
- MainWindow(running_machine &machine, QWidget *parent = nullptr);
+ MainWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~MainWindow();
void setProcessor(device_t *processor);
- void setExiting() { m_exiting = true; }
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
protected:
virtual void saveConfigurationToNode(util::xml::data_node &node) override;
// Used to intercept the user clicking 'X' in the upper corner
- void closeEvent(QCloseEvent *event);
+ virtual void closeEvent(QCloseEvent *event) override;
// Used to intercept the user hitting the up arrow in the input widget
- bool eventFilter(QObject *obj, QEvent *event);
+ virtual bool eventFilter(QObject *obj, QEvent *event) override;
private slots:
void toggleBreakpointAtCursor(bool changedTo);
@@ -54,6 +54,7 @@ private slots:
void rightBarChanged(QAction *changedTo);
void executeCommandSlot();
+ void commandEditedSlot(QString const &text);
void mountImage(bool changedTo);
void unmountImage(bool changedTo);
@@ -61,12 +62,12 @@ private slots:
void dasmViewUpdated();
// Closing the main window hides the debugger and runs the emulated system
- void debugActClose();
+ virtual void debugActClose() override;
+ virtual void debuggerExit() override;
private:
void createImagesMenu();
- void addToHistory(const QString& command);
void executeCommand(bool withClear);
// Widgets and docks
@@ -81,8 +82,7 @@ private:
QAction *m_runToCursorAct;
// Terminal history
- int m_historyIndex;
- std::vector<QString> m_inputHistory;
+ CommandHistory m_inputHistory;
bool m_exiting;
};
@@ -158,29 +158,6 @@ private:
DebuggerView *m_processorView;
};
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class MainWindowQtConfig : public WindowQtConfig
-{
-public:
- MainWindowQtConfig() :
- WindowQtConfig(WINDOW_TYPE_CONSOLE),
- m_rightBar(0),
- m_windowState()
- {}
-
- ~MainWindowQtConfig() {}
-
- // Settings
- int m_rightBar;
- QByteArray m_windowState;
-
- void applyToQWidget(QWidget *widget);
- void recoverFromXmlNode(util::xml::data_node const &node);
-};
-
} // namespace osd::debugger::qt
#endif // MAME_DEBUGGER_QT_MAINWINDOW_H
diff --git a/src/osd/modules/debugger/qt/memorywindow.cpp b/src/osd/modules/debugger/qt/memorywindow.cpp
index 0aed1a750ce..25e38e6ab99 100644
--- a/src/osd/modules/debugger/qt/memorywindow.cpp
+++ b/src/osd/modules/debugger/qt/memorywindow.cpp
@@ -10,6 +10,7 @@
#include "util/xmlfile.h"
#include <QtGui/QClipboard>
+#include <QtGui/QKeyEvent>
#include <QtGui/QMouseEvent>
#include <QtWidgets/QActionGroup>
#include <QtWidgets/QApplication>
@@ -27,8 +28,9 @@
namespace osd::debugger::qt {
-MemoryWindow::MemoryWindow(running_machine &machine, QWidget *parent) :
- WindowQt(machine, nullptr)
+MemoryWindow::MemoryWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr),
+ m_inputHistory()
{
setWindowTitle("Debug: Memory View");
@@ -49,6 +51,8 @@ MemoryWindow::MemoryWindow(running_machine &machine, QWidget *parent) :
// The input edit
m_inputEdit = new QLineEdit(topSubFrame);
connect(m_inputEdit, &QLineEdit::returnPressed, this, &MemoryWindow::expressionSubmitted);
+ connect(m_inputEdit, &QLineEdit::textEdited, this, &MemoryWindow::expressionEdited);
+ m_inputEdit->installEventFilter(this);
// The memory space combo box
m_memoryComboBox = new QComboBox(topSubFrame);
@@ -219,6 +223,71 @@ MemoryWindow::~MemoryWindow()
}
+void MemoryWindow::restoreConfiguration(util::xml::data_node const &node)
+{
+ WindowQt::restoreConfiguration(node);
+
+ debug_view_memory &memView = *m_memTable->view<debug_view_memory>();
+
+ auto const region = node.get_attribute_int(ATTR_WINDOW_MEMORY_REGION, m_memTable->sourceIndex());
+ if ((0 <= region) && (m_memoryComboBox->count() > region))
+ m_memoryComboBox->setCurrentIndex(region);
+
+ auto const reverse = node.get_attribute_int(ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, memView.reverse() ? 1 : 0);
+ if (memView.reverse() != bool(reverse))
+ {
+ memView.set_reverse(bool(reverse));
+ findChild<QAction *>("reverse")->setChecked(bool(reverse));
+ }
+
+ auto const mode = node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_MODE, memView.physical() ? 1 : 0);
+ QActionGroup *const addressGroup = findChild<QActionGroup *>("addressgroup");
+ for (QAction *action : addressGroup->actions())
+ {
+ if (action->data().toBool() == mode)
+ {
+ action->trigger();
+ break;
+ }
+ }
+
+ auto const radix = node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_RADIX, memView.address_radix());
+ QActionGroup *const radixGroup = findChild<QActionGroup *>("radixgroup");
+ for (QAction *action : radixGroup->actions())
+ {
+ if (action->data().toInt() == radix)
+ {
+ action->trigger();
+ break;
+ }
+ }
+
+ auto const format = node.get_attribute_int(ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memView.get_data_format()));
+ QActionGroup *const dataFormat = findChild<QActionGroup *>("dataformat");
+ for (QAction *action : dataFormat->actions())
+ {
+ if (action->data().toInt() == format)
+ {
+ action->trigger();
+ break;
+ }
+ }
+
+ auto const chunks = node.get_attribute_int(ATTR_WINDOW_MEMORY_ROW_CHUNKS, memView.chunks_per_row());
+ memView.set_chunks_per_row(chunks);
+
+ util::xml::data_node const *const expression = node.get_child(NODE_WINDOW_EXPRESSION);
+ if (expression && expression->get_value())
+ {
+ m_inputEdit->setText(QString::fromUtf8(expression->get_value()));
+ expressionSubmitted();
+ }
+
+ m_memTable->restoreConfigurationFromNode(node);
+ m_inputHistory.restoreConfigurationFromNode(node);
+}
+
+
void MemoryWindow::saveConfigurationToNode(util::xml::data_node &node)
{
WindowQt::saveConfigurationToNode(node);
@@ -233,6 +302,9 @@ void MemoryWindow::saveConfigurationToNode(util::xml::data_node &node)
node.set_attribute_int(ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memView.get_data_format()));
node.set_attribute_int(ATTR_WINDOW_MEMORY_ROW_CHUNKS, memView.chunks_per_row());
node.add_child(NODE_WINDOW_EXPRESSION, memView.expression());
+
+ m_memTable->saveConfigurationToNode(node);
+ m_inputHistory.saveConfigurationToNode(node);
}
@@ -256,7 +328,7 @@ void MemoryWindow::memoryRegionChanged(int index)
}
}
- QActionGroup *radixGroup = findChild<QActionGroup*>("radixgroup");
+ QActionGroup *radixGroup = findChild<QActionGroup *>("radixgroup");
for (QAction *action : radixGroup->actions())
{
if (action->data().toInt() == memView->address_radix())
@@ -269,21 +341,65 @@ void MemoryWindow::memoryRegionChanged(int index)
}
+// Used to intercept the user hitting the up arrow in the input widget
+bool MemoryWindow::eventFilter(QObject *obj, QEvent *event)
+{
+ // Only filter keypresses
+ if (event->type() != QEvent::KeyPress)
+ return QObject::eventFilter(obj, event);
+
+ QKeyEvent const &keyEvent = *static_cast<QKeyEvent *>(event);
+
+ // Catch up & down keys
+ if (keyEvent.key() == Qt::Key_Escape)
+ {
+ m_inputEdit->setText(QString::fromUtf8(m_memTable->view<debug_view_memory>()->expression()));
+ m_inputEdit->selectAll();
+ m_inputHistory.reset();
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Up)
+ {
+ QString const *const hist = m_inputHistory.previous(m_inputEdit->text());
+ if (hist)
+ {
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
+ }
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Down)
+ {
+ QString const *const hist = m_inputHistory.next(m_inputEdit->text());
+ if (hist)
+ {
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
+ }
+ return true;
+ }
+ else
+ {
+ return QObject::eventFilter(obj, event);
+ }
+}
+
+
void MemoryWindow::expressionSubmitted()
{
const QString expression = m_inputEdit->text();
- m_memTable->view<debug_view_memory>()->set_expression(expression.toLocal8Bit().data());
+ m_memTable->view<debug_view_memory>()->set_expression(expression.toUtf8().data());
+ m_inputEdit->selectAll();
- // Make the cursor pop
- m_memTable->view()->set_cursor_visible(true);
+ // Add history
+ if (!expression.isEmpty())
+ m_inputHistory.add(expression);
+}
- // Check where the cursor is and adjust the scroll accordingly
- debug_view_xy cursorPosition = m_memTable->view()->cursor_position();
- // TODO: check if the region is already visible?
- m_memTable->verticalScrollBar()->setValue(cursorPosition.y);
- m_memTable->update();
- m_memTable->viewport()->update();
+void MemoryWindow::expressionEdited(QString const &text)
+{
+ m_inputHistory.edit();
}
@@ -430,62 +546,4 @@ void DebuggerMemView::copyLastPc()
QApplication::clipboard()->setText(m_lastPc);
}
-
-//=========================================================================
-// MemoryWindowQtConfig
-//=========================================================================
-
-void MemoryWindowQtConfig::applyToQWidget(QWidget *widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- MemoryWindow *window = dynamic_cast<MemoryWindow *>(widget);
- QComboBox *memoryRegion = window->findChild<QComboBox *>("memoryregion");
- memoryRegion->setCurrentIndex(m_memoryRegion);
-
- QAction *reverse = window->findChild<QAction *>("reverse");
- if (m_reverse)
- reverse->trigger();
-
- QActionGroup *const addressGroup = window->findChild<QActionGroup*>("addressgroup");
- for (QAction *action : addressGroup->actions())
- {
- if (action->data().toBool() == m_addressMode)
- {
- action->trigger();
- break;
- }
- }
-
- QActionGroup *const radixGroup = window->findChild<QActionGroup*>("radixgroup");
- for (QAction *action : radixGroup->actions())
- {
- if (action->data().toInt() == m_addressRadix)
- {
- action->trigger();
- break;
- }
- }
-
- QActionGroup *const dataFormat = window->findChild<QActionGroup*>("dataformat");
- for (QAction *action : dataFormat->actions())
- {
- if (action->data().toInt() == m_dataFormat)
- {
- action->trigger();
- break;
- }
- }
-}
-
-
-void MemoryWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- m_memoryRegion = node.get_attribute_int(ATTR_WINDOW_MEMORY_REGION, m_memoryRegion);
- m_reverse = node.get_attribute_int(ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, m_reverse);
- m_addressMode = node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_MODE, m_addressMode);
- m_addressRadix = node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_RADIX, m_addressRadix);
- m_dataFormat = node.get_attribute_int(ATTR_WINDOW_MEMORY_DATA_FORMAT, m_dataFormat);
-}
-
} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/memorywindow.h b/src/osd/modules/debugger/qt/memorywindow.h
index 131afa3e027..ed5c5b30cb0 100644
--- a/src/osd/modules/debugger/qt/memorywindow.h
+++ b/src/osd/modules/debugger/qt/memorywindow.h
@@ -25,15 +25,22 @@ class MemoryWindow : public WindowQt
Q_OBJECT
public:
- MemoryWindow(running_machine &machine, QWidget *parent = nullptr);
+ MemoryWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~MemoryWindow();
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
+
protected:
virtual void saveConfigurationToNode(util::xml::data_node &node) override;
+ // Used to intercept the user hitting the up arrow in the input widget
+ virtual bool eventFilter(QObject *obj, QEvent *event) override;
+
private slots:
void memoryRegionChanged(int index);
void expressionSubmitted();
+ void expressionEdited(QString const &text);
+
void formatChanged(QAction *changedTo);
void addressChanged(QAction *changedTo);
void radixChanged(QAction *changedTo);
@@ -49,6 +56,9 @@ private:
QLineEdit *m_inputEdit;
QComboBox *m_memoryComboBox;
DebuggerMemView *m_memTable;
+
+ // Expression history
+ CommandHistory m_inputHistory;
};
@@ -76,36 +86,6 @@ private:
QString m_lastPc;
};
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class MemoryWindowQtConfig : public WindowQtConfig
-{
-public:
- MemoryWindowQtConfig() :
- WindowQtConfig(WINDOW_TYPE_MEMORY_VIEWER),
- m_reverse(0),
- m_addressMode(0),
- m_addressRadix(0),
- m_dataFormat(0),
- m_memoryRegion(0)
- {
- }
-
- ~MemoryWindowQtConfig() {}
-
- // Settings
- int m_reverse;
- int m_addressMode;
- int m_addressRadix;
- int m_dataFormat;
- int m_memoryRegion;
-
- void applyToQWidget(QWidget *widget);
- void recoverFromXmlNode(util::xml::data_node const &node);
-};
-
} // namespace osd::debugger::qt
#endif // MAME_DEBUGGER_QT_MEMORYWINDOW_H
diff --git a/src/osd/modules/debugger/qt/windowqt.cpp b/src/osd/modules/debugger/qt/windowqt.cpp
index 7538f1bc11f..783c5a24393 100644
--- a/src/osd/modules/debugger/qt/windowqt.cpp
+++ b/src/osd/modules/debugger/qt/windowqt.cpp
@@ -20,21 +20,24 @@
namespace osd::debugger::qt {
-bool WindowQt::s_refreshAll = false;
-bool WindowQt::s_hideAll = false;
-
-
// 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);
debugActOpenMemory->setShortcut(QKeySequence("Ctrl+M"));
@@ -133,9 +136,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);
@@ -145,7 +149,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);
@@ -155,7 +159,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);
@@ -165,7 +169,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);
@@ -175,7 +179,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);
@@ -191,7 +195,7 @@ void WindowQt::debugActRun()
void WindowQt::debugActRunAndHide()
{
m_machine.debugger().console().get_visible_cpu()->debug()->go();
- hideAll();
+ m_debugger.hideAll();
}
void WindowQt::debugActRunToNextCpu()
@@ -245,6 +249,27 @@ void WindowQt::debugActQuit()
m_machine.schedule_exit();
}
+void WindowQt::debuggerExit()
+{
+ close();
+}
+
+
+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)
{
@@ -263,23 +288,115 @@ void WindowQt::saveConfigurationToNode(util::xml::data_node &node)
}
-//=========================================================================
-// WindowQtConfig
-//=========================================================================
+CommandHistory::CommandHistory() :
+ m_history(),
+ m_current(),
+ m_position(-1)
+{
+}
+
+
+CommandHistory::~CommandHistory()
+{
+}
+
+
+void CommandHistory::add(QString const &entry)
+{
+ 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 WindowQtConfig::applyToQWidget(QWidget *widget)
+void CommandHistory::restoreConfigurationFromNode(util::xml::data_node const &node)
{
- widget->setGeometry(m_position.x(), m_position.y(), m_size.x(), m_size.y());
+ 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 WindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
+void CommandHistory::saveConfigurationToNode(util::xml::data_node &node)
{
- m_size.setX(node.get_attribute_int(ATTR_WINDOW_WIDTH, m_size.x()));
- m_size.setY(node.get_attribute_int(ATTR_WINDOW_HEIGHT, m_size.y()));
- m_position.setX(node.get_attribute_int(ATTR_WINDOW_POSITION_X, m_position.x()));
- m_position.setY(node.get_attribute_int(ATTR_WINDOW_POSITION_Y, m_position.y()));
- m_type = node.get_attribute_int(ATTR_WINDOW_TYPE, m_type);
+ 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
diff --git a/src/osd/modules/debugger/qt/windowqt.h b/src/osd/modules/debugger/qt/windowqt.h
index ceea280e016..8085f9a63bf 100644
--- a/src/osd/modules/debugger/qt/windowqt.h
+++ b/src/osd/modules/debugger/qt/windowqt.h
@@ -9,30 +9,45 @@
#include <QtWidgets/QMainWindow>
+#include <deque>
+#include <memory>
+
namespace osd::debugger::qt {
//============================================================
-// The Qt window that everyone derives from.
+// The Qt debugger module interface
//============================================================
-class WindowQt : public QMainWindow
+class DebuggerQt : public QObject
{
Q_OBJECT
public:
- WindowQt(running_machine &machine, QWidget *parent = nullptr);
- virtual ~WindowQt();
+ virtual ~DebuggerQt() { }
- // The interface to an all-window refresh
- void refreshAll() { s_refreshAll = true; }
- bool wantsRefresh() { return s_refreshAll; }
- void clearRefreshFlag() { s_refreshAll = false; }
+ virtual running_machine &machine() const = 0;
- void hideAll() { s_hideAll = true; }
- bool wantsHide() { return s_hideAll; }
- void clearHideFlag() { s_hideAll = false; }
+ void hideAll() { emit hideAllWindows(); }
+signals:
+ void exitDebugger();
+ void hideAllWindows();
+ void showAllWindows();
void saveConfiguration(util::xml::data_node &parentnode);
+};
+
+
+//============================================================
+// The Qt window that everyone derives from.
+//============================================================
+class WindowQt : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ virtual ~WindowQt();
+
+ virtual void restoreConfiguration(util::xml::data_node const &node);
protected slots:
void debugActOpenMemory();
@@ -52,38 +67,46 @@ protected slots:
void debugActHardReset();
virtual void debugActClose();
void debugActQuit();
+ virtual void debuggerExit();
+private slots:
+ void saveConfiguration(util::xml::data_node &parentnode);
protected:
+ WindowQt(DebuggerQt &debugger, QWidget *parent = nullptr);
+
virtual void saveConfigurationToNode(util::xml::data_node &node);
+ DebuggerQt &m_debugger;
running_machine &m_machine;
-
- static bool s_refreshAll;
- static bool s_hideAll;
};
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class WindowQtConfig
+//============================================================
+// Command history helper
+//============================================================
+class CommandHistory
{
public:
- WindowQtConfig(int type) :
- m_type(type),
- m_size(800, 600),
- m_position(120, 120)
- {}
- virtual ~WindowQtConfig() {}
-
- // Settings
- int m_type;
- QPoint m_size;
- QPoint m_position;
-
- virtual void applyToQWidget(QWidget *widget);
- virtual void recoverFromXmlNode(util::xml::data_node const &node);
+ CommandHistory();
+ ~CommandHistory();
+
+ void add(QString const &entry);
+ QString const *previous(QString const &current);
+ QString const *next(QString const &current);
+ void edit();
+ void reset();
+ void clear();
+
+ void restoreConfigurationFromNode(util::xml::data_node const &node);
+ void saveConfigurationToNode(util::xml::data_node &node);
+
+private:
+ static inline constexpr unsigned CAPACITY = 100U;
+
+ std::deque<QString> m_history;
+ std::unique_ptr<QString> m_current;
+ int m_position;
};
} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/win/debugwininfo.h b/src/osd/modules/debugger/win/debugwininfo.h
index 1fa5e79796f..f6f37c86955 100644
--- a/src/osd/modules/debugger/win/debugwininfo.h
+++ b/src/osd/modules/debugger/win/debugwininfo.h
@@ -20,7 +20,6 @@ namespace osd::debugger::win {
class debugwin_info : protected debugbase_info
{
public:
- debugwin_info(debugger_windows_interface &debugger, bool is_main_console, LPCSTR title, WNDPROC handler);
virtual ~debugwin_info();
bool is_valid() const { return m_wnd != nullptr; }
@@ -121,6 +120,8 @@ protected:
ID_DEVICE_OPTIONS // always keep this at the end
};
+ debugwin_info(debugger_windows_interface &debugger, bool is_main_console, LPCSTR title, WNDPROC handler);
+
bool is_main_console() const { return m_is_main_console; }
HWND window() const { return m_wnd; }
uint32_t minwidth() const { return m_minwidth; }
diff --git a/src/osd/modules/debugger/win/editwininfo.cpp b/src/osd/modules/debugger/win/editwininfo.cpp
index e5e48746f7f..e8c7fbf92e6 100644
--- a/src/osd/modules/debugger/win/editwininfo.cpp
+++ b/src/osd/modules/debugger/win/editwininfo.cpp
@@ -12,6 +12,8 @@
#include "debugviewinfo.h"
#include "uimetrics.h"
+#include "xmlfile.h"
+
#include "strconv.h"
#include "winutil.h"
@@ -25,7 +27,7 @@ constexpr DWORD EDIT_BOX_STYLE = WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
constexpr DWORD EDIT_BOX_STYLE_EX = 0;
constexpr int MAX_EDIT_STRING = 256;
-constexpr int HISTORY_LENGTH = 20;
+constexpr int HISTORY_LENGTH = 100;
} // anonymous namespace
@@ -107,6 +109,43 @@ void editwin_info::draw_contents(HDC dc)
}
+void editwin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ m_history.clear();
+ m_last_history = 0;
+ util::xml::data_node const *const hist = node.get_child(NODE_WINDOW_HISTORY);
+ if (hist)
+ {
+ util::xml::data_node const *item = hist->get_child(NODE_HISTORY_ITEM);
+ while (item)
+ {
+ if (item->get_value() && *item->get_value())
+ {
+ while (m_history.size() >= HISTORY_LENGTH)
+ m_history.pop_back();
+ m_history.emplace_front(osd::text::to_tstring(item->get_value()));
+ }
+ item = item->get_next_sibling(NODE_HISTORY_ITEM);
+ }
+ }
+
+ debugwin_info::restore_configuration_from_node(node);
+}
+
+
+void editwin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugwin_info::save_configuration_to_node(node);
+
+ util::xml::data_node *const hist = node.add_child(NODE_WINDOW_HISTORY, nullptr);
+ if (hist)
+ {
+ for (auto it = m_history.crbegin(); m_history.crend() != it; ++it)
+ hist->add_child(NODE_HISTORY_ITEM, osd::text::from_tstring(*it).c_str());
+ }
+}
+
+
LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
{
// handle a few messages
diff --git a/src/osd/modules/debugger/win/editwininfo.h b/src/osd/modules/debugger/win/editwininfo.h
index 6a18172b5c6..e2c0ce3c4b8 100644
--- a/src/osd/modules/debugger/win/editwininfo.h
+++ b/src/osd/modules/debugger/win/editwininfo.h
@@ -30,6 +30,8 @@ public:
virtual bool set_default_focus() override;
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
+
protected:
constexpr static DWORD COMBO_BOX_STYLE = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
constexpr static DWORD COMBO_BOX_STYLE_EX = 0;
@@ -41,6 +43,8 @@ protected:
virtual void draw_contents(HDC dc) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
+
private:
typedef std::deque<std::basic_string<TCHAR> > history_deque;
diff --git a/src/osd/modules/debugger/xmlconfig.cpp b/src/osd/modules/debugger/xmlconfig.cpp
index 9cdd34fc5da..7e702938bf8 100644
--- a/src/osd/modules/debugger/xmlconfig.cpp
+++ b/src/osd/modules/debugger/xmlconfig.cpp
@@ -12,6 +12,9 @@ char const *const NODE_WINDOW_SPLITS = "splits";
char const *const NODE_WINDOW_SELECTION = "selection";
char const *const NODE_WINDOW_SCROLL = "scroll";
char const *const NODE_WINDOW_EXPRESSION = "expression";
+char const *const NODE_WINDOW_HISTORY = "history";
+
+char const *const NODE_HISTORY_ITEM = "item";
char const *const ATTR_DEBUGGER_SAVE_WINDOWS = "savewindows";
diff --git a/src/osd/modules/debugger/xmlconfig.h b/src/osd/modules/debugger/xmlconfig.h
index a83f6ae960a..ae5cdf8393c 100644
--- a/src/osd/modules/debugger/xmlconfig.h
+++ b/src/osd/modules/debugger/xmlconfig.h
@@ -28,6 +28,9 @@ extern char const *const NODE_WINDOW_SPLITS;
extern char const *const NODE_WINDOW_SELECTION;
extern char const *const NODE_WINDOW_SCROLL;
extern char const *const NODE_WINDOW_EXPRESSION;
+extern char const *const NODE_WINDOW_HISTORY;
+
+extern char const *const NODE_HISTORY_ITEM;
extern char const *const ATTR_DEBUGGER_SAVE_WINDOWS;