From 5ce3d425f832aa049da85927000fe9c770cb4d88 Mon Sep 17 00:00:00 2001
From: Matthias Puchner <github@mpuchner.de>
Date: Tue, 30 Nov 2021 15:57:01 +0100
Subject: [PATCH] use SessionModel-free Material items in Job instead of
 MaterialContainer and so on

---
 GUI/Model/Job/JobItem.cpp                    | 37 +++++++++-----
 GUI/Model/Job/JobItem.h                      |  9 ++--
 GUI/Model/Job/JobModel.cpp                   |  3 +-
 GUI/Model/Job/JobModelFunctions.cpp          | 14 ++---
 GUI/Model/Material/MaterialItemContainer.cpp | 54 --------------------
 GUI/Model/Material/MaterialItemContainer.h   | 44 ----------------
 6 files changed, 35 insertions(+), 126 deletions(-)
 delete mode 100644 GUI/Model/Material/MaterialItemContainer.cpp
 delete mode 100644 GUI/Model/Material/MaterialItemContainer.h

diff --git a/GUI/Model/Job/JobItem.cpp b/GUI/Model/Job/JobItem.cpp
index 90df6955523..23ca2f32d1a 100644
--- a/GUI/Model/Job/JobItem.cpp
+++ b/GUI/Model/Job/JobItem.cpp
@@ -23,7 +23,6 @@
 #include "GUI/Model/IO/ItemFileNameUtils.h"
 #include "GUI/Model/Instrument/InstrumentItems.h"
 #include "GUI/Model/Job/JobItemUtils.h"
-#include "GUI/Model/Material/MaterialItemContainer.h"
 #include "GUI/Model/Sample/ItemWithMaterial.h"
 #include "GUI/Model/Sample/MultiLayerItem.h"
 #include "GUI/Model/Session/SessionXML.h"
@@ -35,6 +34,7 @@ using namespace GUI::Session::XML;
 
 namespace {
 const QString SimulationOptionsTag("SimulationOptions");
+const QString MaterialsTag("Materials");
 } // namespace
 
 
@@ -56,7 +56,6 @@ JobItem::JobItem() : SessionItem(M_TYPE)
     addProperty(P_PRESENTATION_TYPE, QVariant::Type::Invalid)->setVisible(false);
 
     registerTag(T_SAMPLE, 1, 1, {MultiLayerItem::M_TYPE});
-    registerTag(T_MATERIAL_CONTAINER, 1, 1, {MaterialItemContainer::M_TYPE});
     registerTag(T_INSTRUMENT, 1, 1,
                 {GISASInstrumentItem::M_TYPE, OffSpecularInstrumentItem::M_TYPE,
                  SpecularInstrumentItem::M_TYPE, DepthProbeInstrumentItem::M_TYPE});
@@ -252,7 +251,7 @@ MultiLayerItem* JobItem::copySampleIntoJob(const MultiLayerItem* sample)
     // initialize finder-function of items with material
     for (auto* itemWithMaterial : sampleItem()->itemsWithMaterial()) {
         itemWithMaterial->setMaterialFinder(
-            [=](const QString& id) { return materialContainerItem()->findMaterialById(id); });
+            [=](const QString& id) { return materialItems().materialFromIdentifier(id); });
     }
 
     return sampleItem();
@@ -339,16 +338,6 @@ RealDataItem* JobItem::createRealDataItem()
     return model()->insertItem<RealDataItem>(this, -1, T_REALDATA);
 }
 
-MaterialItemContainer* JobItem::materialContainerItem() const
-{
-    return dynamic_cast<MaterialItemContainer*>(getItem(JobItem::T_MATERIAL_CONTAINER));
-}
-
-MaterialItemContainer* JobItem::createMaterialContainer()
-{
-    return model()->insertItem<MaterialItemContainer>(this, -1, T_MATERIAL_CONTAINER);
-}
-
 Data1DViewItem* JobItem::dataItemView()
 {
     return dynamic_cast<Data1DViewItem*>(getItem(JobItem::T_DATAVIEW));
@@ -401,6 +390,10 @@ void JobItem::writeNonSessionItems(QXmlStreamWriter* writer) const
     writer->writeStartElement(SimulationOptionsTag);
     m_simulationOptionsItem.writeContentTo(writer);
     writer->writeEndElement();
+
+    writer->writeStartElement(MaterialsTag);
+    m_materials.writeContentTo(writer);
+    writer->writeEndElement();
 }
 
 void JobItem::readNonSessionItems(QXmlStreamReader* reader)
