From a2ee3adbce7cc9050094532aa4018d94ea7fea29 Mon Sep 17 00:00:00 2001
From: Matthias Puchner <github@mpuchner.de>
Date: Fri, 17 Sep 2021 08:57:26 +0200
Subject: [PATCH] add convenience and book-keeping methods to items
 (add/remove/setter/getter)

---
 GUI/Models/ItemWithMaterial.cpp        |  5 +++++
 GUI/Models/ItemWithMaterial.h          |  7 ++++++-
 GUI/Models/LayerItem.cpp               |  5 +++++
 GUI/Models/LayerItem.h                 |  1 +
 GUI/Models/MultiLayerItem.cpp          | 11 +++++++++++
 GUI/Models/MultiLayerItem.h            |  1 +
 GUI/Models/ParticleCompositionItem.cpp |  5 +++++
 GUI/Models/ParticleCompositionItem.h   |  1 +
 GUI/Models/ParticleLayoutItem.cpp      |  5 +++++
 GUI/Models/ParticleLayoutItem.h        |  1 +
 GUI/Models/SamplesTreeModel.cpp        | 18 ++++++++++++++++++
 GUI/Models/SamplesTreeModel.h          |  3 +++
 12 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/GUI/Models/ItemWithMaterial.cpp b/GUI/Models/ItemWithMaterial.cpp
index 6ce5f0a8b42..3564c5829b9 100644
--- a/GUI/Models/ItemWithMaterial.cpp
+++ b/GUI/Models/ItemWithMaterial.cpp
@@ -23,6 +23,11 @@ void ItemWithMaterial::setMaterial(const MaterialItem* materialItem)
     setItemValue(P_MATERIAL, materialItem->identifier());
 }
 
+void ItemWithMaterial::setMaterial(const QString& materialIdentifier)
+{
+    setItemValue(P_MATERIAL, materialIdentifier);
+}
+
 bool ItemWithMaterial::isMaterialPropertyName(const QString& name)
 {
     return name == P_MATERIAL;
diff --git a/GUI/Models/ItemWithMaterial.h b/GUI/Models/ItemWithMaterial.h
index 5860cc4cc34..fac18285505 100644
--- a/GUI/Models/ItemWithMaterial.h
+++ b/GUI/Models/ItemWithMaterial.h
@@ -26,9 +26,14 @@ private:
 public:
     static bool isMaterialPropertyName(const QString& name);
 
-    //! Set the material this item shall use. Stores the identifier, not the pointer!
+    //! Set the material this item shall use.
+    //! Stores the identifier, not the pointer!
     void setMaterial(const MaterialItem* materialItem);
 
+    //! Set the material this item shall use.
+    //! Stores the given identifier, not a pointer to the material!
+    void setMaterial(const QString& materialIdentifier);
+
     //! Set "no material defined"
     void setMaterialUndefined();
 
diff --git a/GUI/Models/LayerItem.cpp b/GUI/Models/LayerItem.cpp
index 74f5aed35ce..16dc9bcea1c 100644
--- a/GUI/Models/LayerItem.cpp
+++ b/GUI/Models/LayerItem.cpp
@@ -108,6 +108,11 @@ QVector<ParticleLayoutItem*> LayerItem::layouts() const
     return items<ParticleLayoutItem>(T_LAYOUTS);
 }
 
