diff --git a/src/gui2/drivecomponent.cc b/src/gui2/drivecomponent.cc index b17f054b..0ad7315b 100644 --- a/src/gui2/drivecomponent.cc +++ b/src/gui2/drivecomponent.cc @@ -6,6 +6,7 @@ #include "driveConfigurationForm.h" #include "fluxConfigurationForm.h" #include +#include static const char* DRIVE = "drive/"; static const char* SELECTED_DRIVE = "drive/drive"; @@ -96,6 +97,33 @@ public: &QLineEdit::editingFinished, this, &ConfigurationForm::updateSavedState); + + connect(openButton, + &QPushButton::clicked, + [this]() + { + std::string formats = Config::getFluxFormats() | + ranges::views::transform( + [](const FluxConstructor& f) + { + return f.glob; + }) | + ranges::views::filter( + [](const std::string& s) + { + return !s.empty(); + }) | + ranges::views::intersperse(" ") | + ranges::views::join | + ranges::to(); + QFileDialog dialogue(_dci->container()); + dialogue.setFileMode(QFileDialog::ExistingFile); + dialogue.setNameFilter(QString::fromStdString("Flux files (" + formats + ")")); + + QStringList fileNames; + if (dialogue.exec()) + filenameEdit->setText(dialogue.selectedFiles().first()); + }); } void updateSavedState() const override diff --git a/src/gui2/fluxConfigurationForm.ui b/src/gui2/fluxConfigurationForm.ui index 63fdf942..67df7047 100644 --- a/src/gui2/fluxConfigurationForm.ui +++ b/src/gui2/fluxConfigurationForm.ui @@ -33,7 +33,7 @@ - + Open @@ -111,6 +111,9 @@ + + false + 0 diff --git a/src/gui2/mainwindow.cc b/src/gui2/mainwindow.cc index 68eea24e..0657fe86 100644 --- a/src/gui2/mainwindow.cc +++ b/src/gui2/mainwindow.cc @@ -1,6 +1,7 @@ #include "lib/globals.h" #include "lib/config.h" #include "lib/readerwriter.h" +#include "lib/utils.h" #include "globals.h" #include "mainwindow.h" #include "drivecomponent.h" @@ -12,6 +13,14 @@ class MainWindowImpl : public MainWindow { W_OBJECT(MainWindowImpl) +private: + enum State + { + STATE_IDLE, + STATE_READING, + STATE_WRITING + }; + public: MainWindowImpl() { @@ -31,14 +40,20 @@ public: _progressWidget->setAlignment(Qt::AlignRight); statusbar->addPermanentWidget(_progressWidget); - auto* stopWidget = new QToolButton(); - stopWidget->setText("Stop"); - statusbar->addPermanentWidget(stopWidget); + _stopWidget = new QToolButton(); + _stopWidget->setText("Stop"); + statusbar->addPermanentWidget(_stopWidget); connect(readDiskButton, &QAbstractButton::clicked, this, &MainWindowImpl::readDisk); + connect(_stopWidget, + &QPushButton::clicked, + this, + &MainWindowImpl::emergencyStop); + + setState(STATE_IDLE); } public: @@ -61,24 +76,24 @@ public: { _fluxComponent->setDiskData(m.disk); _imageComponent->setDiskData(m.disk); + _currentDisk = m.disk; }, /* Large-scale operation start. */ [this](const BeginOperationLogMessage& m) { - setProgressBar(0); + _progressWidget->setValue(0); }, /* Large-scale operation end. */ [this](const EndOperationLogMessage& m) { - finishedWithProgressBar(); }, /* Large-scale operation progress. */ [this](const OperationProgressLogMessage& m) { - setProgressBar(m.progress); + _progressWidget->setValue(m.progress); }}, *message); @@ -87,18 +102,6 @@ public: logViewerEdit->ensureCursorVisible(); } - void setProgressBar(int progress) override - { - _progressWidget->setEnabled(true); - _progressWidget->setValue(progress); - } - - void finishedWithProgressBar() override - { - _progressWidget->setEnabled(false); - _progressWidget->setValue(0); - } - void collectConfig() override { try @@ -113,9 +116,7 @@ public: } catch (...) { - std::exception_ptr p = std::current_exception(); - std::clog << (p ? p.__cxa_exception_type()->name() : "null") - << std::endl; + log("Mysterious uncaught exception!"); } } @@ -126,22 +127,65 @@ private: return; collectConfig(); - safeRunOnWorkerThread( + ::emergencyStop = false; + setState(STATE_READING); + + runThen( [this]() { auto& fluxSource = globalConfig().getFluxSource(); auto& decoder = globalConfig().getDecoder(); auto diskflux = readDiskCommand(*fluxSource, *decoder); + }, + [this]() + { + setState(STATE_IDLE); }); } W_SLOT(readDisk) +private: + void emergencyStop() + { + ::emergencyStop = true; + } + W_SLOT(emergencyStop) + + void setState(int state) + { + _stopWidget->setEnabled(state != STATE_IDLE); + _progressWidget->setEnabled(state != STATE_IDLE); + diskOperationsGroup->setEnabled(state == STATE_IDLE); + memoryOperationsGroup->setEnabled(state == STATE_IDLE); + driveWindow->setEnabled(state == STATE_IDLE); + formatWindow->setEnabled(state == STATE_IDLE); + + _state = state; + } + W_SLOT(setState) + +private: + void runThen( + std::function workCb, std::function completionCb) + { + QFutureWatcher* watcher = new QFutureWatcher(this); + watcher->setFuture(safeRunOnWorkerThread(workCb)); + connect(watcher, &QFutureWatcher::finished, completionCb); + connect(watcher, + &QFutureWatcher::finished, + watcher, + &QFutureWatcher::deleteLater); + } + private: DriveComponent* _driveComponent; FormatComponent* _formatComponent; FluxComponent* _fluxComponent; ImageComponent* _imageComponent; + QAbstractButton* _stopWidget; QProgressBar* _progressWidget; + std::shared_ptr _currentDisk; + int _state; }; W_OBJECT_IMPL(MainWindowImpl) diff --git a/src/gui2/mainwindow.h b/src/gui2/mainwindow.h index bfd5c675..87ef2baa 100644 --- a/src/gui2/mainwindow.h +++ b/src/gui2/mainwindow.h @@ -10,7 +10,5 @@ public: public: virtual void logMessage(std::shared_ptr message) = 0; - virtual void setProgressBar(int progress) = 0; - virtual void finishedWithProgressBar() = 0; virtual void collectConfig() = 0; }; diff --git a/src/gui2/userinterface.ui b/src/gui2/userinterface.ui index 74d277e6..fe775ddd 100644 --- a/src/gui2/userinterface.ui +++ b/src/gui2/userinterface.ui @@ -65,7 +65,7 @@ - + 1 @@ -134,7 +134,10 @@ - + + + true + 1