@@ -417,10 +410,28 @@ void JobItem::readNonSessionItems(QXmlStreamReader* reader)
         if (reader->name() == SimulationOptionsTag) {
             m_simulationOptionsItem.readContentFrom(reader);
             reader->skipCurrentElement();
+        } else if (reader->name() == MaterialsTag) {
+            m_materials.readContentFrom(reader);
+            reader->skipCurrentElement();
         }
     }
 }
 
+const MaterialModel& JobItem::materialItems() const
+{
+    return m_materials;
+}
+
+MaterialModel& JobItem::materialItems()
+{
+    return m_materials;
+}
+
+bool JobItem::isSpecularJob() const
+{
+    return instrumentItem()->is<SpecularInstrumentItem>();
+}
+
 //! Updates the name of file to store intensity data.
 
 void JobItem::updateIntensityDataFileName()
diff --git a/GUI/Model/Job/JobItem.h b/GUI/Model/Job/JobItem.h
index 16d34064e0e..8d0230c359d 100644
--- a/GUI/Model/Job/JobItem.h
+++ b/GUI/Model/Job/JobItem.h
@@ -16,6 +16,7 @@
 #define BORNAGAIN_GUI_MODEL_JOB_JOBITEM_H
 
 #include "GUI/Model/Job/JobStatus.h" // enum cannot be forward declared
+#include "GUI/Model/Material/MaterialModel.h"
 #include "GUI/Model/Session/SessionItem.h"
 #include "GUI/Model/Session/SessionModel.h" // call to model() from templated fct
 #include "GUI/Model/Session/SimulationOptionsItem.h"
@@ -130,9 +131,6 @@ public:
     void addRealDataItem(RealDataItem* real_data);
     RealDataItem* createRealDataItem();
 
-    MaterialItemContainer* materialContainerItem() const;
-    MaterialItemContainer* createMaterialContainer();
-
     Data1DViewItem* dataItemView();
     void addDataViewItem(Data1DViewItem* data_view);
     Data1DViewItem* createDataViewItem();
@@ -149,10 +147,15 @@ public:
     void writeNonSessionItems(QXmlStreamWriter* writer) const override;
     void readNonSessionItems(QXmlStreamReader* reader) override;
 
+    const MaterialModel& materialItems() const;
+    MaterialModel& materialItems();
+    bool isSpecularJob() const;
+
 private:
     void updateIntensityDataFileName();
 
     SimulationOptionsItem m_simulationOptionsItem;
+    MaterialModel m_materials;
 };
 
 template <typename T> T* JobItem::setDataType()
diff --git a/GUI/Model/Job/JobModel.cpp b/GUI/Model/Job/JobModel.cpp
index 9f882e1d76d..8130489f427 100644
--- a/GUI/Model/Job/JobModel.cpp
+++ b/GUI/Model/Job/JobModel.cpp
@@ -23,7 +23,6 @@
 #include "GUI/Model/Job/JobModelFunctions.h"
 #include "GUI/Model/Job/JobQueueData.h"
 #include "GUI/Model/Job/ParameterTreeUtils.h"
-#include "GUI/Model/Material/MaterialItemContainer.h"
 #include "GUI/Model/Sample/ItemWithMaterial.h"
 #include "GUI/Model/Sample/MultiLayerItem.h"
 #include "GUI/Util/Path.h"
