diff --git a/qt/scientific_interfaces/Indirect/Common/IndirectInstrumentConfig.h b/qt/scientific_interfaces/Indirect/Common/IndirectInstrumentConfig.h index 3766e3248f98..4907690af2b8 100644 --- a/qt/scientific_interfaces/Indirect/Common/IndirectInstrumentConfig.h +++ b/qt/scientific_interfaces/Indirect/Common/IndirectInstrumentConfig.h @@ -17,6 +17,41 @@ namespace MantidQt { namespace MantidWidgets { + +class IInstrumentConfig { +public: + virtual ~IInstrumentConfig() = default; + + virtual QStringList getTechniques() = 0; + virtual void setTechniques(const QStringList &techniques) = 0; + + virtual QStringList getDisabledInstruments() = 0; + virtual void setDisabledInstruments(const QStringList &instrumentNames) = 0; + + virtual QString getFacility() = 0; + virtual void setFacility(const QString &facilityName) = 0; + + virtual bool isDiffractionEnabled() = 0; + virtual void enableDiffraction(bool enabled) = 0; + + virtual bool isDiffractionForced() = 0; + virtual void forceDiffraction(bool forced) = 0; + + virtual bool isInstrumentLabelShown() = 0; + virtual void setShowInstrumentLabel(bool visible) = 0; + + virtual QString getInstrumentName() = 0; + virtual void setInstrument(const QString &instrumentName) = 0; + + virtual QString getAnalyserName() = 0; + virtual void setAnalyser(const QString &analyserName) = 0; + + virtual QString getReflectionName() = 0; + virtual void setReflection(const QString &reflectionName) = 0; + + virtual void showAnalyserAndReflectionOptions(bool visible) = 0; +}; + /** Widget used to select an instrument configuration for indirect geometry spectrometers @@ -29,7 +64,7 @@ are populated by loading an empty instrument. @author Dan Nixon */ -class MANTIDQT_INDIRECT_DLL IndirectInstrumentConfig : public API::MantidWidget { +class MANTIDQT_INDIRECT_DLL IndirectInstrumentConfig : public API::MantidWidget, public IInstrumentConfig { Q_OBJECT Q_PROPERTY(QStringList techniques READ getTechniques WRITE setTechniques) @@ -44,41 +79,41 @@ class MANTIDQT_INDIRECT_DLL IndirectInstrumentConfig : public API::MantidWidget ~IndirectInstrumentConfig() override; /* Getters and setters for Qt properties */ - QStringList getTechniques(); - void setTechniques(const QStringList &techniques); + QStringList getTechniques() override; + void setTechniques(const QStringList &techniques) override; - QStringList getDisabledInstruments(); - void setDisabledInstruments(const QStringList &instrumentNames); + QStringList getDisabledInstruments() override; + void setDisabledInstruments(const QStringList &instrumentNames) override; - QString getFacility(); - void setFacility(const QString &facilityName); + QString getFacility() override; + void setFacility(const QString &facilityName) override; - bool isDiffractionEnabled(); - void enableDiffraction(bool enabled); + bool isDiffractionEnabled() override; + void enableDiffraction(bool enabled) override; - bool isDiffractionForced(); - void forceDiffraction(bool forced); + bool isDiffractionForced() override; + void forceDiffraction(bool forced) override; - bool isInstrumentLabelShown(); - void setShowInstrumentLabel(bool visible); + bool isInstrumentLabelShown() override; + void setShowInstrumentLabel(bool visible) override; /// Gets the name of the selected instrument - QString getInstrumentName(); + QString getInstrumentName() override; /// Set the displayed instrument (if exists) - void setInstrument(const QString &instrumentName); + void setInstrument(const QString &instrumentName) override; /// Gets the name of the selected analyser - QString getAnalyserName(); + QString getAnalyserName() override; /// Set the displayed analyser bank (if exists) - void setAnalyser(const QString &analyserName); + void setAnalyser(const QString &analyserName) override; /// Gets the name of the selected reflection - QString getReflectionName(); + QString getReflectionName() override; /// Set the displayed reflection mode (if exists) - void setReflection(const QString &reflectionName); + void setReflection(const QString &reflectionName) override; /// Controls where to show analyser and reflection options or not - void showAnalyserAndReflectionOptions(bool visible); + void showAnalyserAndReflectionOptions(bool visible) override; public slots: /// Called when an instrument configuration is selected diff --git a/qt/scientific_interfaces/Indirect/Reduction/ILLEnergyTransfer.cpp b/qt/scientific_interfaces/Indirect/Reduction/ILLEnergyTransfer.cpp index 4f73d1d13208..0549b31be90b 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ILLEnergyTransfer.cpp +++ b/qt/scientific_interfaces/Indirect/Reduction/ILLEnergyTransfer.cpp @@ -30,7 +30,7 @@ namespace MantidQt::CustomInterfaces { //---------------------------------------------------------------------------------------------- /** Constructor */ -ILLEnergyTransfer::ILLEnergyTransfer(IndirectDataReduction *idrUI, QWidget *parent) +ILLEnergyTransfer::ILLEnergyTransfer(IIndirectDataReduction *idrUI, QWidget *parent) : IndirectDataReductionTab(idrUI, parent) { m_uiForm.setupUi(parent); diff --git a/qt/scientific_interfaces/Indirect/Reduction/ILLEnergyTransfer.h b/qt/scientific_interfaces/Indirect/Reduction/ILLEnergyTransfer.h index 2e460a8c47d8..11502477fcc4 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ILLEnergyTransfer.h +++ b/qt/scientific_interfaces/Indirect/Reduction/ILLEnergyTransfer.h @@ -13,16 +13,13 @@ namespace MantidQt { namespace CustomInterfaces { -/** ILLEnergyTransfer +class IIndirectDataReduction; - @author Dan Nixon - @date 23/07/2014 -*/ class MANTIDQT_INDIRECT_DLL ILLEnergyTransfer : public IndirectDataReductionTab { Q_OBJECT public: - ILLEnergyTransfer(IndirectDataReduction *idrUI, QWidget *parent = nullptr); + ILLEnergyTransfer(IIndirectDataReduction *idrUI, QWidget *parent = nullptr); ~ILLEnergyTransfer() override; void setup() override; diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISCalibration.cpp b/qt/scientific_interfaces/Indirect/Reduction/ISISCalibration.cpp index 8f58cc01e53e..1b508f679ea4 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISCalibration.cpp +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISCalibration.cpp @@ -41,7 +41,7 @@ namespace MantidQt::CustomInterfaces { //---------------------------------------------------------------------------------------------- /** Constructor */ -ISISCalibration::ISISCalibration(IndirectDataReduction *idrUI, QWidget *parent) +ISISCalibration::ISISCalibration(IIndirectDataReduction *idrUI, QWidget *parent) : IndirectDataReductionTab(idrUI, parent), m_lastCalPlotFilename("") { m_uiForm.setupUi(parent); setOutputPlotOptionsPresenter( diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISCalibration.h b/qt/scientific_interfaces/Indirect/Reduction/ISISCalibration.h index 9e8383caab81..e2319afc5fe4 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISCalibration.h +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISCalibration.h @@ -13,6 +13,8 @@ namespace MantidQt { namespace CustomInterfaces { +class IIndirectDataReduction; + /** ISISCalibration Handles vanadium run calibration for ISIS instruments. @@ -23,7 +25,7 @@ class MANTIDQT_INDIRECT_DLL ISISCalibration : public IndirectDataReductionTab { Q_OBJECT public: - ISISCalibration(IndirectDataReduction *idrUI, QWidget *parent = nullptr); + ISISCalibration(IIndirectDataReduction *idrUI, QWidget *parent = nullptr); ~ISISCalibration() override; void setup() override; diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISDiagnostics.cpp b/qt/scientific_interfaces/Indirect/Reduction/ISISDiagnostics.cpp index 8dd46d85f1db..951c7688f76e 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISDiagnostics.cpp +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISDiagnostics.cpp @@ -24,7 +24,7 @@ namespace MantidQt::CustomInterfaces { //---------------------------------------------------------------------------------------------- /** Constructor */ -ISISDiagnostics::ISISDiagnostics(IndirectDataReduction *idrUI, QWidget *parent) +ISISDiagnostics::ISISDiagnostics(IIndirectDataReduction *idrUI, QWidget *parent) : IndirectDataReductionTab(idrUI, parent) { m_uiForm.setupUi(parent); setOutputPlotOptionsPresenter( diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISDiagnostics.h b/qt/scientific_interfaces/Indirect/Reduction/ISISDiagnostics.h index 58df4b08d1d6..0c7a96c2f650 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISDiagnostics.h +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISDiagnostics.h @@ -32,6 +32,8 @@ namespace MantidQt { namespace CustomInterfaces { +class IIndirectDataReduction; + /** ISISDiagnostics Handles time integration diagnostics for ISIS instruments. @@ -42,7 +44,7 @@ class MANTIDQT_INDIRECT_DLL ISISDiagnostics : public IndirectDataReductionTab { Q_OBJECT public: - ISISDiagnostics(IndirectDataReduction *idrUI, QWidget *parent = nullptr); + ISISDiagnostics(IIndirectDataReduction *idrUI, QWidget *parent = nullptr); ~ISISDiagnostics() override; void setup() override; diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferModel.cpp b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferModel.cpp index 69dba23eb8c9..d74cbb7d0a19 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferModel.cpp +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferModel.cpp @@ -16,7 +16,7 @@ using namespace Mantid::API; namespace MantidQt::CustomInterfaces { -IETModel::IETModel() {} +IETModel::IETModel() : m_outputWorkspaces() {} std::vector IETModel::validateRunData(IETRunData const &runData) { std::vector errors; @@ -110,7 +110,7 @@ void IETModel::setOutputProperties(IAlgorithmRuntimeProps &properties, IETOutput Mantid::API::AlgorithmProperties::update("OutputWorkspace", outputGroupName, properties); } -std::string IETModel::getOuputGroupName(InstrumentData const &instData, std::string const &inputText) { +std::string IETModel::getOutputGroupName(InstrumentData const &instData, std::string const &inputText) { std::string instrument = instData.getInstrument(); std::string analyser = instData.getAnalyser(); std::string reflection = instData.getReflection(); @@ -129,7 +129,7 @@ std::string IETModel::runIETAlgorithm(MantidQt::API::BatchAlgorithmRunner *batch setRebinProperties(*properties, runData.getRebinData()); setAnalysisProperties(*properties, runData.getAnalysisData()); - std::string outputGroupName = getOuputGroupName(instData, runData.getInputData().getInputText()); + std::string outputGroupName = getOutputGroupName(instData, runData.getInputData().getInputText()); setOutputProperties(*properties, runData.getOutputData(), outputGroupName); auto reductionAlg = AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer"); @@ -274,11 +274,11 @@ double IETModel::loadDetailedBalance(std::string const &filename) { std::vector IETModel::groupWorkspaces(std::string const &groupName, std::string const &instrument, std::string const &groupOption, bool const shouldGroup) { - std::vector outputWorkspaces; + m_outputWorkspaces.clear(); if (WorkspaceUtils::doesExistInADS(groupName)) { if (auto const outputGroup = WorkspaceUtils::getADSWorkspace(groupName)) { - outputWorkspaces = outputGroup->getNames(); + m_outputWorkspaces = outputGroup->getNames(); if (instrument == "OSIRIS") { if (!shouldGroup) { @@ -296,7 +296,7 @@ std::vector IETModel::groupWorkspaces(std::string const &groupName, } } - return outputWorkspaces; + return m_outputWorkspaces; } void IETModel::ungroupWorkspace(std::string const &workspaceName) { diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferModel.h b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferModel.h index 36897fb2dbcb..54860df647b8 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferModel.h +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferModel.h @@ -17,12 +17,58 @@ using namespace Mantid::API; namespace MantidQt { namespace CustomInterfaces { -class MANTIDQT_INDIRECT_DLL IETModel { + +class MANTIDQT_INDIRECT_DLL IIETModel { +public: + virtual ~IIETModel() = default; + + virtual void setInstrumentProperties(IAlgorithmRuntimeProps &properties, InstrumentData const &instData) = 0; + + virtual std::vector validateRunData(IETRunData const &runData) = 0; + virtual std::vector validatePlotData(IETPlotData const &plotData) = 0; + + virtual std::string runIETAlgorithm(MantidQt::API::BatchAlgorithmRunner *batchAlgoRunner, + InstrumentData const &instData, IETRunData &runParams) = 0; + virtual std::deque + plotRawAlgorithmQueue(InstrumentData const &instData, IETPlotData const &plotData) const = 0; + + virtual void saveWorkspace(std::string const &workspaceName, IETSaveData const &saveData) = 0; + + virtual void createGroupingWorkspace(std::string const &instrumentName, std::string const &analyser, + std::string const &customGrouping, std::string const &outputName) = 0; + virtual double loadDetailedBalance(std::string const &filename) = 0; + + virtual std::vector groupWorkspaces(std::string const &groupName, std::string const &instrument, + std::string const &groupOption, bool const shouldGroup) = 0; + + virtual std::vector outputWorkspaceNames() const = 0; +}; + +class MANTIDQT_INDIRECT_DLL IETModel : public IIETModel { public: IETModel(); ~IETModel() = default; - void setInstrumentProperties(IAlgorithmRuntimeProps &properties, InstrumentData const &instData); + void setInstrumentProperties(IAlgorithmRuntimeProps &properties, InstrumentData const &instData) override; + + std::vector validateRunData(IETRunData const &runData) override; + std::vector validatePlotData(IETPlotData const &plotData) override; + + std::string runIETAlgorithm(MantidQt::API::BatchAlgorithmRunner *batchAlgoRunner, InstrumentData const &instData, + IETRunData &runParams) override; + std::deque + plotRawAlgorithmQueue(InstrumentData const &instData, IETPlotData const &plotData) const override; + + void saveWorkspace(std::string const &workspaceName, IETSaveData const &saveData) override; + + void createGroupingWorkspace(std::string const &instrumentName, std::string const &analyser, + std::string const &customGrouping, std::string const &outputName) override; + double loadDetailedBalance(std::string const &filename) override; + + std::vector groupWorkspaces(std::string const &groupName, std::string const &instrument, + std::string const &groupOption, bool const shouldGroup) override; + + // Public for testing purposes void setInputProperties(IAlgorithmRuntimeProps &properties, IETInputData const &inputData); void setConversionProperties(IAlgorithmRuntimeProps &properties, IETConversionData const &conversionData, std::string const &instrument); @@ -31,36 +77,27 @@ class MANTIDQT_INDIRECT_DLL IETModel { void setAnalysisProperties(IAlgorithmRuntimeProps &properties, IETAnalysisData const &analysisData); void setOutputProperties(IAlgorithmRuntimeProps &properties, IETOutputData const &outputData, std::string const &outputGroupName); - std::string getOuputGroupName(InstrumentData const &instData, std::string const &inputFiles); - - std::vector validateRunData(IETRunData const &runData); - std::vector validatePlotData(IETPlotData const &plotData); + std::string getOutputGroupName(InstrumentData const &instData, std::string const &inputFiles); - std::string runIETAlgorithm(MantidQt::API::BatchAlgorithmRunner *batchAlgoRunner, InstrumentData const &instData, - IETRunData &runParams); - std::deque plotRawAlgorithmQueue(InstrumentData const &instData, - IETPlotData const &plotData) const; + [[nodiscard]] inline std::vector outputWorkspaceNames() const noexcept override { + return m_outputWorkspaces; + } - void saveWorkspace(std::string const &workspaceName, IETSaveData const &saveData); +private: void saveDaveGroup(std::string const &workspaceName, std::string const &outputName); void saveAclimax(std::string const &workspaceName, std::string const &outputName, std::string const &xUnits = "DeltaE_inWavenumber"); void save(std::string const &algorithmName, std::string const &workspaceName, std::string const &outputName, int const version = -1, std::string const &separator = ""); - void createGroupingWorkspace(std::string const &instrumentName, std::string const &analyser, - std::string const &customGrouping, std::string const &outputName); - double loadDetailedBalance(std::string const &filename); - - std::vector groupWorkspaces(std::string const &groupName, std::string const &instrument, - std::string const &groupOption, bool const shouldGroup); void ungroupWorkspace(std::string const &workspaceName); void groupWorkspaceBySampleChanger(std::string const &workspaceName); -private: std::deque plotRawAlgorithmQueue(std::string const &rawFile, std::string const &basename, std::string const &instrumentName, std::vector const &detectorList, IETBackgroundData const &backgroundData) const; + + std::vector m_outputWorkspaces; }; } // namespace CustomInterfaces } // namespace MantidQt \ No newline at end of file diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferPresenter.cpp b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferPresenter.cpp index 0ade544b5d60..c0c84c56b3e4 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferPresenter.cpp +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferPresenter.cpp @@ -28,27 +28,22 @@ using MantidQt::API::BatchAlgorithmRunner; namespace MantidQt::CustomInterfaces { -IETPresenter::IETPresenter(IndirectDataReduction *idrUI, QWidget *parent) - : IndirectDataReductionTab(idrUI, parent), m_model(std::make_unique()), - m_view(std::make_unique(this, parent)) { +IETPresenter::IETPresenter(IIndirectDataReduction *idrUI, IIETView *view, std::unique_ptr model) + : IndirectDataReductionTab(idrUI), m_view(view), m_model(std::move(model)) { + m_view->subscribePresenter(this); setOutputPlotOptionsPresenter( std::make_unique(m_view->getPlotOptionsView(), PlotWidget::SpectraSliceSurface)); connect(this, SIGNAL(newInstrumentConfiguration()), this, SLOT(setInstrumentDefault())); - - connect(this, SIGNAL(updateRunButton(bool, std::string const &, QString const &, QString const &)), m_view.get(), - SLOT(updateRunButton(bool, std::string const &, QString const &, QString const &))); } -IETPresenter::~IETPresenter() = default; - void IETPresenter::setup() {} bool IETPresenter::validateInstrumentDetails() { auto const instrument = getInstrumentName().toStdString(); if (instrument.empty()) { - showMessageBox("Please select a valid facility and/or instrument."); + m_view->showMessageBox("Please select a valid facility and/or instrument."); return false; } @@ -57,8 +52,8 @@ bool IETPresenter::validateInstrumentDetails() { for (const auto &key : keys) { if (!instrumentDetails.contains(QString::fromStdString(key)) || instrumentDetails[QString::fromStdString(key)].isEmpty()) { - showMessageBox(QString::fromStdString("Could not find " + key + " for the " + instrument + - " instrument. Please select a valid instrument.")); + m_view->showMessageBox("Could not find " + key + " for the " + instrument + + " instrument. Please select a valid instrument."); return false; } } @@ -166,7 +161,7 @@ bool IETPresenter::validate() { QString error = uiv.generateErrorMessage(); if (!error.isEmpty()) - showMessageBox(error); + m_view->showMessageBox(error.toStdString()); return validateInstrumentDetails() && uiv.isAllInputValid(); } @@ -180,23 +175,26 @@ void IETPresenter::run() { connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(plotRawComplete(bool))); + m_view->setRunButtonText("Running..."); + m_view->setEnableOutputOptions(false); + m_outputGroupName = m_model->runIETAlgorithm(m_batchAlgoRunner, instrumentData, runData); } void IETPresenter::algorithmComplete(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); + m_view->setRunButtonText("Run"); + m_view->setEnableOutputOptions(!error); if (!error) { InstrumentData instrumentData = getInstrumentData(); - m_outputWorkspaces = m_model->groupWorkspaces(m_outputGroupName, instrumentData.getInstrument(), - m_view->getGroupOutputOption(), m_view->getGroupOutputCheckbox()); - m_pythonExportWsName = m_outputWorkspaces[0]; - - if (m_outputWorkspaces.size() != 0) { - setOutputPlotOptionsWorkspaces(m_outputWorkspaces); - m_view->setOutputWorkspaces(m_outputWorkspaces); - m_view->setSaveEnabled(true); - } + auto const outputWorkspaceNames = + m_model->groupWorkspaces(m_outputGroupName, instrumentData.getInstrument(), m_view->getGroupOutputOption(), + m_view->getGroupOutputCheckbox()); + m_pythonExportWsName = outputWorkspaceNames[0]; + + setOutputPlotOptionsWorkspaces(outputWorkspaceNames); + m_view->setSaveEnabled(!outputWorkspaceNames.empty()); } } @@ -217,7 +215,7 @@ void IETPresenter::notifyPlotRawClicked() { m_view->setPlotTimeIsPlotting(false); for (auto const &error : errors) { if (!error.empty()) - showMessageBox(QString::fromStdString(error)); + m_view->showMessageBox(error); } } } @@ -237,7 +235,7 @@ void IETPresenter::plotRawComplete(bool error) { void IETPresenter::notifySaveClicked() { IETSaveData saveData = m_view->getSaveData(); - for (auto const &workspaceName : m_outputWorkspaces) + for (auto const &workspaceName : m_model->outputWorkspaceNames()) if (WorkspaceUtils::doesExistInADS(workspaceName)) m_model->saveWorkspace(workspaceName, saveData); } @@ -261,12 +259,11 @@ void IETPresenter::notifySaveCustomGroupingClicked(std::string const &customGrou void IETPresenter::notifyRunFinished() { if (!m_view->isRunFilesValid()) { - m_view->updateRunButton(false, "unchanged", "Invalid Run(s)", - "Cannot find data files for some of the run numbers entered."); + m_view->setRunButtonText("Invalid Run(s)"); } else { double detailedBalance = m_model->loadDetailedBalance(m_view->getFirstFilename()); m_view->setDetailedBalance(detailedBalance); - m_view->updateRunButton(); + m_view->setRunButtonText("Run"); } m_view->setRunFilesEnabled(true); } @@ -281,11 +278,4 @@ void IETPresenter::setFileExtensionsByName(bool filter) { m_view->setFileExtensionsByName(fbSuffixes, wsSuffixes); } -void IETPresenter::updateRunButton(bool enabled, std::string const &enableOutputButtons, QString const &message, - QString const &tooltip) { - m_view->updateRunButton(enabled, enableOutputButtons, message, tooltip); -} - -void IETPresenter::notifyNewMessage(QString const &message) { showMessageBox(message); } - } // namespace MantidQt::CustomInterfaces \ No newline at end of file diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferPresenter.h b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferPresenter.h index 87276856887f..9415206d9aa1 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferPresenter.h +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferPresenter.h @@ -15,17 +15,25 @@ namespace MantidQt { namespace CustomInterfaces { -class MANTIDQT_INDIRECT_DLL IETPresenter : public IndirectDataReductionTab, public IETViewSubscriber { + +class MANTIDQT_INDIRECT_DLL IIETPresenter { +public: + virtual void notifySaveClicked() = 0; + virtual void notifyRunClicked() = 0; + virtual void notifyPlotRawClicked() = 0; + virtual void notifySaveCustomGroupingClicked(std::string const &customGrouping) = 0; + virtual void notifyRunFinished() = 0; +}; + +class MANTIDQT_INDIRECT_DLL IETPresenter : public IndirectDataReductionTab, public IIETPresenter { Q_OBJECT public: - IETPresenter(IndirectDataReduction *idrUI, QWidget *parent = nullptr); - ~IETPresenter() override; + IETPresenter(IIndirectDataReduction *idrUI, IIETView *view, std::unique_ptr model); void setup() override; void run() override; - void notifyNewMessage(const QString &message) override; void notifySaveClicked() override; void notifyRunClicked() override; void notifyPlotRawClicked() override; @@ -38,9 +46,6 @@ public slots: private slots: void algorithmComplete(bool error); void plotRawComplete(bool error); - - void updateRunButton(bool enabled = true, std::string const &enableOutputButtons = "unchanged", - QString const &message = "Run", QString const &tooltip = ""); void setInstrumentDefault(); private: @@ -51,10 +56,9 @@ private slots: void setFileExtensionsByName(bool filter) override; std::string m_outputGroupName; - std::vector m_outputWorkspaces; - std::unique_ptr m_model; - std::unique_ptr m_view; + IIETView *m_view; + std::unique_ptr m_model; }; } // namespace CustomInterfaces } // namespace MantidQt \ No newline at end of file diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferView.cpp b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferView.cpp index e6fcdf1da332..e5c89c25bbed 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferView.cpp +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferView.cpp @@ -8,6 +8,7 @@ #include "ISISEnergyTransferView.h" #include "Common/DetectorGroupingOptions.h" #include "Common/IndirectDataValidationHelper.h" +#include "ISISEnergyTransferPresenter.h" #include "MantidQtWidgets/Common/AlgorithmDialog.h" #include "MantidQtWidgets/Common/InterfaceManager.h" @@ -19,7 +20,7 @@ using namespace MantidQt::API; namespace MantidQt::CustomInterfaces { -IETView::IETView(IETViewSubscriber *subscriber, QWidget *parent) : m_subscriber(subscriber) { +IETView::IETView(QWidget *parent) { m_uiForm.setupUi(parent); connect(m_uiForm.pbPlotTime, SIGNAL(clicked()), this, SLOT(plotRawClicked())); @@ -38,7 +39,7 @@ IETView::IETView(IETViewSubscriber *subscriber, QWidget *parent) : m_subscriber( SLOT(saveCustomGroupingClicked(std::string const &))); } -IETView::~IETView() {} +void IETView::subscribePresenter(IIETPresenter *presenter) { m_presenter = presenter; } IETRunData IETView::getRunData() const { IETInputData inputDetails(m_uiForm.dsRunFiles->getFilenames().join(",").toStdString(), @@ -95,7 +96,7 @@ std::string IETView::getGroupOutputOption() const { return m_uiForm.cbGroupOutpu bool IETView::getGroupOutputCheckbox() const { return m_uiForm.ckGroupOutput->isChecked(); } -OutputPlotOptionsView *IETView::getPlotOptionsView() const { return m_uiForm.ipoPlotOptions; } +IOutputPlotOptionsView *IETView::getPlotOptionsView() const { return m_uiForm.ipoPlotOptions; } std::string IETView::getFirstFilename() const { return m_uiForm.dsRunFiles->getFirstFilename().toStdString(); } @@ -187,7 +188,6 @@ void IETView::setSingleRebin(bool enable) { void IETView::setMultipleRebin(bool enable) { m_uiForm.valRebinString->setVisible(enable); } void IETView::setSaveEnabled(bool enable) { - enable = !m_outputWorkspaces.empty() ? enable : false; m_uiForm.pbSave->setEnabled(enable); m_uiForm.ckSaveAclimax->setEnabled(enable); m_uiForm.ckSaveASCII->setEnabled(enable); @@ -198,7 +198,7 @@ void IETView::setSaveEnabled(bool enable) { void IETView::setPlotTimeIsPlotting(bool plotting) { m_uiForm.pbPlotTime->setText(plotting ? "Plotting..." : "Plot"); - setButtonsEnabled(!plotting); + setEnableOutputOptions(!plotting); } void IETView::setFileExtensionsByName(QStringList calibrationFbSuffixes, QStringList calibrationWSSuffixes) { @@ -206,10 +206,6 @@ void IETView::setFileExtensionsByName(QStringList calibrationFbSuffixes, QString m_uiForm.dsCalibrationFile->setWSSuffixes(calibrationWSSuffixes); } -void IETView::setOutputWorkspaces(std::vector const &outputWorkspaces) { - m_outputWorkspaces = outputWorkspaces; -} - void IETView::setInstrumentSpectraRange(int specMin, int specMax) { m_uiForm.spSpectraMin->setRange(specMin, specMax); m_uiForm.spSpectraMin->setValue(specMin); @@ -276,31 +272,33 @@ void IETView::setInstrumentSpecDefault(std::map &specMap) { m_uiForm.ckFold->setChecked(specMap["defaultFoldMultiple"]); } -void IETView::updateRunButton(bool enabled, std::string const &enableOutputButtons, QString const &message, - QString const &tooltip) { - setRunEnabled(enabled); - m_uiForm.pbRun->setText(message); - m_uiForm.pbRun->setToolTip(tooltip); - if (enableOutputButtons != "unchanged") { - auto const enableButtons = enableOutputButtons == "enable"; - setPlotTimeEnabled(enableButtons); - setSaveEnabled(enableButtons); - } +void IETView::setRunButtonText(std::string const &runText) { + m_uiForm.pbRun->setText(QString::fromStdString(runText)); + m_uiForm.pbRun->setEnabled(runText == "Run"); + m_uiForm.pbRun->setToolTip(runText == "Invalid Run(s)" ? "Cannot find data files for some of the run numbers entered." + : ""); } -void IETView::showMessageBox(const QString &message) { m_subscriber->notifyNewMessage(message); } +void IETView::setEnableOutputOptions(bool const enable) { + setPlotTimeEnabled(enable); + setSaveEnabled(enable); +} -void IETView::saveClicked() { m_subscriber->notifySaveClicked(); } +void IETView::showMessageBox(std::string const &message) { + QMessageBox::warning(this, "Warning!", QString::fromStdString(message)); +} -void IETView::runClicked() { m_subscriber->notifyRunClicked(); } +void IETView::saveClicked() { m_presenter->notifySaveClicked(); } -void IETView::plotRawClicked() { m_subscriber->notifyPlotRawClicked(); } +void IETView::runClicked() { m_presenter->notifyRunClicked(); } + +void IETView::plotRawClicked() { m_presenter->notifyPlotRawClicked(); } void IETView::saveCustomGroupingClicked(std::string const &customGrouping) { - m_subscriber->notifySaveCustomGroupingClicked(customGrouping); + m_presenter->notifySaveCustomGroupingClicked(customGrouping); } -void IETView::pbRunFinished() { m_subscriber->notifyRunFinished(); } +void IETView::pbRunFinished() { m_presenter->notifyRunFinished(); } void IETView::handleDataReady() { UserInputValidator uiv; @@ -308,29 +306,20 @@ void IETView::handleDataReady() { auto const errorMessage = uiv.generateErrorMessage(); if (!errorMessage.isEmpty()) - emit showMessageBox(errorMessage); + showMessageBox(errorMessage.toStdString()); } -void IETView::pbRunEditing() { - updateRunButton(false, "unchanged", "Editing...", "Run numbers are currently being edited."); -} +void IETView::pbRunEditing() { setRunButtonText("Editing..."); } void IETView::pbRunFinding() { - updateRunButton(false, "unchanged", "Finding files...", "Searching for data files for the run numbers entered..."); + setRunButtonText("Finding files..."); m_uiForm.dsRunFiles->setEnabled(false); } -void IETView::setRunEnabled(bool enable) { m_uiForm.pbRun->setEnabled(enable); } - void IETView::setPlotTimeEnabled(bool enable) { m_uiForm.pbPlotTime->setEnabled(enable); m_uiForm.spPlotTimeSpecMin->setEnabled(enable); m_uiForm.spPlotTimeSpecMax->setEnabled(enable); } -void IETView::setButtonsEnabled(bool enable) { - setRunEnabled(enable); - setPlotTimeEnabled(enable); - setSaveEnabled(enable); -} } // namespace MantidQt::CustomInterfaces \ No newline at end of file diff --git a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferView.h b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferView.h index 0e24b95d774a..132a9ead5af5 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferView.h +++ b/qt/scientific_interfaces/Indirect/Reduction/ISISEnergyTransferView.h @@ -16,80 +16,131 @@ namespace MantidQt { namespace CustomInterfaces { class DetectorGroupingOptions; +class IIETPresenter; -class MANTIDQT_INDIRECT_DLL IETViewSubscriber { +class MANTIDQT_INDIRECT_DLL IIETView { public: - virtual void notifyNewMessage(const QString &message) = 0; - virtual void notifySaveClicked() = 0; - virtual void notifyRunClicked() = 0; - virtual void notifyPlotRawClicked() = 0; - virtual void notifySaveCustomGroupingClicked(std::string const &customGrouping) = 0; - virtual void notifyRunFinished() = 0; + virtual ~IIETView() = default; + + virtual void subscribePresenter(IIETPresenter *presenter) = 0; + + virtual IETRunData getRunData() const = 0; + virtual IETPlotData getPlotData() const = 0; + virtual IETSaveData getSaveData() const = 0; + + virtual std::string getGroupOutputOption() const = 0; + virtual IOutputPlotOptionsView *getPlotOptionsView() const = 0; + virtual bool getGroupOutputCheckbox() const = 0; + + virtual std::string getFirstFilename() const = 0; + + virtual bool isRunFilesValid() const = 0; + virtual void validateCalibrationFileType(UserInputValidator &uiv) const = 0; + virtual void validateRebinString(UserInputValidator &uiv) const = 0; + virtual std::optional validateGroupingProperties(std::size_t const &spectraMin, + std::size_t const &spectraMax) const = 0; + + virtual bool showRebinWidthPrompt() const = 0; + virtual void showSaveCustomGroupingDialog(std::string const &customGroupingOutput, + std::string const &defaultGroupingFilename, + std::string const &saveDirectory) const = 0; + virtual void displayWarning(std::string const &message) const = 0; + + virtual void setCalibVisible(bool visible) = 0; + virtual void setEfixedVisible(bool visible) = 0; + virtual void setBackgroundSectionVisible(bool visible) = 0; + virtual void setPlotTimeSectionVisible(bool visible) = 0; + virtual void setAnalysisSectionVisible(bool visible) = 0; + virtual void setPlottingOptionsVisible(bool visible) = 0; + virtual void setAclimaxSaveVisible(bool visible) = 0; + virtual void setSPEVisible(bool visible) = 0; + virtual void setFoldMultipleFramesVisible(bool visible) = 0; + virtual void setOutputInCm1Visible(bool visible) = 0; + virtual void setGroupOutputCheckBoxVisible(bool visible) = 0; + virtual void setGroupOutputDropdownVisible(bool visible) = 0; + + virtual void setDetailedBalance(double detailedBalance) = 0; + virtual void setRunFilesEnabled(bool enable) = 0; + virtual void setSingleRebin(bool enable) = 0; + virtual void setMultipleRebin(bool enable) = 0; + virtual void setSaveEnabled(bool enable) = 0; + virtual void setPlotTimeIsPlotting(bool plotting) = 0; + virtual void setFileExtensionsByName(QStringList calibrationFbSuffixes, QStringList calibrationWSSuffixes) = 0; + virtual void setRunButtonText(std::string const &runText) = 0; + virtual void setEnableOutputOptions(bool const enable) = 0; + + virtual void setInstrumentSpectraRange(int specMin, int specMax) = 0; + virtual void setInstrumentRebinning(std::vector const &rebinParams, std::string const &rebinText, + bool checked, int tabIndex) = 0; + virtual void setInstrumentEFixed(std::string const &instrumentName, double eFixed) = 0; + virtual void setInstrumentGrouping(std::string const &instrumentName) = 0; + virtual void setInstrumentSpecDefault(std::map &specMap) = 0; + + virtual void showMessageBox(std::string const &message) = 0; }; -class MANTIDQT_INDIRECT_DLL IETView : public QWidget { +class MANTIDQT_INDIRECT_DLL IETView : public QWidget, public IIETView { Q_OBJECT public: - IETView(IETViewSubscriber *subscriber, QWidget *parent = nullptr); - ~IETView(); + IETView(QWidget *parent = nullptr); - IETRunData getRunData() const; - IETPlotData getPlotData() const; - IETSaveData getSaveData() const; + void subscribePresenter(IIETPresenter *presenter) override; - std::string getGroupOutputOption() const; - OutputPlotOptionsView *getPlotOptionsView() const; - bool getGroupOutputCheckbox() const; + IETRunData getRunData() const override; + IETPlotData getPlotData() const override; + IETSaveData getSaveData() const override; - std::string getFirstFilename() const; + std::string getGroupOutputOption() const override; + IOutputPlotOptionsView *getPlotOptionsView() const override; + bool getGroupOutputCheckbox() const override; - bool isRunFilesValid() const; - void validateCalibrationFileType(UserInputValidator &uiv) const; - void validateRebinString(UserInputValidator &uiv) const; + std::string getFirstFilename() const override; + + bool isRunFilesValid() const override; + void validateCalibrationFileType(UserInputValidator &uiv) const override; + void validateRebinString(UserInputValidator &uiv) const override; std::optional validateGroupingProperties(std::size_t const &spectraMin, - std::size_t const &spectraMax) const; + std::size_t const &spectraMax) const override; - bool showRebinWidthPrompt() const; + bool showRebinWidthPrompt() const override; void showSaveCustomGroupingDialog(std::string const &customGroupingOutput, std::string const &defaultGroupingFilename, - std::string const &saveDirectory) const; - void displayWarning(std::string const &message) const; - - void setCalibVisible(bool visible); - void setEfixedVisible(bool visible); - void setBackgroundSectionVisible(bool visible); - void setPlotTimeSectionVisible(bool visible); - void setAnalysisSectionVisible(bool visible); - void setPlottingOptionsVisible(bool visible); - void setAclimaxSaveVisible(bool visible); - void setSPEVisible(bool visible); - void setFoldMultipleFramesVisible(bool visible); - void setOutputInCm1Visible(bool visible); - void setGroupOutputCheckBoxVisible(bool visible); - void setGroupOutputDropdownVisible(bool visible); - - void setDetailedBalance(double detailedBalance); - void setRunFilesEnabled(bool enable); - void setSingleRebin(bool enable); - void setMultipleRebin(bool enable); - void setSaveEnabled(bool enable); - void setPlotTimeIsPlotting(bool plotting); - void setFileExtensionsByName(QStringList calibrationFbSuffixes, QStringList calibrationWSSuffixes); - void setOutputWorkspaces(std::vector const &outputWorkspaces); - - void setInstrumentSpectraRange(int specMin, int specMax); + std::string const &saveDirectory) const override; + void displayWarning(std::string const &message) const override; + + void setCalibVisible(bool visible) override; + void setEfixedVisible(bool visible) override; + void setBackgroundSectionVisible(bool visible) override; + void setPlotTimeSectionVisible(bool visible) override; + void setAnalysisSectionVisible(bool visible) override; + void setPlottingOptionsVisible(bool visible) override; + void setAclimaxSaveVisible(bool visible) override; + void setSPEVisible(bool visible) override; + void setFoldMultipleFramesVisible(bool visible) override; + void setOutputInCm1Visible(bool visible) override; + void setGroupOutputCheckBoxVisible(bool visible) override; + void setGroupOutputDropdownVisible(bool visible) override; + + void setDetailedBalance(double detailedBalance) override; + void setRunFilesEnabled(bool enable) override; + void setSingleRebin(bool enable) override; + void setMultipleRebin(bool enable) override; + void setSaveEnabled(bool enable) override; + void setPlotTimeIsPlotting(bool plotting) override; + void setFileExtensionsByName(QStringList calibrationFbSuffixes, QStringList calibrationWSSuffixes) override; + void setRunButtonText(std::string const &runText) override; + void setEnableOutputOptions(bool const enable) override; + + void setInstrumentSpectraRange(int specMin, int specMax) override; void setInstrumentRebinning(std::vector const &rebinParams, std::string const &rebinText, bool checked, - int tabIndex); - void setInstrumentEFixed(std::string const &instrumentName, double eFixed); - void setInstrumentGrouping(std::string const &instrumentName); - void setInstrumentSpecDefault(std::map &specMap); + int tabIndex) override; + void setInstrumentEFixed(std::string const &instrumentName, double eFixed) override; + void setInstrumentGrouping(std::string const &instrumentName) override; + void setInstrumentSpecDefault(std::map &specMap) override; -public slots: - void updateRunButton(bool enabled = true, std::string const &enableOutputButtons = "unchanged", - QString const &message = "Run", QString const &tooltip = ""); + void showMessageBox(std::string const &message) override; private slots: - void showMessageBox(const QString &message); void saveClicked(); void runClicked(); void plotRawClicked(); @@ -102,13 +153,10 @@ private slots: void pbRunFinding(); private: - void setRunEnabled(bool enable); void setPlotTimeEnabled(bool enable); - void setButtonsEnabled(bool enable); - std::vector m_outputWorkspaces; Ui::ISISEnergyTransfer m_uiForm; - IETViewSubscriber *m_subscriber; + IIETPresenter *m_presenter; DetectorGroupingOptions *m_groupingWidget; }; } // namespace CustomInterfaces diff --git a/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReduction.cpp b/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReduction.cpp index 0170bc09423b..0fdd5c95d527 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReduction.cpp +++ b/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReduction.cpp @@ -77,7 +77,7 @@ void IndirectDataReduction::initLayout() { m_uiForm.pbSettings->setIcon(Settings::icon()); // Create the tabs - addTab("ISIS Energy Transfer"); + addMVPTab("ISIS Energy Transfer"); addTab("ISIS Calibration"); addTab("ISIS Diagnostics"); addTab("Transmission"); @@ -210,6 +210,10 @@ void IndirectDataReduction::loadInstrumentIfNotExist(const std::string &instrume } } +MantidWidgets::IInstrumentConfig *IndirectDataReduction::getInstrumentConfiguration() const { + return m_uiForm.iicInstrumentConfiguration; +} + /** * Gets the details for the current instrument configuration. * diff --git a/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReduction.h b/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReduction.h index 2eddc0bbb695..166a1a9c1510 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReduction.h +++ b/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReduction.h @@ -22,6 +22,18 @@ namespace CustomInterfaces { class IndirectDataReductionTab; +class IIndirectDataReduction { +public: + virtual ~IIndirectDataReduction() = default; + + virtual Mantid::API::MatrixWorkspace_sptr instrumentWorkspace() = 0; + + virtual MantidWidgets::IInstrumentConfig *getInstrumentConfiguration() const = 0; + virtual QMap getInstrumentDetails() = 0; + + virtual void showAnalyserAndReflectionOptions(bool visible) = 0; +}; + /** This class defines the IndirectDataReduction interface. It handles the overall instrument settings @@ -33,7 +45,7 @@ mode is defined in the instrument definition file using the "deltaE-mode". @author Michael Whitty */ -class IndirectDataReduction : public IndirectInterface { +class IndirectDataReduction : public IndirectInterface, public IIndirectDataReduction { Q_OBJECT public: @@ -54,14 +66,15 @@ class IndirectDataReduction : public IndirectInterface { /// Handled configuration changes void handleConfigChange(Mantid::Kernel::ConfigValChangeNotification_ptr pNf); - Mantid::API::MatrixWorkspace_sptr instrumentWorkspace(); + Mantid::API::MatrixWorkspace_sptr instrumentWorkspace() override; void loadInstrumentIfNotExist(const std::string &instrumentName, const std::string &analyser = "", const std::string &reflection = ""); - QMap getInstrumentDetails(); + MantidWidgets::IInstrumentConfig *getInstrumentConfiguration() const override; + QMap getInstrumentDetails() override; - void showAnalyserAndReflectionOptions(bool visible); + void showAnalyserAndReflectionOptions(bool visible) override; signals: /// Emitted when the instrument setup is changed @@ -130,6 +143,44 @@ private slots: m_uiForm.twIDRTabs->addTab(tabWidget, name); } + /** + * Adds an MVP tab to the cache of tabs that can be shown. + * + * This method is used to ensure that the tabs are always loaded and their + * layouts setup for the sake of screenshoting them for documentation. + * + * @param name Name to be displayed on tab + */ + + template void addMVPTab(const QString &name) { + QWidget *tabWidget = new QWidget(m_uiForm.twIDRTabs); + QVBoxLayout *tabLayout = new QVBoxLayout(tabWidget); + tabWidget->setLayout(tabLayout); + + QScrollArea *tabScrollArea = new QScrollArea(tabWidget); + tabLayout->addWidget(tabScrollArea); + tabScrollArea->setWidgetResizable(true); + + QWidget *tabContent = new QWidget(tabScrollArea); + tabContent->setObjectName("tab" + QString(name).remove(QRegExp("[ ,()]"))); + tabScrollArea->setWidget(tabContent); + tabScrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + IndirectDataReductionTab *tabIDRContent = + new TabPresenter(this, new TabView(tabContent), std::make_unique()); + + tabIDRContent->setupTab(); + tabContent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + connect(tabIDRContent, SIGNAL(showMessageBox(const QString &)), this, SLOT(showMessageBox(const QString &))); + + // Add to the cache + m_tabs[name] = qMakePair(tabWidget, tabIDRContent); + + // Add all tabs to UI initially + m_uiForm.twIDRTabs->addTab(tabWidget, name); + } + friend class IndirectDataReductionTab; /// The .ui form generated by Qt Designer Ui::IndirectDataReduction m_uiForm; diff --git a/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReductionTab.cpp b/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReductionTab.cpp index 580ae72b586f..76c50e3e3d76 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReductionTab.cpp +++ b/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReductionTab.cpp @@ -24,7 +24,7 @@ Mantid::Kernel::Logger g_log("IndirectDataReductionTab"); namespace MantidQt::CustomInterfaces { -IndirectDataReductionTab::IndirectDataReductionTab(IndirectDataReduction *idrUI, QObject *parent) +IndirectDataReductionTab::IndirectDataReductionTab(IIndirectDataReduction *idrUI, QObject *parent) : IndirectTab(parent), m_idrUI(idrUI), m_tabRunning(false) { connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(tabExecutionComplete(bool))); } @@ -127,8 +127,8 @@ bool IndirectDataReductionTab::hasInstrumentDetail(QMap const * * @return Instrument config widget */ -MantidWidgets::IndirectInstrumentConfig *IndirectDataReductionTab::getInstrumentConfiguration() const { - return m_idrUI->m_uiForm.iicInstrumentConfiguration; +MantidWidgets::IInstrumentConfig *IndirectDataReductionTab::getInstrumentConfiguration() const { + return m_idrUI->getInstrumentConfiguration(); } QString IndirectDataReductionTab::getInstrumentName() const { diff --git a/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReductionTab.h b/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReductionTab.h index 874fbdd5ee07..be5e3cd16873 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReductionTab.h +++ b/qt/scientific_interfaces/Indirect/Reduction/IndirectDataReductionTab.h @@ -31,7 +31,7 @@ namespace MantidQt { namespace CustomInterfaces { -class IndirectDataReduction; +class IIndirectDataReduction; /** IndirectDataReductionTab @@ -45,7 +45,7 @@ class MANTIDQT_INDIRECT_DLL IndirectDataReductionTab : public IndirectTab { Q_OBJECT public: - IndirectDataReductionTab(IndirectDataReduction *idrUI, QObject *parent = nullptr); + IndirectDataReductionTab(IIndirectDataReduction *idrUI, QObject *parent = nullptr); ~IndirectDataReductionTab() override; /// Set the presenter for the output plotting options @@ -75,7 +75,7 @@ public slots: void validateInstrumentDetail(QString const &key) const; bool hasInstrumentDetail(QString const &key) const; bool hasInstrumentDetail(QMap const &instrumentDetails, QString const &key) const; - MantidWidgets::IndirectInstrumentConfig *getInstrumentConfiguration() const; + MantidWidgets::IInstrumentConfig *getInstrumentConfiguration() const; QString getInstrumentName() const; QString getAnalyserName() const; QString getReflectionName() const; @@ -84,7 +84,7 @@ public slots: QString reflection = ""); protected: - IndirectDataReduction *m_idrUI; + IIndirectDataReduction *m_idrUI; private slots: void tabExecutionComplete(bool error); diff --git a/qt/scientific_interfaces/Indirect/Reduction/IndirectTransmission.cpp b/qt/scientific_interfaces/Indirect/Reduction/IndirectTransmission.cpp index 24a367e13727..d1f98f6e12b6 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/IndirectTransmission.cpp +++ b/qt/scientific_interfaces/Indirect/Reduction/IndirectTransmission.cpp @@ -28,7 +28,7 @@ namespace MantidQt::CustomInterfaces { //---------------------------------------------------------------------------------------------- /** Constructor */ -IndirectTransmission::IndirectTransmission(IndirectDataReduction *idrUI, QWidget *parent) +IndirectTransmission::IndirectTransmission(IIndirectDataReduction *idrUI, QWidget *parent) : IndirectDataReductionTab(idrUI, parent) { m_uiForm.setupUi(parent); setOutputPlotOptionsPresenter( diff --git a/qt/scientific_interfaces/Indirect/Reduction/IndirectTransmission.h b/qt/scientific_interfaces/Indirect/Reduction/IndirectTransmission.h index 5a42c29aa469..c73e4fa02d8a 100644 --- a/qt/scientific_interfaces/Indirect/Reduction/IndirectTransmission.h +++ b/qt/scientific_interfaces/Indirect/Reduction/IndirectTransmission.h @@ -13,21 +13,13 @@ namespace MantidQt { namespace CustomInterfaces { -/** IndirectTransmission +class IIndirectDataReduction; - Provides the UI interface to the IndirectTransmissionMonitor algorithm to - calculate - sample transmission using a sample and container raw run file. - - - @author Samuel Jackson - @date 13/08/2013 -*/ class MANTIDQT_INDIRECT_DLL IndirectTransmission : public IndirectDataReductionTab { Q_OBJECT public: - IndirectTransmission(IndirectDataReduction *idrUI, QWidget *parent = nullptr); + IndirectTransmission(IIndirectDataReduction *idrUI, QWidget *parent = nullptr); ~IndirectTransmission() override; void setup() override; diff --git a/qt/scientific_interfaces/Indirect/test/CMakeLists.txt b/qt/scientific_interfaces/Indirect/test/CMakeLists.txt index a609eac50e37..202fc31154fd 100644 --- a/qt/scientific_interfaces/Indirect/test/CMakeLists.txt +++ b/qt/scientific_interfaces/Indirect/test/CMakeLists.txt @@ -1,5 +1,7 @@ set(ALL_TEST_FILES) +set(ALL_TEST_HELPERS) +add_subdirectory(Common) add_subdirectory(Reduction) set(CXXTEST_EXTRA_HEADER_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/InterfacesIndirectTestInitialization.h) @@ -9,6 +11,7 @@ mtd_add_qt_tests( QT_VERSION 5 SRC ${ALL_TEST_FILES} INCLUDE_DIRS ../../../../Framework/DataObjects/inc ../ + TEST_HELPER_SRCS ${ALL_TEST_HELPERS} LINK_LIBS ${CORE_MANTIDLIBS} Mantid::DataObjects gmock diff --git a/qt/scientific_interfaces/Indirect/test/Common/CMakeLists.txt b/qt/scientific_interfaces/Indirect/test/Common/CMakeLists.txt new file mode 100644 index 000000000000..aecc4af95acd --- /dev/null +++ b/qt/scientific_interfaces/Indirect/test/Common/CMakeLists.txt @@ -0,0 +1,10 @@ +get_filename_component(SUB_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" NAME) + +set(TEST_HELPERS MockObjects.h) + +list(TRANSFORM TEST_HELPERS PREPEND ${SUB_DIRECTORY}/) + +set(ALL_TEST_HELPERS + ${ALL_TEST_HELPERS} ${TEST_HELPERS} + PARENT_SCOPE +) diff --git a/qt/scientific_interfaces/Indirect/test/Common/MockObjects.h b/qt/scientific_interfaces/Indirect/test/Common/MockObjects.h new file mode 100644 index 000000000000..6cf9c987db05 --- /dev/null +++ b/qt/scientific_interfaces/Indirect/test/Common/MockObjects.h @@ -0,0 +1,57 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2024 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source +// & Institut Laue - Langevin +// SPDX - License - Identifier: GPL - 3.0 + +#pragma once + +#include +#include + +#include "MantidKernel/WarningSuppressions.h" + +#include "Common/IndirectInstrumentConfig.h" + +#include +#include + +using namespace MantidQt::MantidWidgets; + +GNU_DIAG_OFF_SUGGEST_OVERRIDE + +class MockInstrumentConfig : public IInstrumentConfig { +public: + virtual ~MockInstrumentConfig() = default; + + MOCK_METHOD0(getTechniques, QStringList()); + MOCK_METHOD1(setTechniques, void(const QStringList &techniques)); + + MOCK_METHOD0(getDisabledInstruments, QStringList()); + MOCK_METHOD1(setDisabledInstruments, void(const QStringList &instrumentNames)); + + MOCK_METHOD0(getFacility, QString()); + MOCK_METHOD1(setFacility, void(const QString &facilityName)); + + MOCK_METHOD0(isDiffractionEnabled, bool()); + MOCK_METHOD1(enableDiffraction, void(bool enabled)); + + MOCK_METHOD0(isDiffractionForced, bool()); + MOCK_METHOD1(forceDiffraction, void(bool forced)); + + MOCK_METHOD0(isInstrumentLabelShown, bool()); + MOCK_METHOD1(setShowInstrumentLabel, void(bool visible)); + + MOCK_METHOD0(getInstrumentName, QString()); + MOCK_METHOD1(setInstrument, void(const QString &instrumentName)); + + MOCK_METHOD0(getAnalyserName, QString()); + MOCK_METHOD1(setAnalyser, void(const QString &analyserName)); + + MOCK_METHOD0(getReflectionName, QString()); + MOCK_METHOD1(setReflection, void(const QString &reflectionName)); + + MOCK_METHOD1(showAnalyserAndReflectionOptions, void(bool visible)); +}; + +GNU_DIAG_ON_SUGGEST_OVERRIDE \ No newline at end of file diff --git a/qt/scientific_interfaces/Indirect/test/Reduction/CMakeLists.txt b/qt/scientific_interfaces/Indirect/test/Reduction/CMakeLists.txt index ef34ea0fd594..b3befd608c74 100644 --- a/qt/scientific_interfaces/Indirect/test/Reduction/CMakeLists.txt +++ b/qt/scientific_interfaces/Indirect/test/Reduction/CMakeLists.txt @@ -1,10 +1,19 @@ get_filename_component(SUB_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" NAME) -set(TEST_FILES ISISEnergyTransferModelTest.h ISISEnergyTransferModelUtilsTest.h ReductionAlgorithmUtilsTest.h) +set(TEST_FILES ISISEnergyTransferModelTest.h ISISEnergyTransferModelUtilsTest.h ISISEnergyTransferPresenterTest.h + ReductionAlgorithmUtilsTest.h +) + +set(TEST_HELPERS MockObjects.h) list(TRANSFORM TEST_FILES PREPEND ${SUB_DIRECTORY}/) +list(TRANSFORM TEST_HELPERS PREPEND ${SUB_DIRECTORY}/) set(ALL_TEST_FILES ${ALL_TEST_FILES} ${TEST_FILES} PARENT_SCOPE ) +set(ALL_TEST_HELPERS + ${ALL_TEST_HELPERS} ${TEST_HELPERS} + PARENT_SCOPE +) diff --git a/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferModelTest.h b/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferModelTest.h index f2eb1a4dd5fe..276b5c917954 100644 --- a/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferModelTest.h +++ b/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferModelTest.h @@ -130,17 +130,24 @@ DECLARE_ALGORITHM(ISISIndirectEnergyTransfer) class ISISEnergyTransferModelTest : public CxxTest::TestSuite { public: - ISISEnergyTransferModelTest() = default; - void setUp() override { AnalysisDataService::Instance().clear(); } + static ISISEnergyTransferModelTest *createSuite() { return new ISISEnergyTransferModelTest(); } + static void destroySuite(ISISEnergyTransferModelTest *suite) { delete suite; } - void tearDown() override { AnalysisDataService::Instance().clear(); } + void setUp() override { + m_model = std::make_unique(); + AnalysisDataService::Instance().clear(); + } + + void tearDown() override { + m_model.reset(); + AnalysisDataService::Instance().clear(); + } void testSetInstrumentProperties() { - auto model = makeModel(); auto properties = std::make_unique(); InstrumentData instData("instrument", "analyser", "reflection"); - model->setInstrumentProperties(*properties, instData); + m_model->setInstrumentProperties(*properties, instData); TS_ASSERT_EQUALS(properties->getPropertyValue("Instrument"), "instrument"); TS_ASSERT_EQUALS(properties->getPropertyValue("Analyser"), "analyser"); @@ -148,11 +155,10 @@ class ISISEnergyTransferModelTest : public CxxTest::TestSuite { } void testSetInputPropertiesWithAllEnabled() { - auto model = makeModel(); auto properties = std::make_unique(); IETInputData inputData("input_workspace", "input_workspace", true, true, true, "calibration_workspace"); - model->setInputProperties(*properties, inputData); + m_model->setInputProperties(*properties, inputData); TS_ASSERT_EQUALS(properties->getPropertyValue("InputFiles"), "input_workspace"); TS_ASSERT_EQUALS(properties->getPropertyValue("SumFiles"), "1"); @@ -161,11 +167,10 @@ class ISISEnergyTransferModelTest : public CxxTest::TestSuite { } void testSetInputPropertiesWithAllDisabled() { - auto model = makeModel(); auto properties = std::make_unique(); IETInputData inputData("input_workspace", "input_workspace", false, false, false, ""); - model->setInputProperties(*properties, inputData); + m_model->setInputProperties(*properties, inputData); TS_ASSERT_EQUALS(properties->getPropertyValue("InputFiles"), "input_workspace"); TS_ASSERT_EQUALS(properties->getPropertyValue("SumFiles"), "0"); @@ -174,123 +179,111 @@ class ISISEnergyTransferModelTest : public CxxTest::TestSuite { } void testSetConversionPropertiesWithoutEfixed() { - auto model = makeModel(); auto properties = std::make_unique(); IETConversionData conversionData(1.0, 1, 2); - model->setConversionProperties(*properties, conversionData, "instrument"); + m_model->setConversionProperties(*properties, conversionData, "instrument"); TS_ASSERT(!properties->existsProperty("Efixed")); TS_ASSERT_EQUALS(properties->getPropertyValue("SpectraRange"), "1, 2"); } void testSetConversionPropertiesWithEfixed() { - auto model = makeModel(); auto properties = std::make_unique(); IETConversionData conversionData(1.0, 1, 2); - model->setConversionProperties(*properties, conversionData, "IRIS"); + m_model->setConversionProperties(*properties, conversionData, "IRIS"); TS_ASSERT_EQUALS(properties->getPropertyValue("Efixed"), "1"); TS_ASSERT_EQUALS(properties->getPropertyValue("SpectraRange"), "1, 2"); } void testSetBackgroundPropertiesWithBackgroundEnabled() { - auto model = makeModel(); auto properties = std::make_unique(); IETBackgroundData backgroundData(true, 1.0, 2.0); - model->setBackgroundProperties(*properties, backgroundData); + m_model->setBackgroundProperties(*properties, backgroundData); TS_ASSERT_EQUALS(properties->getPropertyValue("BackgroundRange"), "1, 2"); } void testSetBackgroundPropertiesWithBackgroundDisabled() { - auto model = makeModel(); auto properties = std::make_unique(); IETBackgroundData backgroundData(false, 1.0, 2.0); - model->setBackgroundProperties(*properties, backgroundData); + m_model->setBackgroundProperties(*properties, backgroundData); TS_ASSERT(!properties->existsProperty("BackgroundRange")); } void testSetRebinPropertiesWithMultipleRebin() { - auto model = makeModel(); auto properties = std::make_unique(); IETRebinData rebinData(true, "Multiple", 1.0, 2.0, 3.0, "1,2,10"); - model->setRebinProperties(*properties, rebinData); + m_model->setRebinProperties(*properties, rebinData); TS_ASSERT_EQUALS(properties->getPropertyValue("RebinString"), "1,2,10"); } void testSetRebinPropertiesWithMultipleLogRebin() { - auto model = makeModel(); auto properties = std::make_unique(); IETRebinData rebinData(true, "Multiple", 1.0, 2.0, 3.0, "2,-0.035,10"); - model->setRebinProperties(*properties, rebinData); + m_model->setRebinProperties(*properties, rebinData); TS_ASSERT_EQUALS(properties->getPropertyValue("RebinString"), "2,-0.035,10"); } void testSetRebinPropertiesWithMultipleVariableRangeRebin() { - auto model = makeModel(); auto properties = std::make_unique(); IETRebinData rebinData(true, "Multiple", 1.0, 2.0, 3.0, "0,2,10,4,20"); - model->setRebinProperties(*properties, rebinData); + m_model->setRebinProperties(*properties, rebinData); TS_ASSERT_EQUALS(properties->getPropertyValue("RebinString"), "0,2,10,4,20"); } void testSetRebinPropertiesWithSingleRebin() { - auto model = makeModel(); auto properties = std::make_unique(); IETRebinData rebinData(true, "Single", 0.0, 2.0, 6.0, ""); - model->setRebinProperties(*properties, rebinData); + m_model->setRebinProperties(*properties, rebinData); TS_ASSERT_EQUALS(properties->getPropertyValue("RebinString"), "0.000000,6.000000,2.000000"); } void testSetRebinPropertiesWithNoRebin() { - auto model = makeModel(); auto properties = std::make_unique(); IETRebinData rebinData(false, "Single", 0.0, 0.0, 0.0, "1.0, 3.0, 5.0"); - model->setRebinProperties(*properties, rebinData); + m_model->setRebinProperties(*properties, rebinData); TS_ASSERT(!properties->existsProperty("RebinString")); } void testSetAnalysisPropertiesWithPropsEnabled() { - auto model = makeModel(); auto properties = std::make_unique(); IETAnalysisData analysisData(true, 2.5); - model->setAnalysisProperties(*properties, analysisData); + m_model->setAnalysisProperties(*properties, analysisData); TS_ASSERT_EQUALS(properties->getPropertyValue("DetailedBalance"), "2.5"); } void testSetAnalysisPropertiesWithPropsDisabled() { - auto model = makeModel(); auto properties = std::make_unique(); IETAnalysisData analysisData(false, 2.5); - model->setAnalysisProperties(*properties, analysisData); + m_model->setAnalysisProperties(*properties, analysisData); TS_ASSERT(!properties->existsProperty("DetailedBalance")); } void testSetOutputPropertiesWithPropsEnabled() { - auto model = makeModel(); auto properties = std::make_unique(); IETOutputData outputData(true, true); - model->setOutputProperties(*properties, outputData, "output"); + m_model->setOutputProperties(*properties, outputData, "output"); TS_ASSERT_EQUALS(properties->getPropertyValue("UnitX"), "DeltaE_inWavenumber"); TS_ASSERT_EQUALS(properties->getPropertyValue("FoldMultipleFrames"), "1"); @@ -298,11 +291,10 @@ class ISISEnergyTransferModelTest : public CxxTest::TestSuite { } void testSetOutputPropertiesWithPropsDisabled() { - auto model = makeModel(); auto properties = std::make_unique(); IETOutputData outputData(false, false); - model->setOutputProperties(*properties, outputData, "output"); + m_model->setOutputProperties(*properties, outputData, "output"); TS_ASSERT(!properties->existsProperty("UnitX")); TS_ASSERT_EQUALS(properties->getPropertyValue("FoldMultipleFrames"), "0"); @@ -310,11 +302,10 @@ class ISISEnergyTransferModelTest : public CxxTest::TestSuite { } void testGetOutputGroupName() { - auto model = makeModel(); InstrumentData instData("instrument", "analyser", "reflection"); std::string inputFiles("1234, 1235"); - std::string outputName = model->getOuputGroupName(instData, inputFiles); + std::string outputName = m_model->getOutputGroupName(instData, inputFiles); TS_ASSERT_EQUALS(outputName, "instrument1234, 1235_analyser_reflection_Reduced"); } @@ -520,8 +511,11 @@ class ISISEnergyTransferModelTest : public CxxTest::TestSuite { } private: - std::unique_ptr makeModel() { return std::make_unique(); } - IAlgorithm_sptr makeReductionAlgorithm() { return AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer"); } + IAlgorithm_sptr makeReductionAlgorithm() { + auto alg = AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer"); + alg->setLogging(false); + return alg; + } std::unique_ptr m_model; IAlgorithm_sptr m_reductionAlg; diff --git a/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferModelUtilsTest.h b/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferModelUtilsTest.h index 7e7103dfbf1f..2e04416877d3 100644 --- a/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferModelUtilsTest.h +++ b/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferModelUtilsTest.h @@ -20,7 +20,8 @@ using namespace MantidQt::CustomInterfaces; class ISISEnergyTransferModelUtilsTest : public CxxTest::TestSuite { public: - ISISEnergyTransferModelUtilsTest() = default; + static ISISEnergyTransferModelUtilsTest *createSuite() { return new ISISEnergyTransferModelUtilsTest(); } + static void destroySuite(ISISEnergyTransferModelUtilsTest *suite) { delete suite; } void testGetCustomGroupingNumbers() { auto result = getCustomGroupingNumbers("1,2,3-5,6"); diff --git a/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferPresenterTest.h b/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferPresenterTest.h index 1fde6fe86669..20077aa02d89 100644 --- a/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferPresenterTest.h +++ b/qt/scientific_interfaces/Indirect/test/Reduction/ISISEnergyTransferPresenterTest.h @@ -9,140 +9,115 @@ #include #include +#include "../../../Inelastic/test/Common/MockObjects.h" +#include "../Common/MockObjects.h" +#include "MockObjects.h" #include "Reduction/ISISEnergyTransferPresenter.h" -#include "Reduction/IndirectDataReduction.h" +#include "MantidFrameworkTestHelpers/IndirectFitDataCreationHelper.h" #include "MantidKernel/WarningSuppressions.h" using namespace MantidQt::CustomInterfaces; -using MantidQt::API::BatchAlgorithmRunner; using namespace testing; -GNU_DIAG_OFF_SUGGEST_OVERRIDE +namespace { -class MockIETModel : public IETModel { +IETSaveData createSaveData() { return IETSaveData(true, true, true, true, true); } -public: - MOCK_METHOD3(runIETAlgorithm, std::string(MantidQt::API::BatchAlgorithmRunner *, InstrumentData, IETRunData)); -}; - -class MockIETView : public IETView { -public: - MOCK_CONST_METHOD0(getRunData, IETRunData()); - MOCK_CONST_METHOD0(getPlotData, IETPlotData()); - MOCK_CONST_METHOD0(getSaveData, IETSaveData()); - - MOCK_CONST_METHOD0(getCustomGrouping, std::string()); - - MOCK_CONST_METHOD0(getGroupOutputOption, std::string()); - MOCK_CONST_METHOD0(getPlotOptionsView, IndirectPlotOptionsView *()); - MOCK_CONST_METHOD0(getGroupOutputCheckbox, bool()); - - MOCK_CONST_METHOD0(getFirstFilename, std::string()); - - MOCK_CONST_METHOD0(isRunFilesValid, bool()); - MOCK_CONST_METHOD1(validateCalibrationFileType, void(UserInputValidator &)); - MOCK_CONST_METHOD1(validateRebinString, void(UserInputValidator &uiv)); - - MOCK_CONST_METHOD0(showRebinWidthPrompt, bool()); - MOCK_CONST_METHOD3(showSaveCustomGroupingDialog, - void(std::string const &customGroupingOutput, std::string const &defaultGroupingFilename, - std::string const &saveDirectory)); - MOCK_CONST_METHOD1(displayWarning, void(std::string const &message)); - - MOCK_METHOD1(setBackgroundSectionVisible, void(bool visible)); - MOCK_METHOD1(setPlotTimeSectionVisible, void(bool visible)); - MOCK_METHOD1(setPlottingOptionsVisible, void(bool visible)); - MOCK_METHOD1(setScaleFactorVisible, void(bool visible)); - MOCK_METHOD1(setAclimaxSaveVisible, void(bool visible)); - MOCK_METHOD1(setNXSPEVisible, void(bool visible)); - MOCK_METHOD1(setFoldMultipleFramesVisible, void(bool visible)); - MOCK_METHOD1(setOutputInCm1Visible, void(bool visible)); - MOCK_METHOD1(setGroupOutputCheckBoxVisible, void(bool visible)); - MOCK_METHOD1(setGroupOutputDropdownVisible, void(bool visible)); - - MOCK_METHOD1(setDetailedBalance, void(double detailedBalance)); - MOCK_METHOD1(setRunFilesEnabled, void(bool enable)); - MOCK_METHOD1(setSingleRebin, void(bool enable)); - MOCK_METHOD1(setMultipleRebin, void(bool enable)); - MOCK_METHOD1(setSaveEnabled, void(bool enable)); - MOCK_METHOD1(setPlotTimeIsPlotting, void(bool plotting)); - MOCK_METHOD2(setFileExtensionsByName, void(QStringList calibrationFbSuffixes, QStringList calibrationWSSuffixes)); - MOCK_METHOD1(setOutputWorkspaces, void(std::vector const &outputWorkspaces)); - - MOCK_METHOD1(setInstrumentDefault, void(InstrumentData const &instrumentDetails)); - MOCK_METHOD4(updateRunButton, void(bool enabled, std::string const &enableOutputButtons, QString const &message, - QString const &tooltip)); -}; - -class MockIndirectDataReduction : public IndirectDataReduction { - Q_OBJECT +} // namespace +class ISISEnergyTransferPresenterTest : public CxxTest::TestSuite { public: - MockIndirectDataReduction() : IndirectDataReduction(nullptr) {} -}; - -class IETPresenterTest : public CxxTest::TestSuite { -public: - static IETPresenterTest *createSuite() { return new IETPresenterTest(); } - static void destroySuite(IETPresenterTest *suite) { delete suite; } + static ISISEnergyTransferPresenterTest *createSuite() { return new ISISEnergyTransferPresenterTest(); } + static void destroySuite(ISISEnergyTransferPresenterTest *suite) { delete suite; } void setUp() override { - auto view = std::make_unique>(); auto model = std::make_unique>(); - m_view = view.get(); + m_outputOptionsView = std::make_unique>(); + m_instrumentConfig = std::make_unique>(); + + m_view = std::make_unique>(); + ON_CALL(*m_view, getPlotOptionsView()).WillByDefault(Return(m_outputOptionsView.get())); + m_model = model.get(); - m_idrUI = new MockIndirectDataReduction(); + m_idrUI = std::make_unique>(); + ON_CALL(*m_idrUI, getInstrumentConfiguration()).WillByDefault(Return(m_instrumentConfig.get())); - m_presenter = std::make_unique(std::move(view), std::move(model), m_idrUI); + m_presenter = std::make_unique(m_idrUI.get(), m_view.get(), std::move(model)); } void tearDown() override { - TS_ASSERT(Mock::VerifyAndClearExpectations(m_view)); + TS_ASSERT(Mock::VerifyAndClearExpectations(&m_outputOptionsView)); + TS_ASSERT(Mock::VerifyAndClearExpectations(&m_instrumentConfig)); + TS_ASSERT(Mock::VerifyAndClearExpectations(&m_view)); TS_ASSERT(Mock::VerifyAndClearExpectations(m_model)); - TS_ASSERT(Mock::VerifyAndClearExpectations(m_idrUI)); + TS_ASSERT(Mock::VerifyAndClearExpectations(&m_idrUI)); m_presenter.reset(); + m_idrUI.reset(); + m_view.reset(); + m_outputOptionsView.reset(); + m_instrumentConfig.reset(); + } + + void test_notifySaveClicked_will_not_save_the_workspace_if_its_not_in_the_ADS() { + std::vector names{"NotInADS"}; + + ON_CALL(*m_view, getSaveData()).WillByDefault(Return(createSaveData())); + ON_CALL(*m_model, outputWorkspaceNames()).WillByDefault(Return(names)); + + // Expect no call because the workspace is not in the ADS + EXPECT_CALL(*m_model, saveWorkspace(_, _)).Times(0); + + m_presenter->notifySaveClicked(); + } + + void test_notifySaveClicked_will_save_the_workspace_if_its_not_in_the_ADS() { + std::vector names{"InADS"}; + auto const workspace = Mantid::IndirectFitDataCreationHelper::createWorkspace(4, 5); + AnalysisDataService::Instance().addOrReplace(names[0], workspace); + + ON_CALL(*m_view, getSaveData()).WillByDefault(Return(createSaveData())); + ON_CALL(*m_model, outputWorkspaceNames()).WillByDefault(Return(names)); + + EXPECT_CALL(*m_model, saveWorkspace(names[0], _)).Times(1); + + m_presenter->notifySaveClicked(); } - void test_fetch_instrument_data() { - QMap instDetails; - instDetails["spectra-min"] = "1"; - instDetails["spectra-max"] = "10"; - instDetails["Efixed"] = "0.85"; - instDetails["cm-1-convert-choice"] = "true"; - instDetails["save-nexus-choice"] = "true"; - instDetails["save-ascii-choice"] = "true"; - instDetails["fold-frames-choice"] = "true"; - - IETInputData inputData("iris26184_multi_graphite002_red"); - IETConversionData conversionData(0.5, 1, 2); - IETGroupingData groupingData(IETGroupingType::DEFAULT); - IETBackgroundData backgroundData(false); - IETAnalysisData analysisData; - IETRebinData rebinData; - IETOutputData outputData; - - IETRunData runData(inputData, conversionData, groupingData, backgroundData, analysisData, rebinData, outputData); - - auto instrument = QString::fromStdString("IRIS"); - auto analyser = QString::fromStdString("Analyser"); - auto reflection = QString::fromStdString("Reflection"); - - ON_CALL(*m_model, runIETAlgorithm(_, _, _)).WillByDefault(Return("")); - ON_CALL(*m_view, getRunData()).WillByDefault(Return(runData)); - - ExpectationSet expectRunData = EXPECT_CALL(*m_view, getRunData()).Times(1); - ExpectationSet expectRunAlgo = EXPECT_CALL(*m_model, runIETAlgorithm(_, _, _)).Times(1).After(expectRunData); - - m_presenter->run(); + void test_notifyRunFinished_sets_run_text_to_invalid_if_the_run_files_are_not_valid() { + ON_CALL(*m_view, isRunFilesValid()).WillByDefault(Return(false)); + + EXPECT_CALL(*m_view, setRunButtonText("Invalid Run(s)")).Times(1); + EXPECT_CALL(*m_view, setRunFilesEnabled(true)).Times(1); + + m_presenter->notifyRunFinished(); + } + + void test_notifyRunFinished_sets_the_run_text_when_the_run_files_are_valid() { + std::string const filename = "filename.nxs"; + double const detailedBalance = 1.1; + + ON_CALL(*m_view, isRunFilesValid()).WillByDefault(Return(true)); + + ON_CALL(*m_view, getFirstFilename()).WillByDefault(Return(filename)); + ON_CALL(*m_model, loadDetailedBalance(filename)).WillByDefault(Return(detailedBalance)); + + EXPECT_CALL(*m_view, setDetailedBalance(detailedBalance)).Times(1); + EXPECT_CALL(*m_view, setRunButtonText("Run")).Times(1); + EXPECT_CALL(*m_view, setRunFilesEnabled(true)).Times(1); + + m_presenter->notifyRunFinished(); } private: std::unique_ptr m_presenter; - MockIETView *m_view; - MockIETModel *m_model; - IndirectDataReduction *m_idrUI; + std::unique_ptr> m_view; + NiceMock *m_model; + std::unique_ptr> m_idrUI; + + std::unique_ptr> m_outputOptionsView; + std::unique_ptr> m_instrumentConfig; }; \ No newline at end of file diff --git a/qt/scientific_interfaces/Indirect/test/Reduction/MockObjects.h b/qt/scientific_interfaces/Indirect/test/Reduction/MockObjects.h new file mode 100644 index 000000000000..2cad26d6c0ae --- /dev/null +++ b/qt/scientific_interfaces/Indirect/test/Reduction/MockObjects.h @@ -0,0 +1,121 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2024 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source +// & Institut Laue - Langevin +// SPDX - License - Identifier: GPL - 3.0 + +#pragma once + +#include +#include + +#include "MantidKernel/WarningSuppressions.h" + +#include "Reduction/ISISEnergyTransferModel.h" +#include "Reduction/ISISEnergyTransferView.h" +#include "Reduction/IndirectDataReduction.h" + +#include +#include +#include + +using namespace MantidQt::CustomInterfaces; + +GNU_DIAG_OFF_SUGGEST_OVERRIDE + +class MockIndirectDataReduction : public IIndirectDataReduction { +public: + virtual ~MockIndirectDataReduction() = default; + + MOCK_METHOD0(instrumentWorkspace, Mantid::API::MatrixWorkspace_sptr()); + + MOCK_CONST_METHOD0(getInstrumentConfiguration, MantidQt::MantidWidgets::IInstrumentConfig *()); + MOCK_METHOD0(getInstrumentDetails, QMap()); + + MOCK_METHOD1(showAnalyserAndReflectionOptions, void(bool visible)); +}; + +class MockIETModel : public IIETModel { +public: + virtual ~MockIETModel() = default; + + MOCK_METHOD2(setInstrumentProperties, void(IAlgorithmRuntimeProps &properties, InstrumentData const &instData)); + + MOCK_METHOD1(validateRunData, std::vector(IETRunData const &runData)); + MOCK_METHOD1(validatePlotData, std::vector(IETPlotData const &plotData)); + + MOCK_METHOD3(runIETAlgorithm, std::string(MantidQt::API::BatchAlgorithmRunner *batchAlgoRunner, + InstrumentData const &instData, IETRunData &runParams)); + MOCK_CONST_METHOD2(plotRawAlgorithmQueue, + std::deque(InstrumentData const &instData, + IETPlotData const &plotData)); + + MOCK_METHOD2(saveWorkspace, void(std::string const &workspaceName, IETSaveData const &saveData)); + + MOCK_METHOD4(createGroupingWorkspace, void(std::string const &instrumentName, std::string const &analyser, + std::string const &customGrouping, std::string const &outputName)); + + MOCK_METHOD1(loadDetailedBalance, double(std::string const &filename)); + + MOCK_METHOD4(groupWorkspaces, std::vector(std::string const &groupName, std::string const &instrument, + std::string const &groupOption, bool const shouldGroup)); + + MOCK_CONST_METHOD0(outputWorkspaceNames, std::vector()); +}; + +class MockIETView : public IIETView { +public: + virtual ~MockIETView() = default; + + MOCK_METHOD1(subscribePresenter, void(IIETPresenter *presenter)); + + MOCK_CONST_METHOD0(getRunData, IETRunData()); + MOCK_CONST_METHOD0(getPlotData, IETPlotData()); + MOCK_CONST_METHOD0(getSaveData, IETSaveData()); + MOCK_CONST_METHOD0(getGroupOutputOption, std::string()); + MOCK_CONST_METHOD0(getPlotOptionsView, IOutputPlotOptionsView *()); + MOCK_CONST_METHOD0(getGroupOutputCheckbox, bool()); + MOCK_CONST_METHOD0(getFirstFilename, std::string()); + MOCK_CONST_METHOD0(isRunFilesValid, bool()); + MOCK_CONST_METHOD1(validateCalibrationFileType, void(UserInputValidator &uiv)); + MOCK_CONST_METHOD1(validateRebinString, void(UserInputValidator &uiv)); + MOCK_CONST_METHOD2(validateGroupingProperties, + std::optional(std::size_t const &spectraMin, std::size_t const &spectraMax)); + MOCK_CONST_METHOD0(showRebinWidthPrompt, bool()); + MOCK_CONST_METHOD3(showSaveCustomGroupingDialog, + void(std::string const &customGroupingOutput, std::string const &defaultGroupingFilename, + std::string const &saveDirectory)); + MOCK_CONST_METHOD1(displayWarning, void(std::string const &message)); + MOCK_METHOD1(setCalibVisible, void(bool visible)); + MOCK_METHOD1(setEfixedVisible, void(bool visible)); + MOCK_METHOD1(setBackgroundSectionVisible, void(bool visible)); + MOCK_METHOD1(setPlotTimeSectionVisible, void(bool visible)); + MOCK_METHOD1(setAnalysisSectionVisible, void(bool visible)); + MOCK_METHOD1(setPlottingOptionsVisible, void(bool visible)); + MOCK_METHOD1(setAclimaxSaveVisible, void(bool visible)); + MOCK_METHOD1(setSPEVisible, void(bool visible)); + MOCK_METHOD1(setFoldMultipleFramesVisible, void(bool visible)); + MOCK_METHOD1(setOutputInCm1Visible, void(bool visible)); + MOCK_METHOD1(setGroupOutputCheckBoxVisible, void(bool visible)); + MOCK_METHOD1(setGroupOutputDropdownVisible, void(bool visible)); + MOCK_METHOD1(setDetailedBalance, void(double detailedBalance)); + MOCK_METHOD1(setRunFilesEnabled, void(bool enable)); + MOCK_METHOD1(setSingleRebin, void(bool enable)); + MOCK_METHOD1(setMultipleRebin, void(bool enable)); + MOCK_METHOD1(setSaveEnabled, void(bool enable)); + MOCK_METHOD1(setPlotTimeIsPlotting, void(bool plotting)); + MOCK_METHOD2(setFileExtensionsByName, void(QStringList calibrationFbSuffixes, QStringList calibrationWSSuffixes)); + MOCK_METHOD1(setRunButtonText, void(std::string const &runText)); + MOCK_METHOD1(setEnableOutputOptions, void(bool const enable)); + + MOCK_METHOD2(setInstrumentSpectraRange, void(int specMin, int specMax)); + MOCK_METHOD4(setInstrumentRebinning, + void(std::vector const &rebinParams, std::string const &rebinText, bool checked, int tabIndex)); + MOCK_METHOD2(setInstrumentEFixed, void(std::string const &instrumentName, double eFixed)); + MOCK_METHOD1(setInstrumentGrouping, void(std::string const &instrumentName)); + MOCK_METHOD1(setInstrumentSpecDefault, void(std::map &specMap)); + + MOCK_METHOD1(showMessageBox, void(std::string const &message)); +}; + +GNU_DIAG_ON_SUGGEST_OVERRIDE \ No newline at end of file diff --git a/qt/scientific_interfaces/Indirect/test/Reduction/ReductionAlgorithmUtilsTest.h b/qt/scientific_interfaces/Indirect/test/Reduction/ReductionAlgorithmUtilsTest.h index ff467304675e..d0ae7cae5892 100644 --- a/qt/scientific_interfaces/Indirect/test/Reduction/ReductionAlgorithmUtilsTest.h +++ b/qt/scientific_interfaces/Indirect/test/Reduction/ReductionAlgorithmUtilsTest.h @@ -15,7 +15,8 @@ using namespace MantidQt::CustomInterfaces; class ReductionAlgorithmUtilsTest : public CxxTest::TestSuite { public: - ReductionAlgorithmUtilsTest() = default; + static ReductionAlgorithmUtilsTest *createSuite() { return new ReductionAlgorithmUtilsTest(); } + static void destroySuite(ReductionAlgorithmUtilsTest *suite) { delete suite; } void setUp() override { m_filename = "C:/path/to/file.raw"; diff --git a/qt/scientific_interfaces/Inelastic/Common/OutputPlotOptionsModel.h b/qt/scientific_interfaces/Inelastic/Common/OutputPlotOptionsModel.h index 19f0a18bdb80..bf8f576207d7 100644 --- a/qt/scientific_interfaces/Inelastic/Common/OutputPlotOptionsModel.h +++ b/qt/scientific_interfaces/Inelastic/Common/OutputPlotOptionsModel.h @@ -8,7 +8,7 @@ #include "MantidQtWidgets/Plotting/ExternalPlotter.h" -#include "DllConfig.h" +#include "../DllConfig.h" #include "MantidAPI/MatrixWorkspace_fwd.h" #include diff --git a/qt/scientific_interfaces/Inelastic/Common/OutputPlotOptionsView.h b/qt/scientific_interfaces/Inelastic/Common/OutputPlotOptionsView.h index 96e3fbcbab40..a0ba9b166501 100644 --- a/qt/scientific_interfaces/Inelastic/Common/OutputPlotOptionsView.h +++ b/qt/scientific_interfaces/Inelastic/Common/OutputPlotOptionsView.h @@ -8,7 +8,7 @@ #include "ui_OutputPlotOptions.h" -#include "DllConfig.h" +#include "../DllConfig.h" #include "MantidKernel/System.h" #include "MantidQtWidgets/Common/MantidWidget.h"