diff --git a/OSBindings/Qt/ClockSignal.pro b/OSBindings/Qt/ClockSignal.pro
index 8d8ce6204..57e7ccb10 100644
--- a/OSBindings/Qt/ClockSignal.pro
+++ b/OSBindings/Qt/ClockSignal.pro
@@ -252,6 +252,7 @@ HEADERS += \
functionthread.h \
mainwindow.h \
scantargetwidget.h \
+ settings.h \
timer.h
FORMS += \
diff --git a/OSBindings/Qt/mainwindow.cpp b/OSBindings/Qt/mainwindow.cpp
index 06e5e8410..c6b391414 100644
--- a/OSBindings/Qt/mainwindow.cpp
+++ b/OSBindings/Qt/mainwindow.cpp
@@ -3,6 +3,7 @@
#include
#include "mainwindow.h"
+#include "settings.h"
#include "timer.h"
#include "../../Numeric/CRC.hpp"
@@ -15,38 +16,54 @@
affect the window, so isn't useful for this project). Therefore the emulation window resizes freely.
*/
-MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- , ui(new Ui::MainWindow)
-{
- ui->setupUi(this);
- createActions();
+MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
+ init();
+ setVisibleWidgetSet(WidgetSet::MachinePicker);
+}
+
+MainWindow::MainWindow(const QString &fileName) {
+ init();
+ launchFile(fileName);
+}
+
+void MainWindow::init() {
qApp->installEventFilter(this);
- timer = std::make_unique(this);
-
- setVisibleWidgetSet(WidgetSet::MachinePicker);
+ ui = std::make_unique();
+ ui->setupUi(this);
romRequestBaseText = ui->missingROMsBox->toPlainText();
+
+ createActions();
+ restoreSelections();
+
+ timer = std::make_unique(this);
}
void MainWindow::createActions() {
// Create a file menu.
- QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
+ QMenu *const fileMenu = menuBar()->addMenu(tr("&File"));
- // Add file option: 'New...'
- QAction *newAct = new QAction(tr("&New"), this);
+ // Add file option: 'New'
+ QAction *const newAct = new QAction(tr("&New"), this);
newAct->setShortcuts(QKeySequence::New);
newAct->setStatusTip(tr("Create a new file"));
connect(newAct, &QAction::triggered, this, &MainWindow::newFile);
fileMenu->addAction(newAct);
// Add file option: 'Open...'
- QAction *openAct = new QAction(tr("&Open..."), this);
+ QAction *const openAct = new QAction(tr("&Open..."), this);
openAct->setShortcuts(QKeySequence::Open);
openAct->setStatusTip(tr("Open an existing file"));
connect(openAct, &QAction::triggered, this, &MainWindow::open);
fileMenu->addAction(openAct);
+ // Add a separator and then an 'Insert...'.
+ fileMenu->addSeparator();
+ QAction *const insertAct = new QAction(tr("&Insert..."), this);
+ insertAct->setStatusTip(tr("Open an existing file"));
+ connect(insertAct, &QAction::triggered, this, &MainWindow::insert);
+ fileMenu->addAction(insertAct);
+
// Add Help menu, with an 'About...' option.
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
@@ -59,26 +76,61 @@ void MainWindow::createActions() {
void MainWindow::open() {
QString fileName = QFileDialog::getOpenFileName(this);
if(!fileName.isEmpty()) {
- targets = Analyser::Static::GetTargets(fileName.toStdString());
- if(!targets.empty()) {
- launchMachine();
+ // My understanding of SDI: if a file was opened for a 'vacant' window, launch it directly there;
+ // otherwise create a new window for it.
+ if(machine) {
+ MainWindow *const other = new MainWindow(fileName);
+ other->tile(this);
+ other->show();
+ } else {
+ launchFile(fileName);
}
}
}
-void MainWindow::newFile() {
+void MainWindow::insert() {
}
+void MainWindow::launchFile(const QString &fileName) {
+ targets = Analyser::Static::GetTargets(fileName.toStdString());
+ if(!targets.empty()) {
+ launchMachine();
+ }
+}
+
+void MainWindow::newFile() {
+ MainWindow *other = new MainWindow;
+ other->tile(this);
+ other->show();
+}
+
+void MainWindow::tile(const QMainWindow *previous)
+{
+ // This entire function is essentially verbatim from the Qt SDI example.
+ if (!previous)
+ return;
+
+ int topFrameWidth = previous->geometry().top() - previous->pos().y();
+ if (!topFrameWidth)
+ topFrameWidth = 40;
+
+ const QPoint pos = previous->pos() + 2 * QPoint(topFrameWidth, topFrameWidth);
+ if (screen()->availableGeometry().contains(rect().bottomRight() + pos))
+ move(pos);
+}
+
+
void MainWindow::about() {
QMessageBox::about(this, tr("About Clock Signal"),
- tr( "Clock Signal is an emulator of various platforms by "
- "Thomas Harte.
"
+ tr( "Clock Signal is an emulator of various platforms.
"
"This emulator is offered under the MIT licence; its source code "
"is available from GitHub.
"
"This port is experimental, especially with regard to latency; "
- "please don't hesitate to provide feedback.
"
+ "please don't hesitate to provide feedback, "
+ "by email or via the "
+ "GitHub issue tracker.
"
));
}
@@ -94,6 +146,9 @@ MainWindow::~MainWindow() {
});
audioThread.stop();
}
+
+ // Store the current user selections.
+ storeSelections();
}
// MARK: Machine launch.
@@ -424,7 +479,6 @@ void MainWindow::startMachine() {
#define TEST(x) \
if(selectedTab == ui->x ## Tab) { \
- qDebug() << #x; \
start_##x(); \
return; \
}
@@ -602,3 +656,14 @@ void MainWindow::launchTarget(std::unique_ptr &&target
targets.push_back(std::move(target));
launchMachine();
}
+
+// MARK - UI state
+
+void MainWindow::storeSelections() {
+ Settings settings;
+
+ settings.setValue("machineSelection", ui->machineSelectionTabs->currentIndex());
+}
+
+void MainWindow::restoreSelections() {
+}
diff --git a/OSBindings/Qt/mainwindow.h b/OSBindings/Qt/mainwindow.h
index e1953df31..a9846b8db 100644
--- a/OSBindings/Qt/mainwindow.h
+++ b/OSBindings/Qt/mainwindow.h
@@ -25,6 +25,7 @@ class MainWindow : public QMainWindow, public Outputs::Speaker::Speaker::Delegat
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
+ explicit MainWindow(const QString &fileName);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
@@ -70,6 +71,7 @@ class MainWindow : public QMainWindow, public Outputs::Speaker::Speaker::Delegat
void open();
void newFile();
void about();
+ void insert();
void startMachine();
private:
@@ -84,7 +86,14 @@ class MainWindow : public QMainWindow, public Outputs::Speaker::Speaker::Delegat
void start_zx80();
void start_zx81();
+ void launchFile(const QString &fileName);
void launchTarget(std::unique_ptr &&);
+
+ void restoreSelections();
+ void storeSelections();
+
+ void init();
+ void tile(const QMainWindow *previous);
};
#endif // MAINWINDOW_H
diff --git a/OSBindings/Qt/settings.h b/OSBindings/Qt/settings.h
new file mode 100644
index 000000000..234d8a8d9
--- /dev/null
+++ b/OSBindings/Qt/settings.h
@@ -0,0 +1,11 @@
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include
+
+class Settings: public QSettings {
+ public:
+ Settings() : QSettings("thomasharte", "Clock Signal") {}
+};
+
+#endif // SETTINGS_H