From d9415e6c878b65e13a6620edfb24d0224f77ec87 Mon Sep 17 00:00:00 2001
From: Matthias Puchner <github@mpuchner.de>
Date: Fri, 27 Aug 2021 09:48:27 +0200
Subject: [PATCH] refactor instrument copy

---
 GUI/Models/InstrumentModel.cpp                | 27 ++++++++++++
 GUI/Models/InstrumentModel.h                  |  5 +++
 .../InstrumentSelectorWidget.cpp              | 42 ++++++-------------
 .../InstrumentSelectorWidget.h                |  2 +
 4 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/GUI/Models/InstrumentModel.cpp b/GUI/Models/InstrumentModel.cpp
index 072be044b2d..94a80e6d03d 100644
--- a/GUI/Models/InstrumentModel.cpp
+++ b/GUI/Models/InstrumentModel.cpp
@@ -71,6 +71,33 @@ void InstrumentModel::readFrom(QXmlStreamReader* reader, MessageService* message
         emit instrumentAddedOrRemoved();
 }
 
+InstrumentItem* InstrumentModel::insertCopy(const InstrumentItem& source)
+{
+    InstrumentItem* copy = static_cast<InstrumentItem*>(insertNewItem(source.modelType()));
+    const QString idBackup = copy->id(); // will be overwritten by the following
+    for (auto child : source.children()) {
+        auto tag = source.tagFromItem(child);
+        copyItem(child, copy, tag);
+    }
+    copy->setId(idBackup);
+
+    // copying non-uniform axis data
+    if (auto specularSource = dynamic_cast<const SpecularInstrumentItem*>(&source)) {
+        auto axis_group = specularSource->beamItem()->inclinationAxisGroup();
+
+        auto donor_axis = axis_group->itemOfType<PointwiseAxisItem>();
+        if (donor_axis->containsNonXMLData()) {
+            auto acceptor_axis = dynamic_cast<SpecularInstrumentItem*>(copy)
+                                     ->beamItem()
+                                     ->inclinationAxisGroup()
+                                     ->itemOfType<PointwiseAxisItem>();
+            acceptor_axis->init(*donor_axis->axis(), donor_axis->getUnitsLabel());
+        }
+    }
+
+    return copy;
+}
+
 QVector<InstrumentItem*> InstrumentModel::instrumentItems() const
 {
     return topItems<InstrumentItem>();
diff --git a/GUI/Models/InstrumentModel.h b/GUI/Models/InstrumentModel.h
index 597b9a49f5e..cd691c7d47a 100644
--- a/GUI/Models/InstrumentModel.h
+++ b/GUI/Models/InstrumentModel.h
@@ -31,6 +31,11 @@ public:
     QVector<SessionItem*> nonXMLItems() const override;
     virtual void readFrom(QXmlStreamReader* reader, MessageService* messageService = 0) override;
 
+    //! Inserts a deep copy (also of any non xml data in a pointwise axis)
+    //! The id will not be copied, but a new unique one will created
+    //! Returns the newly created instrument.
+    InstrumentItem* insertCopy(const InstrumentItem& instrument);
+
     QVector<InstrumentItem*> instrumentItems() const;
     QVector<Instrument2DItem*> instrument2DItems() const;
 
diff --git a/GUI/Views/InstrumentWidgets/InstrumentSelectorWidget.cpp b/GUI/Views/InstrumentWidgets/InstrumentSelectorWidget.cpp
index 0daced01d8b..fcc42709e3a 100644
--- a/GUI/Views/InstrumentWidgets/InstrumentSelectorWidget.cpp
+++ b/GUI/Views/InstrumentWidgets/InstrumentSelectorWidget.cpp
@@ -25,7 +25,7 @@
 #include <QVBoxLayout>
 
 InstrumentSelectorWidget::InstrumentSelectorWidget(InstrumentModel* model, QWidget* parent)
-    : ItemSelectorWidget(parent)
+    : ItemSelectorWidget(parent), m_instrumentModel(model)
 {
     setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
 
@@ -156,36 +156,18 @@ void InstrumentSelectorWidget::onRemove()
 void InstrumentSelectorWidget::onCopy()
 {
     QModelIndex index = selectionModel()->selectedIndexes().front();
+    if (!index.isValid())
+        return;
 
-    if (index.isValid()) {
-        SessionItem* item = m_model->itemForIndex(index);
-        QString nameOfCopy = suggestInstrumentName(item->itemName());
-        InstrumentItem* copy =
-            static_cast<InstrumentItem*>(m_model->insertNewItem(item->modelType()));
-        const QString idBackup = copy->id(); // will be overwritten by the following
-        for (auto child : item->children()) {
-            auto tag = item->tagFromItem(child);
-            m_model->copyItem(child, copy, tag);
-        }
-        copy->setId(idBackup);
-        copy->setItemName(nameOfCopy);
-
-        // copying non-uniform axis data
-        if (auto instrument = dynamic_cast<SpecularInstrumentItem*>(item)) {
-            auto axis_group = instrument->beamItem()->inclinationAxisGroup();
-
-            auto donor_axis = axis_group->itemOfType<PointwiseAxisItem>();
-            if (!donor_axis->containsNonXMLData())
-                return;
-
-            auto acceptor_axis = dynamic_cast<SpecularInstrumentItem*>(copy)
-                                     ->beamItem()
-                                     ->inclinationAxisGroup()
-                                     ->itemOfType<PointwiseAxisItem>();
-            acceptor_axis->init(*donor_axis->axis(), donor_axis->getUnitsLabel());
-        }
-        selectionModel()->select(m_model->indexOfItem(copy), QItemSelectionModel::ClearAndSelect);
-    }
+    const InstrumentItem* toBeCopied = dynamic_cast<InstrumentItem*>(m_model->itemForIndex(index));
+    if (toBeCopied == nullptr)
+        return;
+
+    const auto newName = suggestInstrumentName(toBeCopied->instrumentName());
+    InstrumentItem* copy = m_instrumentModel->insertCopy(*toBeCopied);
+    copy->setItemName(newName);
+
+    selectionModel()->select(m_model->indexOfItem(copy), QItemSelectionModel::ClearAndSelect);
 }
 
 void InstrumentSelectorWidget::updateActions()
diff --git a/GUI/Views/InstrumentWidgets/InstrumentSelectorWidget.h b/GUI/Views/InstrumentWidgets/InstrumentSelectorWidget.h
index b0ddfacda0d..cec90551d1d 100644
--- a/GUI/Views/InstrumentWidgets/InstrumentSelectorWidget.h
+++ b/GUI/Views/InstrumentWidgets/InstrumentSelectorWidget.h
@@ -48,6 +48,8 @@ private:
     QMap<QString, int> mapOfNames();
     template <class Instrument> void newInstrument();
 
+    InstrumentModel* m_instrumentModel;
+
 public:
     QAction* m_action_new_gisas;
     QAction* m_action_new_offspecular;
-- 
GitLab