+void LayerItem::removeLayout(ParticleLayoutItem* layout)
+{
+    model()->removeItem(layout);
+}
+
 void LayerItem::updateAppearance(SessionItem* new_parent)
 {
     if (!new_parent) {
diff --git a/GUI/Models/LayerItem.h b/GUI/Models/LayerItem.h
index fea1cabf5ee..8a03fe293b7 100644
--- a/GUI/Models/LayerItem.h
+++ b/GUI/Models/LayerItem.h
@@ -49,6 +49,7 @@ public:
     SessionItem* numSlicesItem() const;
 
     QVector<ParticleLayoutItem*> layouts() const;
+    void removeLayout(ParticleLayoutItem* layout);
 
 private:
     void updateAppearance(SessionItem* new_parent);
diff --git a/GUI/Models/MultiLayerItem.cpp b/GUI/Models/MultiLayerItem.cpp
index 69d8f6502a9..156e2ef5575 100644
--- a/GUI/Models/MultiLayerItem.cpp
+++ b/GUI/Models/MultiLayerItem.cpp
@@ -107,6 +107,17 @@ void MultiLayerItem::removeLayer(LayerItem* item)
     model()->removeItem(item);
 }
 
+
+void MultiLayerItem::moveLayer(LayerItem* item, LayerItem* beforeThisLayer)
+{
+    int index = -1; // move to end
+    if (beforeThisLayer != nullptr) {
+        index = layers().indexOf(beforeThisLayer);
+    }
+
+    model()->moveItem(item, this, index);
+}
+
 void MultiLayerItem::updateLayers()
 {
     QVector<LayerItem*> list = childrenOfType<LayerItem>();
diff --git a/GUI/Models/MultiLayerItem.h b/GUI/Models/MultiLayerItem.h
index ee079fb7938..65a2f2a491e 100644
--- a/GUI/Models/MultiLayerItem.h
+++ b/GUI/Models/MultiLayerItem.h
@@ -55,6 +55,7 @@ public:
     LayerItem* addLayer(int index);
 
     void removeLayer(LayerItem* item);
+    void moveLayer(LayerItem* item, LayerItem* beforeThisLayer);
 
 private:
     void updateLayers();
diff --git a/GUI/Models/ParticleCompositionItem.cpp b/GUI/Models/ParticleCompositionItem.cpp
index 995e622d7a4..7445774b4ac 100644
--- a/GUI/Models/ParticleCompositionItem.cpp
+++ b/GUI/Models/ParticleCompositionItem.cpp
@@ -89,3 +89,8 @@ void ParticleCompositionItem::addParticle(ItemWithParticles* particle)
 {
     model()->moveItem(particle, this, -1, T_PARTICLES);
 }
+
+void ParticleCompositionItem::removeParticle(ItemWithParticles* particle)
+{
+    model()->removeItem(particle);
+}
diff --git a/GUI/Models/ParticleCompositionItem.h b/GUI/Models/ParticleCompositionItem.h
index bca44f32065..35ca50042cf 100644
--- a/GUI/Models/ParticleCompositionItem.h
+++ b/GUI/Models/ParticleCompositionItem.h
@@ -33,6 +33,7 @@ public:
 
     QVector<ItemWithParticles*> particles() const;
     void addParticle(ItemWithParticles* particle);
+    void removeParticle(ItemWithParticles* particle);
 };
 
 #endif // BORNAGAIN_GUI_MODELS_PARTICLECOMPOSITIONITEM_H
diff --git a/GUI/Models/ParticleLayoutItem.cpp b/GUI/Models/ParticleLayoutItem.cpp
index f4f63dfa2b9..cd83ea3f4fe 100644
--- a/GUI/Models/ParticleLayoutItem.cpp
+++ b/GUI/Models/ParticleLayoutItem.cpp
@@ -108,6 +108,11 @@ void ParticleLayoutItem::addParticle(ItemWithParticles* particle)
     model()->moveItem(particle, this, -1, T_PARTICLES);
 }
 
+void ParticleLayoutItem::removeParticle(ItemWithParticles* particle)
+{
+    model()->removeItem(particle);
+}
+
 InterferenceItem* ParticleLayoutItem::interference() const
 {
     return dynamic_cast<InterferenceItem*>(getItem(T_INTERFERENCE));
diff --git a/GUI/Models/ParticleLayoutItem.h b/GUI/Models/ParticleLayoutItem.h
index 275decfc4d9..0b05e37dd39 100644
--- a/GUI/Models/ParticleLayoutItem.h
+++ b/GUI/Models/ParticleLayoutItem.h
@@ -41,6 +41,7 @@ public:
 
     QVector<ItemWithParticles*> particles() const;
     void addParticle(ItemWithParticles* particle);
+    void removeParticle(ItemWithParticles* particle);
 
     InterferenceItem* interference() const;
     template <typename T> T* createInterference();
diff --git a/GUI/Models/SamplesTreeModel.cpp b/GUI/Models/SamplesTreeModel.cpp
index 960ed832a9a..0fa9329ccb2 100644
--- a/GUI/Models/SamplesTreeModel.cpp
+++ b/GUI/Models/SamplesTreeModel.cpp
@@ -14,9 +14,11 @@
 
 #include "GUI/Models/SamplesTreeModel.h"
 #include "GUI/Application/Application.h"
+#include "GUI/Models/GUIExamplesFactory.h"
 #include "GUI/Models/ModelUtils.h"
 #include "GUI/Models/MultiLayerItem.h"
 #include "GUI/Models/SampleModel.h"
+#include "GUI/mainwindow/projectmanager.h"
 #include <QApplication>
 #include <QFontMetrics>
 #include <QIcon>
@@ -213,3 +215,19 @@ QModelIndex SamplesTreeModel::createSample()
     endInsertRows();
     return indexForItem(multilayer_item);
 }
+
+QModelIndex SamplesTreeModel::createSampleFromExamples(const QString& className,
+                                                       const QString& title,
+                                                       const QString& description)
+{
+    const int row = m_sampleModel->multiLayerItems().size();
+    beginInsertRows(index(0, 0), row, row);
+
+    auto* sample = dynamic_cast<MultiLayerItem*>(GUIExamplesFactory::createSampleItems(
+        className, m_sampleModel, ProjectManager::instance()->document()->materialModel()));
+    sample->setItemName(title);
+    sample->setDescription(description);
+
+    endInsertRows();
+    return indexForItem(sample);
+}
diff --git a/GUI/Models/SamplesTreeModel.h b/GUI/Models/SamplesTreeModel.h
index 071e26133bc..af65fb27aa6 100644
--- a/GUI/Models/SamplesTreeModel.h
+++ b/GUI/Models/SamplesTreeModel.h
@@ -48,6 +48,9 @@ public:
 
     //! Create a new sample (multilayer) and return the index of it.
     QModelIndex createSample();
+    QModelIndex createSampleFromExamples(const QString& className, const QString& title,
+                                         const QString& description);
+
 
 private:
     void clear();
-- 
GitLab