@@ -170,7 +169,7 @@ void JobModel::readFrom(QXmlStreamReader* reader, MessageService* messageService
         // initialize the material finder functions
         for (auto* itemWithMaterial : jobItem->sampleItem()->itemsWithMaterial())
             itemWithMaterial->setMaterialFinder([=](const QString& id) {
-                return jobItem->materialContainerItem()->findMaterialById(id);
+                return jobItem->materialItems().materialFromIdentifier(id);
             });
 
         // Create the not stored parameter tuning tree
diff --git a/GUI/Model/Job/JobModelFunctions.cpp b/GUI/Model/Job/JobModelFunctions.cpp
index e7f99ef7ed3..2151c4d6123 100644
--- a/GUI/Model/Job/JobModelFunctions.cpp
+++ b/GUI/Model/Job/JobModelFunctions.cpp
@@ -29,7 +29,6 @@
 #include "GUI/Model/Job/JobItem.h"
 #include "GUI/Model/Job/JobItemUtils.h"
 #include "GUI/Model/Material/MaterialItem.h"
-#include "GUI/Model/Material/MaterialItemContainer.h"
 #include "GUI/Model/Sample/ItemWithMaterial.h"
 #include "GUI/Model/Sample/MultiLayerItem.h"
 #include "GUI/Util/Error.h"
@@ -130,13 +129,12 @@ void GUI::Model::JobFunctions::setupJobItemSampleData(JobItem* jobItem,
     multilayer->setItemName(MultiLayerItem::M_TYPE);
 
     // copy used materials into material container
-    MaterialItemContainer* container = jobItem->createMaterialContainer();
-
     for (auto* itemWithMaterial : sampleItem->itemsWithMaterial()) {
         auto* material = itemWithMaterial->materialItem();
-        if (!container->findMaterialById(material->identifier())) {
-            auto* materialCopy = container->insertCopy(material);
-            materialCopy->setIdentifier(material->identifier()); // insertCopy() doesn't do this
+        if (!jobItem->materialItems().findMaterialItem(material->identifier())) {
+            auto* materialCopy = jobItem->materialItems().insertCopy(*material);
+            materialCopy->setIdentifier(material->identifier());     // insertCopy() doesn't do this
+            materialCopy->setMaterialName(material->materialName()); // insertCopy() doesn't do this
         }
     }
 }
@@ -206,10 +204,6 @@ void GUI::Model::JobFunctions::setupJobItemForFit(JobItem* jobItem,
 
 void GUI::Model::JobFunctions::muteMagnetizationData(JobItem* jobItem)
 {
-    MaterialItemContainer* container = jobItem->materialContainerItem();
-    for (MaterialItem* material : container->getMaterials())
-        material->hideMagnetization();
-
     MultiLayerItem* sample = jobItem->sampleItem();
     sample->externalFieldItem()->setVisible(false);
 }
diff --git a/GUI/Model/Material/MaterialItemContainer.cpp b/GUI/Model/Material/MaterialItemContainer.cpp
deleted file mode 100644
index 8e0c528b79d..00000000000
--- a/GUI/Model/Material/MaterialItemContainer.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      GUI/Model/Material/MaterialItemContainer.cpp
-//! @brief     Implements class MaterialItemContainer
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#include "GUI/Model/Material/MaterialItemContainer.h"
-#include "GUI/Model/Material/MaterialItem.h"
-#include "GUI/Model/Session/SessionModel.h"
-#include <QUuid>
-
-MaterialItemContainer::MaterialItemContainer() : SessionItem(M_TYPE)
-{
-    setItemName("Materials");
-    registerTag(T_MATERIALS, 0, -1, {MaterialItem::M_TYPE});
-}
-
-MaterialItem* MaterialItemContainer::insertCopy(MaterialItem* material_item)
-{
-    MaterialItem* item_copy = model()->copyItem(material_item, this, T_MATERIALS);
-    item_copy->setIdentifier(QUuid::createUuid().toString());
-
-    return item_copy;
-}
-
-MaterialItem* MaterialItemContainer::findMaterialById(QString id)
-{
-    return const_cast<MaterialItem*>(
-        static_cast<const MaterialItemContainer*>(this)->findMaterialById(id));
-}
-
-const MaterialItem* MaterialItemContainer::findMaterialById(QString id) const
-{
-    auto materials = getItems(T_MATERIALS);
-    for (auto* item : materials) {
-        auto* material = dynamic_cast<MaterialItem*>(item);
-        if (material->identifier() == id)
-            return material;
-    }
-    return nullptr;
-}
-
-QVector<MaterialItem*> MaterialItemContainer::getMaterials()
-{
-    return items<MaterialItem>(T_MATERIALS);
-}
diff --git a/GUI/Model/Material/MaterialItemContainer.h b/GUI/Model/Material/MaterialItemContainer.h
deleted file mode 100644
index 8ef61c64c43..00000000000
--- a/GUI/Model/Material/MaterialItemContainer.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      GUI/Model/Material/MaterialItemContainer.h
-//! @brief     Defines class MaterialItemContainer
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#ifndef BORNAGAIN_GUI_MODEL_MATERIAL_MATERIALITEMCONTAINER_H
-#define BORNAGAIN_GUI_MODEL_MATERIAL_MATERIALITEMCONTAINER_H
-
-#include "GUI/Model/Session/SessionItem.h"
-
-class MaterialItem;
-
-class MaterialItemContainer : public SessionItem {
-private:
-    static constexpr auto T_MATERIALS{"MaterialVector"};
-
-public:
-    static constexpr auto M_TYPE{"MaterialContainer"};
-
-    MaterialItemContainer();
-
-    //! Copies MaterialItem, inserts it into the container
-    //! and returns a pointer to the copy.
-    MaterialItem* insertCopy(MaterialItem* material_item);
-
-    //! Can be nullptr if not found
-    const MaterialItem* findMaterialById(QString id) const;
-
-    //! Can be nullptr if not found
-    MaterialItem* findMaterialById(QString id);
-
-    QVector<MaterialItem*> getMaterials();
-};
-
-#endif // BORNAGAIN_GUI_MODEL_MATERIAL_MATERIALITEMCONTAINER_H
-- 
GitLab