From 2d58946f3fedad643ff8abf619cc0ec59f5ded72 Mon Sep 17 00:00:00 2001 From: Carl Philipp Klemm Date: Mon, 13 Oct 2025 14:28:34 +0200 Subject: [PATCH 1/4] Implement actions --- mainwindow.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++++++++- mainwindow.h | 10 ++++- 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 379cd2b..dab222f 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,6 +1,9 @@ #include #include #include +#include +#include +#include #include "mainwindow.h" #include "ui_mainwindow.h" #include "triggerwidget.h" @@ -8,7 +11,9 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow), - codeEditor(this) + codeEditor(this), + currentFilePath(""), + isFileModified(false) { ui->setupUi(this); enumerateDevices(); @@ -24,6 +29,15 @@ MainWindow::MainWindow(QWidget *parent): ui->codeLayout->addWidget(&codeEditor); connect(ui->actionQuit, &QAction::triggered, this, [this]() {close();}); + connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::onActionOpenTriggered); + connect(ui->actionSave, &QAction::triggered, this, &MainWindow::onActionSaveTriggered); + connect(ui->actionSave_As, &QAction::triggered, this, &MainWindow::onActionSaveAsTriggered); + + // Connect text changed signal to track modifications + connect(&codeEditor, &QTextEdit::textChanged, this, [this]() { + isFileModified = true; + updateTitle(); + }); } MainWindow::~MainWindow() @@ -31,6 +45,97 @@ MainWindow::~MainWindow() delete ui; } +void MainWindow::updateTitle() +{ + QString windowTitle = "EisMultiplexer-Qt"; + if (!currentFilePath.isEmpty()) { + windowTitle = QString("%1 - %2").arg(currentFilePath); + } + if (isFileModified) { + windowTitle += "[*]"; + } + setWindowTitle(windowTitle); +} + +void MainWindow::onActionOpenTriggered() +{ + QString filePath = QFileDialog::getOpenFileName(this, tr("Open Python Script"), + "", + tr("Python Files (*.py);;All Files (*)")); + + if (filePath.isEmpty()) { + return; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QMessageBox::warning(this, tr("Error"), tr("Could not open file: %1").arg(filePath)); + return; + } + + QTextStream in(&file); + QString content = in.readAll(); + file.close(); + + codeEditor.setPlainText(content); + currentFilePath = filePath; + isFileModified = false; + updateTitle(); +} + +void MainWindow::onActionSaveTriggered() +{ + if (currentFilePath.isEmpty()) { + onActionSaveAsTriggered(); + return; + } + + QFile file(currentFilePath); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QMessageBox::warning(this, tr("Error"), tr("Could not save file: %1").arg(currentFilePath)); + return; + } + + QTextStream out(&file); + out << codeEditor.toPlainText(); + file.close(); + + isFileModified = false; + updateTitle(); +} + +void MainWindow::onActionSaveAsTriggered() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("Save Python Script"), + "", + tr("Python Files (*.py);;All Files (*)")); + + if (filePath.isEmpty()) { + return; + } + + // Ensure the file has a .py extension if it's a Python file + if (filePath.endsWith(".py", Qt::CaseInsensitive)) { + // File already has .py extension + } else { + filePath += ".py"; + } + + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QMessageBox::warning(this, tr("Error"), tr("Could not save file: %1").arg(filePath)); + return; + } + + QTextStream out(&file); + out << codeEditor.toPlainText(); + file.close(); + + currentFilePath = filePath; + isFileModified = false; + updateTitle(); +} + void MainWindow::enumerateDevices() { size_t count = 0; diff --git a/mainwindow.h b/mainwindow.h index 7373d2b..508f1c2 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -34,9 +34,17 @@ public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); +private slots: + void onActionOpenTriggered(); + void onActionSaveTriggered(); + void onActionSaveAsTriggered(); + private: void enumerateDevices(); - void generateExample(); + void generateExample(); + void updateTitle(); + QString currentFilePath; + bool isFileModified; }; #endif // MAINWINDOW_H From 5e91fd4a1ae57558d678b7aa06ff45251eab3923 Mon Sep 17 00:00:00 2001 From: Carl Philipp Klemm Date: Mon, 13 Oct 2025 14:51:28 +0200 Subject: [PATCH 2/4] Add keyboard shortcuts --- mainwindow.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mainwindow.cpp b/mainwindow.cpp index dab222f..8cd4086 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -28,6 +28,12 @@ MainWindow::MainWindow(QWidget *parent): ui->codeLayout->addWidget(&codeEditor); + // Set up keyboard shortcuts + ui->actionOpen->setShortcut(QKeySequence::Open); + ui->actionSave->setShortcut(QKeySequence::Save); + ui->actionSave_As->setShortcut(QKeySequence::SaveAs); + ui->actionQuit->setShortcut(QKeySequence::Quit); + connect(ui->actionQuit, &QAction::triggered, this, [this]() {close();}); connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::onActionOpenTriggered); connect(ui->actionSave, &QAction::triggered, this, &MainWindow::onActionSaveTriggered); From 8ad659de762396f2e36878763f26273bfb312c00 Mon Sep 17 00:00:00 2001 From: Carl Philipp Klemm Date: Mon, 13 Oct 2025 15:21:17 +0200 Subject: [PATCH 3/4] Add example generation --- mainwindow.cpp | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 379cd2b..81e80f8 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "mainwindow.h" #include "ui_mainwindow.h" #include "triggerwidget.h" @@ -114,17 +115,47 @@ void MainWindow::enumerateDevices() ui->statusbar->showMessage("Ready"); free(serials); + generateExample(); } void MainWindow::generateExample() { QString example = - "import eismultiplexer\n\n" - "from time import sleep"; + "# This is an example script to show you how\n# to drive eismultiplexer using the python api\n" + "import eismultiplexer as multi\n" + "from time import sleep\n\n" + "# First initalize the device(s)\n"; - for (const auto& channel : channels) + std::set serials; + for (size_t i = 0; i < channels.size(); ++i) + serials.insert(channels[i]->getDeviceSerial()); + + size_t i = 0; + for (uint16_t serial : serials) { - example.append(QString("eismultiplexer")); + example.append(QString("multiplexer_") + QString::number(i) + " multi.Multiplexer(serial=" + QString::number(serial) + ")\n"); + ++i; } + + example.append("\nprint('\\nListing the nummber of channels per unit')\n"); + for (size_t i = 0; i < serials.size(); ++i) + { + QString printLine = "print(f'Found unit with serial number {" + QString::number(channels[i]->getDeviceSerial()) + "} and {multiplexer_" + QString::number(i) + ".getChannelCount()} channels')\n"; + example.append(printLine); + } + + example.append("\nprint('Connecting the first and second channel on the first unit')\n"); + example.append("multiplexer_0.connectChannel(multi.Channel.A)\n"); + example.append("multiplexer_0.connectChannel(multi.Channel.B)\n\n"); + example.append("print('Waiting for half a second for something to happen')\n"); + example.append("sleep(0.5)\n\n"); + example.append("print('Disconnect first channel')\n"); + example.append("multiplexer_0.disconnectChannel(multi.Channel.A)\n\n"); + example.append("print('Waiting up to 5000 milliseconds for a trigger')\n"); + example.append("multiplexer_0.setTriggerState(0, multi.TriggerState.INPUT)\n"); + example.append("multiplexer_0.waitTrigger(0, multi.TriggerState.HIGHLEVEL, 5000)\n\n"); + example.append("print('Disconnecting all channels')\n"); + example.append("multiplexer_0.clear()\n"); + codeEditor.setText(example); } From b6fb6ca7d43348510b9c03934b8431fb5af88b82 Mon Sep 17 00:00:00 2001 From: Carl Philipp Klemm Date: Mon, 13 Oct 2025 15:32:47 +0200 Subject: [PATCH 4/4] Put the file name of the code editor into the satus bar instead of the title bar --- mainwindow.cpp | 29 +++++++++++------------------ mainwindow.h | 2 +- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 2537ad9..89f86a3 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -43,7 +43,7 @@ MainWindow::MainWindow(QWidget *parent): // Connect text changed signal to track modifications connect(&codeEditor, &QTextEdit::textChanged, this, [this]() { isFileModified = true; - updateTitle(); + updateStatus(); }); } @@ -52,16 +52,16 @@ MainWindow::~MainWindow() delete ui; } -void MainWindow::updateTitle() +void MainWindow::updateStatus() { - QString windowTitle = "EisMultiplexer-Qt"; if (!currentFilePath.isEmpty()) { - windowTitle = QString("%1 - %2").arg(currentFilePath); + QString status = "EisMultiplexer-Qt"; + status = QString("%1").arg(currentFilePath); + if (isFileModified) { + status += " - [Unsaved Changes]"; + } + ui->statusbar->showMessage(status); } - if (isFileModified) { - windowTitle += "[*]"; - } - setWindowTitle(windowTitle); } void MainWindow::onActionOpenTriggered() @@ -87,7 +87,7 @@ void MainWindow::onActionOpenTriggered() codeEditor.setPlainText(content); currentFilePath = filePath; isFileModified = false; - updateTitle(); + updateStatus(); } void MainWindow::onActionSaveTriggered() @@ -108,7 +108,7 @@ void MainWindow::onActionSaveTriggered() file.close(); isFileModified = false; - updateTitle(); + updateStatus(); } void MainWindow::onActionSaveAsTriggered() @@ -121,13 +121,6 @@ void MainWindow::onActionSaveAsTriggered() return; } - // Ensure the file has a .py extension if it's a Python file - if (filePath.endsWith(".py", Qt::CaseInsensitive)) { - // File already has .py extension - } else { - filePath += ".py"; - } - QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { QMessageBox::warning(this, tr("Error"), tr("Could not save file: %1").arg(filePath)); @@ -140,7 +133,7 @@ void MainWindow::onActionSaveAsTriggered() currentFilePath = filePath; isFileModified = false; - updateTitle(); + updateStatus(); } void MainWindow::enumerateDevices() diff --git a/mainwindow.h b/mainwindow.h index 508f1c2..70bbc2f 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -42,7 +42,7 @@ private slots: private: void enumerateDevices(); void generateExample(); - void updateTitle(); + void updateStatus(); QString currentFilePath; bool isFileModified; };