diff --git a/qt/scientific_interfaces/ISISReflectometry/CMakeLists.txt b/qt/scientific_interfaces/ISISReflectometry/CMakeLists.txt index 9746acb34e293edfac987a542a392a6a46cd200f..4c2e4d3e5e1485053ad656a6d68e28649ae10f1f 100644 --- a/qt/scientific_interfaces/ISISReflectometry/CMakeLists.txt +++ b/qt/scientific_interfaces/ISISReflectometry/CMakeLists.txt @@ -13,8 +13,7 @@ add_subdirectory(Reduction) set(SRC_FILES ${COMMON_SRC_FILES} ${GUI_SRC_FILES} - ${REDUCTION_SRC_FILES} - ISISReflectometryEncoder.cpp) + ${REDUCTION_SRC_FILES}) # Include files aren't required, but this makes them appear in Visual Studio # IMPORTANT: Include files are required in the MOC_FILES set. Scroll down to @@ -23,8 +22,7 @@ set(INC_FILES ${COMMON_INC_FILES} ${GUI_INC_FILES} ${REDUCTION_INC_FILES} - PrecompiledHeader.h - ISISReflectometryEncoder.h) + PrecompiledHeader.h) set(MOC_FILES ${GUI_MOC_FILES}) diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Batch/BatchPresenter.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Batch/BatchPresenter.h index f2c6de05feb90b9f369b6db60de99e567631269f..08ee871a16a2085f44e0ef3a710d3df030bf8e4e 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/Batch/BatchPresenter.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Batch/BatchPresenter.h @@ -105,7 +105,7 @@ private: std::unique_ptr<ISavePresenter> m_savePresenter; Mantid::Geometry::Instrument_const_sptr m_instrument; - friend class ISISReflectometryEncoder; + friend class Encoder; protected: std::unique_ptr<IBatchJobRunner> m_jobRunner; diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Batch/BatchView.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Batch/BatchView.h index 37dd10e4ae6245583d3e30c478adb8330789f9c2..68ba0454e08948a3aa1f1d19320d2ab27016fc33 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/Batch/BatchView.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Batch/BatchView.h @@ -66,7 +66,7 @@ private: std::unique_ptr<InstrumentView> m_instrument; API::BatchAlgorithmRunner m_batchAlgoRunner; - friend class ISISReflectometryEncoder; + friend class Encoder; }; } // namespace CustomInterfaces } // namespace MantidQt diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Common/CMakeLists.txt b/qt/scientific_interfaces/ISISReflectometry/GUI/Common/CMakeLists.txt index 41826909cd70f6129d251886b1489c1712e2db9b..9866f2a45ed11ea1f5fe38865c9f1ee9060fd61d 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/Common/CMakeLists.txt +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Common/CMakeLists.txt @@ -1,4 +1,7 @@ -set(COMMON_SRC_FILES Plotter.cpp) +set(COMMON_SRC_FILES + Plotter.cpp + Encoder.cpp +) # Include files aren't required, but this makes them appear in Visual Studio set( @@ -7,6 +10,7 @@ set( IPythonRunner.h IPlotter.h Plotter.h + Encoder.h ) set(COMMON_MOC_FILES SearchModel.h) diff --git a/qt/scientific_interfaces/ISISReflectometry/ISISReflectometryEncoder.cpp b/qt/scientific_interfaces/ISISReflectometry/GUI/Common/Encoder.cpp similarity index 78% rename from qt/scientific_interfaces/ISISReflectometry/ISISReflectometryEncoder.cpp rename to qt/scientific_interfaces/ISISReflectometry/GUI/Common/Encoder.cpp index 8d3f68d88a5e05e05c3e4e1396de837e0933007d..c9b88b3a38313996678b4c688fee3dc0143ec9e0 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ISISReflectometryEncoder.cpp +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Common/Encoder.cpp @@ -5,13 +5,12 @@ // & Institut Laue - Langevin // SPDX - License - Identifier: GPL - 3.0 + -#include "ISISReflectometryEncoder.h" -#include "GUI/RunsTable/RunsTablePresenter.h" +#include "Encoder.h" +#include "../RunsTable/RunsTablePresenter.h" namespace MantidQt { namespace CustomInterfaces { -QMap<QString, QVariant> -ISISReflectometryEncoder::encode(const MainWindowView &gui) { +QMap<QString, QVariant> Encoder::encode(const MainWindowView &gui) { QMap<QString, QVariant> map; QList<QVariant> batches; for (const auto &batchView : gui.m_batchViews) { @@ -22,9 +21,8 @@ ISISReflectometryEncoder::encode(const MainWindowView &gui) { return map; } -BatchPresenter * -ISISReflectometryEncoder::findBatchPresenter(const BatchView *gui, - const MainWindowView &mwv) { +BatchPresenter *Encoder::findBatchPresenter(const BatchView *gui, + const MainWindowView &mwv) { for (auto ipresenter : mwv.m_presenter->m_batchPresenters) { auto presenter = std::dynamic_pointer_cast<BatchPresenter>(ipresenter); if (presenter->m_view == gui) { @@ -34,9 +32,14 @@ ISISReflectometryEncoder::findBatchPresenter(const BatchView *gui, return nullptr; } -QMap<QString, QVariant> ISISReflectometryEncoder::encodeBatch( - const BatchView *gui, const MainWindowView &mwv, bool projectSave) { - auto batchPresenter = findBatchPresenter(gui, mwv); +QMap<QString, QVariant> Encoder::encodeBatch(const BatchView *gui, + const MainWindowView &mwv, + bool projectSave, + const BatchPresenter *presenter) { + auto batchPresenter = presenter; + if (!batchPresenter) { + batchPresenter = findBatchPresenter(gui, mwv); + } if (!batchPresenter) { throw std::runtime_error( "BatchPresenter could not be found during encode."); @@ -61,9 +64,18 @@ QMap<QString, QVariant> ISISReflectometryEncoder::encodeBatch( return map; } -QMap<QString, QVariant> -ISISReflectometryEncoder::encodeRuns(const RunsView *gui, bool projectSave, - const ReductionJobs *redJobs) { +QMap<QString, QVariant> Encoder::encodeBatch(const IBatchPresenter *presenter, + const IMainWindowView *mwv, + bool projectSave) { + auto batchPresenter = dynamic_cast<const BatchPresenter *>(presenter); + return encodeBatch(dynamic_cast<BatchView *>(batchPresenter->m_view), + *dynamic_cast<const MainWindowView *>(mwv), projectSave, + batchPresenter); +} + +QMap<QString, QVariant> Encoder::encodeRuns(const RunsView *gui, + bool projectSave, + const ReductionJobs *redJobs) { QMap<QString, QVariant> map; map.insert(QString("runsTable"), QVariant(encodeRunsTable(gui->m_tableView, projectSave, redJobs))); @@ -73,8 +85,9 @@ ISISReflectometryEncoder::encodeRuns(const RunsView *gui, bool projectSave, return map; } -QMap<QString, QVariant> ISISReflectometryEncoder::encodeRunsTable( - const RunsTableView *gui, bool projectSave, const ReductionJobs *redJobs) { +QMap<QString, QVariant> Encoder::encodeRunsTable(const RunsTableView *gui, + bool projectSave, + const ReductionJobs *redJobs) { QMap<QString, QVariant> map; map.insert(QString("filterBox"), QVariant(gui->m_ui.filterBox->text())); @@ -84,8 +97,7 @@ QMap<QString, QVariant> ISISReflectometryEncoder::encodeRunsTable( return map; } -QList<QVariant> -ISISReflectometryEncoder::encodeRunsTableModel(const ReductionJobs *redJobs) { +QList<QVariant> Encoder::encodeRunsTableModel(const ReductionJobs *redJobs) { QList<QVariant> groups; for (const auto &group : redJobs->groups()) { groups.append(QVariant(encodeGroup(group))); @@ -93,8 +105,8 @@ ISISReflectometryEncoder::encodeRunsTableModel(const ReductionJobs *redJobs) { return groups; } -QMap<QString, QVariant> ISISReflectometryEncoder::encodeGroup( - const MantidQt::CustomInterfaces::Group &group) { +QMap<QString, QVariant> +Encoder::encodeGroup(const MantidQt::CustomInterfaces::Group &group) { QMap<QString, QVariant> map; map.insert(QString("name"), QVariant(QString::fromStdString(group.m_name))); map.insert( @@ -104,8 +116,8 @@ QMap<QString, QVariant> ISISReflectometryEncoder::encodeGroup( return map; } -QList<QVariant> ISISReflectometryEncoder::encodeRows( - const MantidQt::CustomInterfaces::Group &group) { +QList<QVariant> +Encoder::encodeRows(const MantidQt::CustomInterfaces::Group &group) { QList<QVariant> rows; for (const auto &row : group.m_rows) { if (row) { @@ -117,8 +129,7 @@ QList<QVariant> ISISReflectometryEncoder::encodeRows( return rows; } -QMap<QString, QVariant> -ISISReflectometryEncoder::encodeRangeInQ(const RangeInQ &rangeInQ) { +QMap<QString, QVariant> Encoder::encodeRangeInQ(const RangeInQ &rangeInQ) { QMap<QString, QVariant> map; auto min = rangeInQ.min(); auto max = rangeInQ.max(); @@ -135,8 +146,8 @@ ISISReflectometryEncoder::encodeRangeInQ(const RangeInQ &rangeInQ) { return map; } -QMap<QString, QVariant> ISISReflectometryEncoder::encodeTransmissionRunPair( - const TransmissionRunPair &transRunPair) { +QMap<QString, QVariant> +Encoder::encodeTransmissionRunPair(const TransmissionRunPair &transRunPair) { QList<QVariant> firstTransRunNums; for (const auto firstTransRunNum : transRunPair.m_firstTransmissionRunNumbers) { @@ -155,8 +166,8 @@ QMap<QString, QVariant> ISISReflectometryEncoder::encodeTransmissionRunPair( return map; } -QMap<QString, QVariant> ISISReflectometryEncoder::encodeReductionWorkspace( - const ReductionWorkspaces &redWs) { +QMap<QString, QVariant> +Encoder::encodeReductionWorkspace(const ReductionWorkspaces &redWs) { QList<QVariant> inputRunNumbers; for (const auto &inputRunNum : redWs.m_inputRunNumbers) { inputRunNumbers.append(QVariant(QString::fromStdString(inputRunNum))); @@ -173,8 +184,8 @@ QMap<QString, QVariant> ISISReflectometryEncoder::encodeReductionWorkspace( return map; } -QMap<QString, QVariant> ISISReflectometryEncoder::encodeReductionOptions( - const ReductionOptionsMap &rom) { +QMap<QString, QVariant> +Encoder::encodeReductionOptions(const ReductionOptionsMap &rom) { QMap<QString, QVariant> map; for (const auto &elem : rom) { map.insert(QString::fromStdString(elem.first), @@ -183,8 +194,8 @@ QMap<QString, QVariant> ISISReflectometryEncoder::encodeReductionOptions( return map; } -QMap<QString, QVariant> ISISReflectometryEncoder::encodeRow( - const MantidQt::CustomInterfaces::Row &row) { +QMap<QString, QVariant> +Encoder::encodeRow(const MantidQt::CustomInterfaces::Row &row) { QMap<QString, QVariant> map; QList<QVariant> runNumbers; for (const auto &runNumber : row.m_runNumbers) { @@ -209,8 +220,7 @@ QMap<QString, QVariant> ISISReflectometryEncoder::encodeRow( return map; } -QMap<QString, QVariant> -ISISReflectometryEncoder::encodeEvent(const EventView *gui) { +QMap<QString, QVariant> Encoder::encodeEvent(const EventView *gui) { QMap<QString, QVariant> map; map.insert(QString("disabledSlicingButton"), QVariant(gui->m_ui.disabledSlicingButton->isChecked())); @@ -238,8 +248,7 @@ ISISReflectometryEncoder::encodeEvent(const EventView *gui) { return map; } -QMap<QString, QVariant> -ISISReflectometryEncoder::encodeInstrument(const InstrumentView *gui) { +QMap<QString, QVariant> Encoder::encodeInstrument(const InstrumentView *gui) { QMap<QString, QVariant> map; map.insert(QString("intMonCheckBox"), QVariant(gui->m_ui.intMonCheckBox->isChecked())); @@ -261,8 +270,7 @@ ISISReflectometryEncoder::encodeInstrument(const InstrumentView *gui) { return map; } -QMap<QString, QVariant> -ISISReflectometryEncoder::encodeExperiment(const ExperimentView *gui) { +QMap<QString, QVariant> Encoder::encodeExperiment(const ExperimentView *gui) { QMap<QString, QVariant> map; map.insert(QString("analysisModeComboBox"), QVariant(gui->m_ui.analysisModeComboBox->currentIndex())); @@ -282,12 +290,10 @@ ISISReflectometryEncoder::encodeExperiment(const ExperimentView *gui) { QVariant(gui->m_ui.endOverlapEdit->text())); map.insert(QString("transStitchParamsEdit"), QVariant(gui->m_ui.transStitchParamsEdit->text())); - map.insert(QString("polCorrComboBox"), - QVariant(gui->m_ui.polCorrComboBox->currentIndex())); - map.insert(QString("CRhoEdit"), QVariant(gui->m_ui.CRhoEdit->text())); - map.insert(QString("CAlphaEdit"), QVariant(gui->m_ui.CAlphaEdit->text())); - map.insert(QString("CApEdit"), QVariant(gui->m_ui.CApEdit->text())); - map.insert(QString("CPpEdit"), QVariant(gui->m_ui.CPpEdit->text())); + map.insert(QString("transScaleRHSCheckBox"), + QVariant(gui->m_ui.transScaleRHSCheckBox->isChecked())); + map.insert(QString("polCorrCheckBox"), + QVariant(gui->m_ui.polCorrCheckBox->isChecked())); map.insert(QString("floodCorComboBox"), QVariant(gui->m_ui.floodCorComboBox->currentIndex())); map.insert(QString("floodWorkspaceWsSelector"), @@ -297,19 +303,20 @@ ISISReflectometryEncoder::encodeExperiment(const ExperimentView *gui) { } QMap<QString, QVariant> -ISISReflectometryEncoder::encodePerAngleDefaults(const QTableWidget *tab) { +Encoder::encodePerAngleDefaults(const QTableWidget *tab) { QMap<QString, QVariant> map; const int rowsNum = tab->rowCount(); const int columnNum = tab->columnCount(); map.insert(QString("rowsNum"), QVariant(rowsNum)); map.insert(QString("columnsNum"), QVariant(columnNum)); map.insert(QString("rows"), - QVariant(encodePerAngleDefaultsRow(tab, rowsNum, columnNum))); + QVariant(encodePerAngleDefaultsRow(tab, rowsNum - 1, columnNum))); return map; } -QList<QVariant> ISISReflectometryEncoder::encodePerAngleDefaultsRows( - const QTableWidget *tab, int rowsNum, int columnsNum) { +QList<QVariant> Encoder::encodePerAngleDefaultsRows(const QTableWidget *tab, + int rowsNum, + int columnsNum) { QList<QVariant> rows; for (auto rowIndex = 0; rowIndex < rowsNum; ++rowIndex) { rows.append(QVariant(encodePerAngleDefaultsRow(tab, rowIndex, columnsNum))); @@ -317,8 +324,9 @@ QList<QVariant> ISISReflectometryEncoder::encodePerAngleDefaultsRows( return rows; } -QList<QVariant> ISISReflectometryEncoder::encodePerAngleDefaultsRow( - const QTableWidget *tab, int rowIndex, int columnsNum) { +QList<QVariant> Encoder::encodePerAngleDefaultsRow(const QTableWidget *tab, + int rowIndex, + int columnsNum) { QList<QVariant> row; for (auto columnIndex = 0; columnIndex < columnsNum; ++columnIndex) { row.append(QVariant(tab->item(rowIndex, columnIndex)->text())); @@ -326,8 +334,7 @@ QList<QVariant> ISISReflectometryEncoder::encodePerAngleDefaultsRow( return row; } -QMap<QString, QVariant> -ISISReflectometryEncoder::encodeSave(const SaveView *gui) { +QMap<QString, QVariant> Encoder::encodeSave(const SaveView *gui) { QMap<QString, QVariant> map; map.insert(QString("savePathEdit"), QVariant(gui->m_ui.savePathEdit->text())); map.insert(QString("prefixEdit"), QVariant(gui->m_ui.prefixEdit->text())); diff --git a/qt/scientific_interfaces/ISISReflectometry/ISISReflectometryEncoder.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Common/Encoder.h similarity index 76% rename from qt/scientific_interfaces/ISISReflectometry/ISISReflectometryEncoder.h rename to qt/scientific_interfaces/ISISReflectometry/GUI/Common/Encoder.h index daf0b9650cce1050adc08666866b04dd873c165f..702c6721e2dc445930313270ae58bdf5dc074abf 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ISISReflectometryEncoder.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Common/Encoder.h @@ -7,17 +7,17 @@ #ifndef MANTID_ISISREFLECTOMETRY_ENCODER_H #define MANTID_ISISREFLECTOMETRY_ENCODER_H -#include "GUI/Batch/BatchView.h" -#include "GUI/Experiment/ExperimentView.h" -#include "GUI/Instrument/InstrumentView.h" -#include "GUI/MainWindow/MainWindowView.h" -#include "GUI/Runs/RunsView.h" -#include "GUI/RunsTable/RunsTableView.h" -#include "GUI/Save/SaveView.h" -#include "Reduction/Group.h" -#include "Reduction/ReductionJobs.h" -#include "Reduction/ReductionWorkspaces.h" -#include "Reduction/Row.h" +#include "../../Reduction/Group.h" +#include "../../Reduction/ReductionJobs.h" +#include "../../Reduction/ReductionWorkspaces.h" +#include "../../Reduction/Row.h" +#include "../Batch/BatchView.h" +#include "../Experiment/ExperimentView.h" +#include "../Instrument/InstrumentView.h" +#include "../MainWindow/MainWindowView.h" +#include "../Runs/RunsView.h" +#include "../RunsTable/RunsTableView.h" +#include "../Save/SaveView.h" #include <QMap> #include <QString> @@ -27,12 +27,16 @@ namespace MantidQt { namespace CustomInterfaces { -class ISISReflectometryEncoder { +class Encoder { public: - ISISReflectometryEncoder(); + Encoder() {} QMap<QString, QVariant> encode(const MainWindowView &gui); - QMap<QString, QVariant> encodeBatch(const BatchView *gui, - const MainWindowView &mwv, + QMap<QString, QVariant> + encodeBatch(const BatchView *gui, const MainWindowView &mwv, + bool projectSave = false, + const BatchPresenter *presenter = nullptr); + QMap<QString, QVariant> encodeBatch(const IBatchPresenter *presenter, + const IMainWindowView *mwv, bool projectSave = false); private: diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Event/EventView.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Event/EventView.h index 19c1f065525d6b44efe496659bdc2b52c5ecdd53..2b43bd5f7fd013ff63efd8e877165ba7bfeb253f 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/Event/EventView.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Event/EventView.h @@ -78,7 +78,7 @@ private: Ui::EventWidget m_ui; EventViewSubscriber *m_notifyee; - friend class ISISReflectometryEncoder; + friend class Encoder; }; } // namespace CustomInterfaces diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Experiment/ExperimentView.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Experiment/ExperimentView.h index c980295d62db0ff03617f32c8abd807af00adb1e..2ee2b378f7e51a72394ce3c9dcee1d86a87ec337 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/Experiment/ExperimentView.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Experiment/ExperimentView.h @@ -175,7 +175,7 @@ private: Ui::ExperimentWidget m_ui; ExperimentViewSubscriber *m_notifyee; - friend class ISISReflectometryEncoder; + friend class Encoder; }; } // namespace CustomInterfaces diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Instrument/InstrumentView.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Instrument/InstrumentView.h index d7f9223f17352ee89ab5c585b0160745bda2b0ab..77084d0ca01cf1b24b5d652dddebd91cbbde8608 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/Instrument/InstrumentView.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Instrument/InstrumentView.h @@ -110,7 +110,7 @@ private: Ui::InstrumentWidget m_ui; InstrumentViewSubscriber *m_notifyee; - friend class ISISReflectometryEncoder; + friend class Encoder; }; } // namespace CustomInterfaces diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/IMainWindowView.h b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/IMainWindowView.h index 59c16a5fbae80617486c9179bc0e026be2e4a0ae..1a6ba0aea95fb9b0f84b2445549575461d6bb4a3 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/IMainWindowView.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/IMainWindowView.h @@ -26,6 +26,8 @@ public: virtual void notifyHelpPressed() = 0; virtual void notifyNewBatchRequested() = 0; virtual void notifyCloseBatchRequested(int) = 0; + virtual void notifySaveBatchRequested(int) = 0; + virtual void notifyLoadBatchRequested(int) = 0; virtual ~MainWindowSubscriber() = default; }; diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowPresenter.cpp b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowPresenter.cpp index bc245d7b2622c505449468665f6cd7cdc892784f..cc6467802416edc4584bb70d44e028c32a81054a 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowPresenter.cpp +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowPresenter.cpp @@ -5,12 +5,16 @@ // & Institut Laue - Langevin // SPDX - License - Identifier: GPL - 3.0 + #include "MainWindowPresenter.h" +#include "../Common/Encoder.h" #include "GUI/Common/IMessageHandler.h" #include "GUI/Runs/IRunsPresenter.h" #include "IMainWindowView.h" #include "MantidQtWidgets/Common/HelpWindow.h" +#include "MantidQtWidgets/Common/QtJSONUtils.h" #include "Reduction/Batch.h" +#include <QFileDialog> + namespace MantidQt { namespace CustomInterfaces { @@ -99,5 +103,21 @@ void MainWindowPresenter::showHelp() { MantidQt::API::HelpWindow::showCustomInterface(nullptr, QString("ISIS Reflectometry")); } + +void MainWindowPresenter::notifySaveBatchRequested(int tabIndex) { + auto filename = QFileDialog::getSaveFileName(); + Encoder encoder; + IBatchPresenter *batchPresenter = m_batchPresenters[tabIndex].get(); + auto map = encoder.encodeBatch(batchPresenter, m_view, false); + MantidQt::API::saveJSONToFile(filename, map); +} + +void MainWindowPresenter::notifyLoadBatchRequested(int tabIndex) { + // auto filename = QFileDialog::getOpenFileName(); + // auto map = MantidQt::API::loadJSONFromFile(filename); + UNUSED_ARG(tabIndex) + // ISISReflectometryDecoder decoder; + // decoder.decodeBatch(m_batchPresenters[tabIndex].get(), m_view, false); +} } // namespace CustomInterfaces } // namespace MantidQt diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowPresenter.h b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowPresenter.h index 51b4b7b0a34663f5f814b7ca2bcf9c8e350d3595..c34cc6575c34b01f39dd8d62874c5dec3339e509 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowPresenter.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowPresenter.h @@ -42,6 +42,8 @@ public: void notifyHelpPressed() override; void notifyNewBatchRequested() override; void notifyCloseBatchRequested(int batchIndex) override; + void notifySaveBatchRequested(int batchIndex) override; + void notifyLoadBatchRequested(int batchIndex) override; private: void showHelp(); @@ -52,7 +54,7 @@ private: BatchPresenterFactory m_batchPresenterFactory; std::vector<std::shared_ptr<IBatchPresenter>> m_batchPresenters; - friend class ISISReflectometryEncoder; + friend class Encoder; }; } // namespace CustomInterfaces } // namespace MantidQt diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowView.cpp b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowView.cpp index 3f0d23e73bbc0b47075cc055e015813c036a3f63..cefb78c8a261559f55a272a2183a3078b060fc54 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowView.cpp +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowView.cpp @@ -63,6 +63,10 @@ void MainWindowView::initLayout() { SLOT(onTabCloseRequested(int))); connect(m_ui.newBatch, SIGNAL(triggered(bool)), this, SLOT(onNewBatchRequested(bool))); + connect(m_ui.loadBatch, SIGNAL(triggered(bool)), this, + SLOT(onLoadBatchRequested(bool))); + connect(m_ui.saveBatch, SIGNAL(triggered(bool)), this, + SLOT(onSaveBatchRequested(bool))); auto instruments = std::vector<std::string>( {{"INTER", "SURF", "CRISP", "POLREF", "OFFSPEC"}}); @@ -109,6 +113,14 @@ void MainWindowView::onNewBatchRequested(bool) { m_notifyee->notifyNewBatchRequested(); } +void MainWindowView::onLoadBatchRequested(bool) { + m_notifyee->notifyLoadBatchRequested(m_ui.mainTabs->currentIndex()); +} + +void MainWindowView::onSaveBatchRequested(bool) { + m_notifyee->notifySaveBatchRequested(m_ui.mainTabs->currentIndex()); +} + void MainWindowView::subscribe(MainWindowSubscriber *notifyee) { m_notifyee = notifyee; } diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowView.h b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowView.h index a3d38114e39d196521cc28b016b9bfd25b20a58a..1e0bccd9786e5f6c9a3364634df1a1ab7215c8a8 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowView.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/MainWindowView.h @@ -56,6 +56,8 @@ public slots: void helpPressed(); void onTabCloseRequested(int tabIndex); void onNewBatchRequested(bool); + void onLoadBatchRequested(bool); + void onSaveBatchRequested(bool); private: /// Initializes the interface @@ -70,7 +72,7 @@ private: std::unique_ptr<MainWindowPresenter> m_presenter; std::vector<IBatchView *> m_batchViews; - friend class ISISReflectometryEncoder; + friend class Encoder; }; } // namespace CustomInterfaces } // namespace MantidQt diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsPresenter.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsPresenter.h index 59202c1b9301aff4e4d9e265e8d7790393ad56f0..e293f3431d520145520ee084bbfd2b7ae5dbaa00 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsPresenter.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsPresenter.h @@ -179,7 +179,7 @@ private: void updateViewWhenMonitorStarted(); void updateViewWhenMonitorStopped(); - friend class ISISReflectometryEncoder; + friend class Encoder; }; } // namespace CustomInterfaces } // namespace MantidQt diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsView.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsView.h index 82853bb87461566734f665ffe4e12afbdc707dd9..14ff97ca6dc5167d7aa3e65a01a2b9ddf3d2b525 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsView.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsView.h @@ -115,7 +115,7 @@ private: // Timer for triggering periodic autoreduction QBasicTimer m_timer; - friend class ISISReflectometryEncoder; + friend class Encoder; private slots: void on_actionSearch_triggered(); diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/RunsTable/RunsTablePresenter.h b/qt/scientific_interfaces/ISISReflectometry/GUI/RunsTable/RunsTablePresenter.h index 0cf57019a3187da8398e927e171e9e8a8abb9e94..678caf557b9c88dad421ef139efe845d505e266a 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/RunsTable/RunsTablePresenter.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/RunsTable/RunsTablePresenter.h @@ -163,7 +163,7 @@ private: IRunsPresenter *m_mainPresenter; const IPlotter &m_plotter; - friend class ISISReflectometryEncoder; + friend class Encoder; }; } // namespace CustomInterfaces } // namespace MantidQt diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/RunsTable/RunsTableView.h b/qt/scientific_interfaces/ISISReflectometry/GUI/RunsTable/RunsTableView.h index 99c51736fb3e373a83eba114ec5a1a7e18a920f8..e121e4ec3659aebba66b6a0def37da4c4ba37846 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/RunsTable/RunsTableView.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/RunsTable/RunsTableView.h @@ -78,7 +78,7 @@ private: RunsTableViewSubscriber *m_notifyee; std::map<Action, QAction *> m_actions; - friend class ISISReflectometryEncoder; + friend class Encoder; }; class RunsTableViewFactory { diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Save/SaveView.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Save/SaveView.h index 91ee4ef1f2d08fcddb8e82e7c4314209209a7c45..d163ea7f915c15804a37cc3d0c10f6bac8b9c742 100644 --- a/qt/scientific_interfaces/ISISReflectometry/GUI/Save/SaveView.h +++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Save/SaveView.h @@ -107,7 +107,7 @@ private: Ui::SaveWidget m_ui; SaveViewSubscriber *m_notifyee; - friend class ISISReflectometryEncoder; + friend class Encoder; }; } // namespace CustomInterfaces diff --git a/qt/scientific_interfaces/ISISReflectometry/Reduction/Group.h b/qt/scientific_interfaces/ISISReflectometry/Reduction/Group.h index e9273aa211385ee68fafdf95b4578752a2a99cfe..ecdc6ad4fe2cde4f5829637d027a0edba52a893e 100644 --- a/qt/scientific_interfaces/ISISReflectometry/Reduction/Group.h +++ b/qt/scientific_interfaces/ISISReflectometry/Reduction/Group.h @@ -68,7 +68,7 @@ private: std::string m_postprocessedWorkspaceName; std::vector<boost::optional<Row>> m_rows; - friend class ISISReflectometryEncoder; + friend class Encoder; }; template <typename ModificationListener> diff --git a/qt/scientific_interfaces/ISISReflectometry/Reduction/ReductionJobs.h b/qt/scientific_interfaces/ISISReflectometry/Reduction/ReductionJobs.h index 20ca916e87f570cb0301977d5af023eda09b2f20..bfbe03f3d8721b89b893e8bbd0fa72fa0ff9c0be 100644 --- a/qt/scientific_interfaces/ISISReflectometry/Reduction/ReductionJobs.h +++ b/qt/scientific_interfaces/ISISReflectometry/Reduction/ReductionJobs.h @@ -60,7 +60,7 @@ private: std::vector<Group> m_groups; size_t m_groupNameSuffix; - friend class ISISReflectometryEncoder; + friend class Encoder; }; MANTIDQT_ISISREFLECTOMETRY_DLL bool operator!=(ReductionJobs const &lhs, diff --git a/qt/scientific_interfaces/ISISReflectometry/Reduction/ReductionWorkspaces.h b/qt/scientific_interfaces/ISISReflectometry/Reduction/ReductionWorkspaces.h index b0d894d35a9cc722705436d61ef28d24ac00f56b..c22f0235a84afafc00537aee6f683e215c4f2c33 100644 --- a/qt/scientific_interfaces/ISISReflectometry/Reduction/ReductionWorkspaces.h +++ b/qt/scientific_interfaces/ISISReflectometry/Reduction/ReductionWorkspaces.h @@ -47,7 +47,7 @@ private: std::string m_iVsQ; std::string m_iVsQBinned; - friend class ISISReflectometryEncoder; + friend class Encoder; }; MANTIDQT_ISISREFLECTOMETRY_DLL bool operator==(ReductionWorkspaces const &lhs, diff --git a/qt/scientific_interfaces/ISISReflectometry/Reduction/Row.h b/qt/scientific_interfaces/ISISReflectometry/Reduction/Row.h index 8d4d90cdcef5f7ceaaac5f21f2190f3e47ac6f00..ac8f2088ba1c8970ea4457bafd9a1b52cce1b2de 100644 --- a/qt/scientific_interfaces/ISISReflectometry/Reduction/Row.h +++ b/qt/scientific_interfaces/ISISReflectometry/Reduction/Row.h @@ -65,7 +65,7 @@ private: ReductionWorkspaces m_reducedWorkspaceNames; ReductionOptionsMap m_reductionOptions; - friend class ISISReflectometryEncoder; + friend class Encoder; }; MANTIDQT_ISISREFLECTOMETRY_DLL bool operator!=(Row const &lhs, Row const &rhs); diff --git a/qt/scientific_interfaces/ISISReflectometry/Reduction/RunsTable.h b/qt/scientific_interfaces/ISISReflectometry/Reduction/RunsTable.h index 26439bc9685768d27b6fe59d6d9b8f5174e72333..9a5e9cc77d01f18aea46ca7bb20bb85b1a65b9f4 100644 --- a/qt/scientific_interfaces/ISISReflectometry/Reduction/RunsTable.h +++ b/qt/scientific_interfaces/ISISReflectometry/Reduction/RunsTable.h @@ -51,7 +51,7 @@ private: ReductionJobs m_reductionJobs; std::vector<MantidWidgets::Batch::RowLocation> m_selectedRowLocations; - friend class ISISReflectometryEncoder; + friend class Encoder; }; template <typename T> diff --git a/qt/scientific_interfaces/ISISReflectometry/Reduction/TransmissionRunPair.h b/qt/scientific_interfaces/ISISReflectometry/Reduction/TransmissionRunPair.h index 8f16f7ddfc81c555c5a132014111b6d105d0175f..183b65ebc04f6d91de91837bb201903a663b39fb 100644 --- a/qt/scientific_interfaces/ISISReflectometry/Reduction/TransmissionRunPair.h +++ b/qt/scientific_interfaces/ISISReflectometry/Reduction/TransmissionRunPair.h @@ -36,7 +36,7 @@ private: std::vector<std::string> m_firstTransmissionRunNumbers; std::vector<std::string> m_secondTransmissionRunNumbers; - friend class ISISReflectometryEncoder; + friend class Encoder; }; MANTIDQT_ISISREFLECTOMETRY_DLL bool operator==(TransmissionRunPair const &lhs, diff --git a/qt/widgets/common/CMakeLists.txt b/qt/widgets/common/CMakeLists.txt index 727879c87ae2479c043fcd9f97d6afda032b4148..92b51ef06db151f154e2faba1dfa1e1dab80884a 100644 --- a/qt/widgets/common/CMakeLists.txt +++ b/qt/widgets/common/CMakeLists.txt @@ -64,6 +64,7 @@ set(QT5_SRC_FILES src/PropertyWidgetFactory.cpp src/PythonRunner.cpp src/QtSignalChannel.cpp + src/QtJSONUtils.cpp src/RenameParDialog.cpp src/ScriptEditor.cpp src/SequentialFitDialog.cpp @@ -238,6 +239,7 @@ set(QT5_INC_FILES inc/MantidQtWidgets/Common/pixmaps.h inc/MantidQtWidgets/Common/ProgressableView.h inc/MantidQtWidgets/Common/PropertyWidgetFactory.h + inc/MantidQtWidgets/Common/QtJSONUtils.h inc/MantidQtWidgets/Common/SequentialFitDialog.h inc/MantidQtWidgets/Common/UserInputValidator.h inc/MantidQtWidgets/Common/WidgetScrollbarDecorator.h @@ -326,6 +328,7 @@ set(SRC_FILES src/PythonRunner.cpp src/QScienceSpinBox.cpp src/QtSignalChannel.cpp + src/QtJSONUtils.cpp src/RepoModel.cpp src/ScriptRepositoryView.cpp src/SelectionNotificationService.cpp @@ -600,6 +603,7 @@ set( inc/MantidQtWidgets/Common/PropertyWidgetFactory.h inc/MantidQtWidgets/Common/QScienceSpinBox.h inc/MantidQtWidgets/Common/QStringUtils.h + inc/MantidQtWidgets/Common/QtJSONUtils.h inc/MantidQtWidgets/Common/ScriptRepositoryView.h inc/MantidQtWidgets/Common/SelectionNotificationService.h inc/MantidQtWidgets/Common/SignalBlocker.h @@ -826,6 +830,7 @@ mtd_add_qt_library(TARGET_NAME Qt4::QtNetwork Qt4::QtWebKit Qt4::Qscintilla + Qt4::QtScript INSTALL_DIR ${LIB_DIR} OSX_INSTALL_RPATH diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtJSONUtils.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtJSONUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..2386fa6f15232d484c338996cd4d4f2a58b899f8 --- /dev/null +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtJSONUtils.h @@ -0,0 +1,30 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source +// & Institut Laue - Langevin +// SPDX - License - Identifier: GPL - 3.0 + + +#ifndef MANTIDQT_API_QJSONUTILS_H +#define MANTIDQT_API_QJSONUTILS_H + +#include "DllOption.h" + +#include <QMap> +#include <QString> +#include <QVariant> +#include <string> + +namespace MantidQt { +namespace API { + +void EXPORT_OPT_MANTIDQT_COMMON +saveJSONToFile(const QString &filename, const QMap<QString, QVariant> &map); + +QMap<QString, QVariant> + EXPORT_OPT_MANTIDQT_COMMON loadJSONFromFile(const QString &filename); + +} // namespace API +} // namespace MantidQt + +#endif /* MANTIDQT_API_QJSONUTILS_H */ \ No newline at end of file diff --git a/qt/widgets/common/src/QtJSONUtils.cpp b/qt/widgets/common/src/QtJSONUtils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a75491cce69c0bccca511258481c695322da8749 --- /dev/null +++ b/qt/widgets/common/src/QtJSONUtils.cpp @@ -0,0 +1,144 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source +// & Institut Laue - Langevin +// SPDX - License - Identifier: GPL - 3.0 + + +#include "MantidQtWidgets/Common/QtJSONUtils.h" + +#include <QFile> +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#include <QScriptEngine> +#include <QScriptValue> +#include <QScriptValueIterator> +#else +#include <QJsonDocument> +#include <QJsonObject> +#endif + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +namespace { +// Code in anonymous namespace taken from stack overflow +// https://stackoverflow.com/questions/4169988/easiest-way-to-parse-json-in-qt-4-7 +// from user2243820 on 1st August 2019 + +class JSON { +public: + QScriptValue encodeInner(const QMap<QString, QVariant> &map, + QScriptEngine *engine) { + QScriptValue obj = engine->newObject(); + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + if (i.value().type() == QVariant::String) + obj.setProperty(i.key(), i.value().toString()); + else if (i.value().type() == QVariant::Int) + obj.setProperty(i.key(), i.value().toInt()); + else if (i.value().type() == QVariant::Double) + obj.setProperty(i.key(), i.value().toDouble()); + else if (i.value().type() == QVariant::List) + obj.setProperty(i.key(), + qScriptValueFromSequence(engine, i.value().toList())); + else if (i.value().type() == QVariant::Map) + obj.setProperty(i.key(), encodeInner(i.value().toMap(), engine)); + } + return obj; + } + + QString encode(const QMap<QString, QVariant> &map) { + QScriptEngine engine; + engine.evaluate("function toString() { return JSON.stringify(this) }"); + + QScriptValue toString = engine.globalObject().property("toString"); + QScriptValue obj = encodeInner(map, &engine); + return toString.call(obj).toString(); + } + + QMap<QString, QVariant> decodeInner(QScriptValue object) { + QMap<QString, QVariant> map; + QScriptValueIterator it(object); + while (it.hasNext()) { + it.next(); + if (it.value().isArray()) + map.insert(it.name(), QVariant(decodeInnerToList(it.value()))); + else if (it.value().isNumber()) + map.insert(it.name(), QVariant(it.value().toNumber())); + else if (it.value().isString()) + map.insert(it.name(), QVariant(it.value().toString())); + else if (it.value().isNull()) + map.insert(it.name(), QVariant()); + else if (it.value().isObject()) + map.insert(it.name(), QVariant(decodeInner(it.value()))); + } + return map; + } + + QList<QVariant> decodeInnerToList(QScriptValue arrayValue) { + QList<QVariant> list; + QScriptValueIterator it(arrayValue); + while (it.hasNext()) { + it.next(); + if (it.name() == "length") + continue; + + if (it.value().isArray()) + list.append(QVariant(decodeInnerToList(it.value()))); + else if (it.value().isNumber()) + list.append(QVariant(it.value().toNumber())); + else if (it.value().isString()) + list.append(QVariant(it.value().toString())); + else if (it.value().isNull()) + list.append(QVariant()); + else if (it.value().isObject()) + list.append(QVariant(decodeInner(it.value()))); + } + return list; + } + + QMap<QString, QVariant> decode(const QString &jsonStr) { + QScriptValue object; + QScriptEngine engine; + object = engine.evaluate("(" + jsonStr + ")"); + return decodeInner(object); + } +}; +} // namespace +#endif +namespace MantidQt { +namespace API { +void saveJSONToFile(const QString &filename, + const QMap<QString, QVariant> &map) { +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + JSON JSON; + auto jsonString = JSON.encode(map); + QFile jsonFile(filename); + jsonFile.open(QFile::WriteOnly); + QByteArray jsonByteArray; + jsonFile.write(jsonByteArray.append(jsonString)); +#else + QJsonDocument jsonDocument(QJsonObject::fromVariantMap(map)); + QFile jsonFile(filename); + jsonFile.open(QFile::WriteOnly); + jsonFile.write(jsonDocument.toJson()); +#endif +} + +QMap<QString, QVariant> loadJSONFromFile(const QString &filename) { +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + JSON JSON; + QFile jsonFile(filename); + jsonFile.open(QFile::ReadOnly); + QString json(jsonFile.readAll()); + return JSON.decode(json); +#else + QFile jsonFile(filename); + jsonFile.open(QFile::ReadOnly); + QJsonDocument jsonDocument; + jsonDocument.fromJson(jsonFile.readAll()); + return jsonDocument.object().toVariantMap(); + +#endif +} +} // namespace API +} // namespace MantidQt \ No newline at end of file