From 8f1debf14c118675b6c990329f1dcee521190c9c Mon Sep 17 00:00:00 2001 From: Matthias Puchner <github@mpuchner.de> Date: Fri, 26 Nov 2021 12:04:50 +0100 Subject: [PATCH] store backup values in ParamContainer instead of each leaf --- GUI/Model/Fit/ParameterTreeItems.cpp | 92 ++++++++++++++++++++++++---- GUI/Model/Fit/ParameterTreeItems.h | 16 +++-- GUI/Model/Job/JobModel.cpp | 12 +--- GUI/Model/Job/JobModel.h | 1 - GUI/Model/Job/ParameterTreeUtils.cpp | 20 +++--- 5 files changed, 101 insertions(+), 40 deletions(-) diff --git a/GUI/Model/Fit/ParameterTreeItems.cpp b/GUI/Model/Fit/ParameterTreeItems.cpp index 342aeb8c7b1..3136a9d8962 100644 --- a/GUI/Model/Fit/ParameterTreeItems.cpp +++ b/GUI/Model/Fit/ParameterTreeItems.cpp @@ -15,6 +15,21 @@ #include "GUI/Model/Fit/ParameterTreeItems.h" #include "GUI/Model/Job/JobItem.h" #include "GUI/Model/Session/ModelPath.h" +#include "GUI/Model/Session/SessionXML.h" +#include "GUI/Util/DeserializationException.h" +#include <QXmlStreamReader> +#include <QXmlStreamWriter> + +using namespace GUI::Session::XML; + +namespace { +namespace Tags { +const QString BackupValues("BackupValues"); +const QString BackupValue("BackupValue"); +const QString Link("Link"); +const QString Value("Value"); +} // namespace Tags +} // namespace // ---------------------------------------------------------------------------- @@ -31,8 +46,6 @@ ParameterItem::ParameterItem() : SessionItem(M_TYPE) { // Link to original PropertyItem in one of components of MultiLayerItem or InstrumentItem addProperty(P_LINK, QString()); - // The back up value of PropertyItem to be able to reset parameter tuning tree to initial state - addProperty(P_BACKUP, 0.0); } //! Sets current value to the original PropertyItem of MultiLayerItem/InstrumentItem. @@ -60,17 +73,9 @@ void ParameterItem::setLink(const QString& link) setItemValue(P_LINK, link); } -//! Restore the value from backup and propagate it to the linked item. - -void ParameterItem::restoreFromBackup() -{ - double newValue = getItemValue(P_BACKUP).toDouble(); - propagateValueToLink(newValue); -} - -void ParameterItem::setBackup(double value) +QString ParameterItem::link() const { - setItemValue(P_BACKUP, value); + return getItemValue(P_LINK).toString(); } // ---------------------------------------------------------------------------- @@ -81,3 +86,66 @@ ParameterContainerItem::ParameterContainerItem() : SessionItem(M_TYPE) registerTag(T_CHILDREN, 0, -1, {ParameterLabelItem::M_TYPE}); setDefaultTag(T_CHILDREN); } + +void ParameterContainerItem::writeNonSessionItems(QXmlStreamWriter* writer) const +{ + writeAttribute(writer, GUI::Session::XML::Version, int(1)); + + writer->writeStartElement(Tags::BackupValues); + + for (auto v = m_backupValues.cbegin(); v != m_backupValues.cend(); v++) { + writer->writeEmptyElement(Tags::BackupValue); + writeAttribute(writer, Tags::Link, v.key()); + writeAttribute(writer, Tags::Value, v.value()); + } + writer->writeEndElement(); +} + +void ParameterContainerItem::readNonSessionItems(QXmlStreamReader* reader) +{ + m_backupValues.clear(); + const int version = reader->attributes().value(GUI::Session::XML::Version).toInt(); + + if (version < 1) + throw DeserializationException::tooOld(); + + if (version > 1) + throw DeserializationException::tooNew(); + + while (reader->readNextStartElement()) { + if (reader->name().toString() == Tags::BackupValues) { + + while (reader->readNextStartElement()) { + ASSERT(reader->name().toString() == Tags::BackupValue); + QString link; + double d; + readAttribute(reader, Tags::Link, &link); + readAttribute(reader, Tags::Value, &d); + m_backupValues[link] = d; + reader->skipCurrentElement(); + } + } + } +} + +void ParameterContainerItem::setBackupValue(const QString& link, double d) +{ + m_backupValues[link] = d; +} + +void ParameterContainerItem::restoreBackupValue(SessionItem* item) +{ + ASSERT(item); + if (auto* parameter = dynamic_cast<ParameterItem*>(item)) + if (m_backupValues.contains(parameter->link())) + parameter->propagateValueToLink(m_backupValues[parameter->link()]); + + for (auto* child : item->children()) + restoreBackupValue(child); +} + +void ParameterContainerItem::restoreBackupValues() +{ + for (auto* child : children()) + restoreBackupValue(child); +} diff --git a/GUI/Model/Fit/ParameterTreeItems.h b/GUI/Model/Fit/ParameterTreeItems.h index f293defdd03..2490ba5b34b 100644 --- a/GUI/Model/Fit/ParameterTreeItems.h +++ b/GUI/Model/Fit/ParameterTreeItems.h @@ -35,7 +35,6 @@ public: class ParameterItem : public SessionItem { private: static constexpr auto P_LINK{"Link"}; - static constexpr auto P_BACKUP{"Backup"}; public: static constexpr auto M_TYPE{"Parameter"}; @@ -45,9 +44,7 @@ public: void propagateValueToLink(double newValue); SessionItem* linkedItem(); void setLink(const QString& link); - - void restoreFromBackup(); - void setBackup(double value); + QString link() const; }; //! The ParameterContainerItem is a top item to hold all ParameterItem, represents an entry @@ -58,6 +55,17 @@ public: static constexpr auto M_TYPE{"Parameter Container"}; ParameterContainerItem(); + + void writeNonSessionItems(QXmlStreamWriter* writer) const override; + void readNonSessionItems(QXmlStreamReader* reader) override; + + void setBackupValue(const QString& link, double d); + void restoreBackupValues(); + +private: + void restoreBackupValue(SessionItem* item); + + QMap<QString, double> m_backupValues; }; #endif // BORNAGAIN_GUI_MODEL_FIT_PARAMETERTREEITEMS_H diff --git a/GUI/Model/Job/JobModel.cpp b/GUI/Model/Job/JobModel.cpp index 72c433103d4..5be45711265 100644 --- a/GUI/Model/Job/JobModel.cpp +++ b/GUI/Model/Job/JobModel.cpp @@ -108,7 +108,7 @@ QVector<JobItem*> JobModel::jobItems() const //! restore instrument and sample model from backup for given JobItem void JobModel::restore(JobItem* jobItem) { - restoreItem(jobItem->parameterContainerItem()); + jobItem->parameterContainerItem()->restoreBackupValues(); } bool JobModel::hasUnfinishedJobs() @@ -221,13 +221,3 @@ QString JobModel::generateJobName() } return QString("job") + QString::number(++glob_index); } - -void JobModel::restoreItem(SessionItem* item) -{ - ASSERT(item); - if (auto* parameter = dynamic_cast<ParameterItem*>(item)) - parameter->restoreFromBackup(); - - for (auto* child : item->children()) - restoreItem(child); -} diff --git a/GUI/Model/Job/JobModel.h b/GUI/Model/Job/JobModel.h index 62fea049428..656f4ddc84f 100644 --- a/GUI/Model/Job/JobModel.h +++ b/GUI/Model/Job/JobModel.h @@ -61,7 +61,6 @@ public slots: private: QString generateJobName(); - void restoreItem(SessionItem* item); JobQueueData* m_queue_data; }; diff --git a/GUI/Model/Job/ParameterTreeUtils.cpp b/GUI/Model/Job/ParameterTreeUtils.cpp index c4339454f5c..85c4aef7f47 100644 --- a/GUI/Model/Job/ParameterTreeUtils.cpp +++ b/GUI/Model/Job/ParameterTreeUtils.cpp @@ -18,9 +18,9 @@ #include "GUI/Model/Group/PropertyItem.h" #include "GUI/Model/Instrument/InstrumentItems.h" #include "GUI/Model/Job/JobItem.h" -#include "GUI/Model/Session/ModelPath.h" #include "GUI/Model/Material/MaterialItemContainer.h" #include "GUI/Model/Sample/MultiLayerItem.h" +#include "GUI/Model/Session/ModelPath.h" #include "GUI/Util/Error.h" #include <QStack> @@ -29,7 +29,7 @@ using boost::polymorphic_downcast; namespace { -void handleItem(SessionItem* tree, const SessionItem* source) +void handleItem(ParameterContainerItem* container, SessionItem* tree, const SessionItem* source) { if (tree->hasModelType<ParameterLabelItem>()) tree->setDisplayName(source->itemName()); @@ -44,7 +44,7 @@ void handleItem(SessionItem* tree, const SessionItem* source) path = path.mid(firstSlash + 1); auto* parItem = polymorphic_downcast<ParameterItem*>(tree); parItem->setLink(path); - parItem->setBackup(sourceValue); + container->setBackupValue(parItem->link(), sourceValue); return; } @@ -56,18 +56,18 @@ void handleItem(SessionItem* tree, const SessionItem* source) if (child->hasModelType<PropertyItem>()) { if (child->value().type() == QVariant::Double) { auto* branch = tree->model()->insertItem<ParameterItem>(tree); - handleItem(branch, child); + handleItem(container, branch, child); } } else if (child->hasModelType<GroupItem>()) { SessionItem* currentItem = dynamic_cast<GroupItem*>(child)->currentItem(); if (currentItem && currentItem->numberOfChildren() > 0) { auto* branch = tree->model()->insertItem<ParameterLabelItem>(tree); - handleItem(branch, currentItem); + handleItem(container, branch, currentItem); } } else { auto* branch = tree->model()->insertItem<ParameterLabelItem>(tree); - handleItem(branch, child); + handleItem(container, branch, child); } } } @@ -76,14 +76,10 @@ void handleItem(SessionItem* tree, const SessionItem* source) //! Populates ParameterContainer with ParameterItem's corresponding to all properties found //! in a source item. -void populateParameterContainer(SessionItem* container, const SessionItem* source) +void populateParameterContainer(ParameterContainerItem* container, const SessionItem* source) { - if (!container->hasModelType<ParameterContainerItem>()) - throw Error("GUI::Model::ParameterTreeUtils::populateParameterContainer() -> Error. " - "Not a ParameterContainerType."); - auto* sourceLabel = container->model()->insertItem<ParameterLabelItem>(container); - handleItem(sourceLabel, source); + handleItem(container, sourceLabel, source); } } // namespace -- GitLab