diff --git a/Base/Types/OwningVector.h b/Base/Types/OwningVector.h
index 8b084ef76a894966c3fd82e950a394707fe6e9e1..c92b2c28a52ea942e63c8b84b71b1de6df668c24 100644
--- a/Base/Types/OwningVector.h
+++ b/Base/Types/OwningVector.h
@@ -70,8 +70,15 @@ public:
                 return;
             }
     }
-
-    T* release_at(size_t i)
+    void delete_at(size_t i)
+    {
+        if (i >= m_v.size())
+            return;
+        delete m_v[i];
+        m_v.erase(m_v.begin() + i);
+        return;
+    }
+    T* release_at(size_t i) // TODO rm
     {
         if (i >= m_v.size())
             return nullptr;
diff --git a/GUI/Model/Device/DatafileItem.cpp b/GUI/Model/Device/DatafileItem.cpp
index c12f62ad8435622a8d21e3449c152fe4afab0175..6642fdf09312bab20657e0b2e0ccac3259dce462 100644
--- a/GUI/Model/Device/DatafileItem.cpp
+++ b/GUI/Model/Device/DatafileItem.cpp
@@ -234,13 +234,13 @@ void DatafileItem::readFrom(QXmlStreamReader* r)
     }
 }
 
-void DatafileItem::writeDatafiles(const QString& projectDir) const
+void DatafileItem::saveDatafield(const QString& projectDir) const
 {
     if (m_data_item)
         m_data_item->saveDatafield(projectDir);
 }
 
-QString DatafileItem::readDatafiles(const QString& projectDir, MessageService* messageService)
+QString DatafileItem::loadDatafield(const QString& projectDir, MessageService* messageService)
 {
     if (m_data_item) {
         QString dataError = m_data_item->loadDatafield(messageService, projectDir, rank());
diff --git a/GUI/Model/Device/DatafileItem.h b/GUI/Model/Device/DatafileItem.h
index 239c7f3b29996f1fc60242ed0417e66cae5191dd..1814d6244665b377cb87f3e492875a22f864de61 100644
--- a/GUI/Model/Device/DatafileItem.h
+++ b/GUI/Model/Device/DatafileItem.h
@@ -67,8 +67,8 @@ public:
     void writeTo(QXmlStreamWriter* w) const;
     void readFrom(QXmlStreamReader* r);
 
-    void writeDatafiles(const QString& projectDir) const;
-    QString readDatafiles(const QString& projectDir, MessageService* messageService);
+    void saveDatafield(const QString& projectDir) const;
+    QString loadDatafield(const QString& projectDir, MessageService* messageService);
 
     //... Other
 
diff --git a/GUI/Model/Files/DatafilesQModel.cpp b/GUI/Model/Files/DatafilesQModel.cpp
index 415e79a0aa4bb8f4a9466777afaa630cfba6952e..73d4e3218bf6cb6d4bfd788ac396697edb286674 100644
--- a/GUI/Model/Files/DatafilesQModel.cpp
+++ b/GUI/Model/Files/DatafilesQModel.cpp
@@ -15,199 +15,69 @@
 #include "GUI/Model/Files/DatafilesQModel.h"
 #include "GUI/Model/Device/DatafileItem.h"
 #include "GUI/Model/Files/DatafilesSet.h"
-#include <QApplication>
-#include <QFontMetrics>
-#include <QPalette>
 
 DatafilesQModel::DatafilesQModel(QObject* parent, DatafilesSet* model)
-    : QAbstractItemModel(parent)
+    : QAbstractListModel(parent)
     , m_model(model)
 {
-    for (int rank : {1, 2})
-        m_items[rank - 1] = model->dfileItems(rank);
-}
-
-bool DatafilesQModel::setData(const QModelIndex& index, const QVariant& value, int role)
-{
-    if (role == Qt::EditRole && index.isValid() && index.column() == 0) {
-        itemForIndex(index)->setDatafileItemName(value.toString());
-        emit dataChanged(index, index);
-        return true;
-    }
-    return false;
 }
 
 void DatafilesQModel::injectDatafileItem(DatafileItem* item)
 {
-    m_model->insertDatafileItem(item);
-    const int rank = item->rank();
-    const int rowOfItem = m_model->dfileItems(rank).indexOf(item);
-    beginInsertRows(indexOfHeadline(rank), rowOfItem, rowOfItem);
-    m_items[rank - 1] = m_model->dfileItems(rank);
+    const int row = m_model->size();
+    beginInsertRows({}, row, row);
+    m_model->appendDatafileItem(item);
     endInsertRows();
 }
 
-void DatafilesQModel::removeDatafileItem(DatafileItem* item)
+void DatafilesQModel::removeDatafileItemAt(int row)
 {
-    QModelIndex index = indexForItem(item);
-    if (!index.isValid())
-        return;
-    const int rank = item->rank();
-    const int rowOfItem = m_items[rank - 1].indexOf(item);
-    beginRemoveRows(indexOfHeadline(rank), rowOfItem, rowOfItem);
-    m_items[rank - 1].removeAll(item);
-    m_model->removeDatafileItem(item);
+    ASSERT(0 <= row && row < (int)m_model->size());
+    beginRemoveRows({}, row, row);
+    m_model->deleteDatafileItemAt(row);
     endRemoveRows();
 }
 
-DatafileItem* DatafilesQModel::topMostItem() const
+const DatafileItem* DatafilesQModel::topMostItem() const
 {
-    if (!m_items[0].isEmpty())
-        return m_items[0].first();
-    if (!m_items[1].isEmpty())
-        return m_items[1].first();
+    if (m_model->size() > 0)
+        return m_model->dfileItemAt(0);
     return nullptr;
 }
 
-QModelIndex DatafilesQModel::indexOfHeadline(int rank) const
+int DatafilesQModel::rowCount(const QModelIndex& /*parent*/) const
 {
-    return createIndex(rank - 1, 0, nullptr);
-}
-
-QModelIndex DatafilesQModel::index(int row, int column, const QModelIndex& parent) const
-{
-    if (!hasIndex(row, column, parent))
-        return {};
-
-    if (!parent.isValid())
-        return createIndex(row, column, nullptr);
-
-    for (int rank : {1, 2})
-        if (parent == indexOfHeadline(rank))
-            return createIndex(row, column, m_items[rank - 1][row]);
-
-    return {};
-}
-
-QModelIndex DatafilesQModel::parent(const QModelIndex& index) const
-{
-    if (!index.isValid())
-        return {};
-
-    if (index.internalPointer() == nullptr) // index is headline => no parent
-        return {};
-
-    return indexOfHeadline(itemForIndex(index)->rank());
-}
-
-int DatafilesQModel::columnCount(const QModelIndex& /*parent*/) const
-{
-    return 1;
-}
-
-int DatafilesQModel::rowCount(const QModelIndex& parent) const
-{
-    if (!parent.isValid())
-        return 2;
-
-    // parent is a headline
-    for (int rank : {1, 2})
-        if (parent == indexOfHeadline(rank))
-            return m_items[rank - 1].size();
-
-    return 0;
+    return m_model->size();
 }
 
 QVariant DatafilesQModel::data(const QModelIndex& index, int role) const
 {
-    if (isHeadline(index)) {
-        QString title = (index == indexOfHeadline(1)) ? "1D Data" : "2D Data";
-
-        switch (role) {
-        case Qt::DisplayRole:
-            return title;
-
-        case Qt::FontRole: {
-            QFont f(QApplication::font());
-            f.setPointSize(f.pointSize() * 1.5);
-            f.setBold(true);
-            return f;
-        }
-
-        case Qt::SizeHintRole: {
-            QFont f(QApplication::font());
-            f.setPointSize(f.pointSize() * 1.5);
-            f.setBold(true);
-            QSize s = QFontMetrics(f).boundingRect(title).size();
-            return QSize(s.width() * 2, s.height() * 2);
-        }
-
-        case Qt::TextAlignmentRole:
-            return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
-
-        case Qt::BackgroundRole:
-            return qApp->palette().color(QPalette::Base);
-
-        case Qt::ForegroundRole:
-            return qApp->palette().color(QPalette::Text);
-
-        default:
-            return {};
-        }
-    }
-
-    auto* const item = itemForIndex(index);
-
-    if (role == Qt::ToolTipRole)
+    if (!index.isValid() || index.row() >= (int)m_model->size() || index.row() < 0)
         return {};
 
+    const auto* item = itemForIndex(index);
+    ASSERT(item);
+
     if (role == Qt::DisplayRole)
         return item->realItemName();
 
-    if (role == Qt::EditRole)
-        return item->realItemName();
+    if (role == Qt::ToolTipRole)
+        return {};
 
     return {};
 }
 
-Qt::ItemFlags DatafilesQModel::flags(const QModelIndex& index) const
-{
-    if (isHeadline(index) || !index.isValid())
-        return Qt::NoItemFlags;
-
-    auto f = QAbstractItemModel::flags(index);
-    f |= Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled;
-
-    if (index.column() == 0) // col 0 contains name of the data entry
-        f |= Qt::ItemIsEditable;
-
-    return f;
-}
-
 DatafileItem* DatafilesQModel::itemForIndex(const QModelIndex& index) const
 {
-    if (!index.isValid())
+    if (!index.isValid() || index.row() >= (int)m_model->size() || index.row() < 0)
         return nullptr;
-
-    return reinterpret_cast<DatafileItem*>(index.internalPointer());
+    return m_model->dfileItemAt(index.row());
 }
 
-QModelIndex DatafilesQModel::indexForItem(DatafileItem* item) const
+QModelIndex DatafilesQModel::indexForItem(const DatafileItem* item) const
 {
-    if (item == nullptr)
-        return {};
-
-    const int rank = item->rank();
-    if (auto index = m_items[rank - 1].indexOf(item); index >= 0)
-        return createIndex(index, 0, item);
-
+    for (size_t i = 0; i < m_model->size(); ++i)
+        if (m_model->dfileItemAt(i) == item)
+            return createIndex(i, 0, item);
     return {};
 }
-
-bool DatafilesQModel::isHeadline(const QModelIndex& index) const
-{
-    if (!index.isValid())
-        return false;
-
-    return index.internalPointer() == nullptr;
-}
diff --git a/GUI/Model/Files/DatafilesQModel.h b/GUI/Model/Files/DatafilesQModel.h
index 038f183dd315a0221d43a09d5b537d2d4959338f..0b908b0c0f63b4928b57f3a4ff2dac0fd7eccd17 100644
--- a/GUI/Model/Files/DatafilesQModel.h
+++ b/GUI/Model/Files/DatafilesQModel.h
@@ -15,39 +15,31 @@
 #ifndef BORNAGAIN_GUI_MODEL_FILES_DATAFILESQMODEL_H
 #define BORNAGAIN_GUI_MODEL_FILES_DATAFILESQMODEL_H
 
-#include <QAbstractItemModel>
+#include <QAbstractListModel>
 
 class DatafileItem;
 class DatafilesSet;
 
 //! Tree representation of DatafilesSet, for use in DatafilesSelector.
 
-class DatafilesQModel : public QAbstractItemModel {
+class DatafilesQModel : public QAbstractListModel {
     Q_OBJECT
 public:
     explicit DatafilesQModel(QObject* parent, DatafilesSet* model);
 
-    bool setData(const QModelIndex& index, const QVariant& value, int role) override;
     void injectDatafileItem(DatafileItem* item);
-    void removeDatafileItem(DatafileItem* item);
+    void removeDatafileItemAt(int row);
 
-    QModelIndex index(int row, int column,
-                      const QModelIndex& parent = QModelIndex()) const override;
-    QModelIndex parent(const QModelIndex& index) const override;
-    int columnCount(const QModelIndex& parent = QModelIndex()) const override;
-    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+    int rowCount(const QModelIndex& parent = {}) const override;
     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
-    Qt::ItemFlags flags(const QModelIndex& index) const override;
 
     DatafileItem* itemForIndex(const QModelIndex& index) const;
-    QModelIndex indexForItem(DatafileItem* item) const;
-    DatafileItem* topMostItem() const; //!< The topmost visible item. Can be null.
-    QModelIndex indexOfHeadline(int rank) const;
-    bool isHeadline(const QModelIndex& index) const;
+    QModelIndex indexForItem(const DatafileItem* item) const;
+    const DatafileItem* topMostItem() const; //!< The topmost visible item. Can be null.
+    bool isHeadline(const QModelIndex&) const { return false; }
 
 private:
     DatafilesSet* const m_model;
-    QVector<DatafileItem*> m_items[2]; //< Items borrowed from model. Never delete the ptrs!
 };
 
 #endif // BORNAGAIN_GUI_MODEL_FILES_DATAFILESQMODEL_H
diff --git a/GUI/Model/Files/DatafilesSet.cpp b/GUI/Model/Files/DatafilesSet.cpp
index 3e28040fa03f50189ff3fcf80e454b80bc1a8353..7f4b990e9b7f1b1ba19e0aac3bbb5feb68e0278a 100644
--- a/GUI/Model/Files/DatafilesSet.cpp
+++ b/GUI/Model/Files/DatafilesSet.cpp
@@ -22,7 +22,6 @@ namespace Tag {
 
 const QString RealData("RealData");
 const QString CurrentIndex("CurrentIndex");
-const QString SelectedRank("SelectedRank");
 
 } // namespace Tag
 } // namespace
@@ -34,20 +33,28 @@ DatafilesSet::DatafilesSet()
 
 DatafilesSet::~DatafilesSet() = default;
 
-QVector<DataItem*> DatafilesSet::dataItems() const
+void DatafilesSet::appendDatafileItem(DatafileItem* dfi)
 {
-    QVector<DataItem*> result;
-    for (auto* dfile_item : dfileItems())
-        if (auto* data_item = dfile_item->dataItem())
-            result.push_back(data_item);
+    m_dfile_items.emplace_back(dfi);
+}
 
-    return result;
+void DatafilesSet::deleteDatafileItemAt(int index)
+{
+    m_dfile_items.delete_at(index);
 }
 
 void DatafilesSet::clear()
 {
-    for (auto* dfile_item : dfileItems())
-        removeDatafileItem(dfile_item);
+    m_dfile_items.clear();
+}
+
+QVector<DataItem*> DatafilesSet::dataItems() const
+{
+    QVector<DataItem*> result;
+    for (auto* dfi : m_dfile_items)
+        if (auto* data_item = dfi->dataItem())
+            result.push_back(data_item);
+    return result;
 }
 
 void DatafilesSet::writeTo(QXmlStreamWriter* w) const
@@ -55,10 +62,10 @@ void DatafilesSet::writeTo(QXmlStreamWriter* w) const
     XML::writeAttribute(w, XML::Attrib::version, uint(1));
 
     // real items
-    for (auto* dfile_item : dfileItems()) {
+    for (auto* dfi : m_dfile_items) {
         w->writeStartElement(Tag::RealData);
-        XML::writeAttribute(w, XML::Attrib::name, dfile_item->realItemName());
-        dfile_item->writeTo(w);
+        XML::writeAttribute(w, XML::Attrib::name, dfi->realItemName());
+        dfi->writeTo(w);
         w->writeEndElement();
     }
 
@@ -66,11 +73,6 @@ void DatafilesSet::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::CurrentIndex);
     XML::writeAttribute(w, XML::Attrib::value, m_current_index);
     w->writeEndElement();
-
-    // selected rank
-    w->writeStartElement(Tag::SelectedRank);
-    XML::writeAttribute(w, XML::Attrib::value, m_selected_rank);
-    w->writeEndElement();
 }
 
 void DatafilesSet::readFrom(QXmlStreamReader* r)
@@ -95,11 +97,6 @@ void DatafilesSet::readFrom(QXmlStreamReader* r)
             XML::readAttribute(r, XML::Attrib::value, &m_current_index);
             XML::gotoEndElementOfTag(r, tag);
 
-            // selected rank
-        } else if (tag == Tag::SelectedRank) {
-            XML::readAttribute(r, XML::Attrib::value, &m_selected_rank);
-            XML::gotoEndElementOfTag(r, tag);
-
         } else
             r->skipCurrentElement();
     }
@@ -108,74 +105,26 @@ void DatafilesSet::readFrom(QXmlStreamReader* r)
         throw std::runtime_error(r->errorString().toLatin1());
 }
 
-void DatafilesSet::writeDatafiles(const QString& projectDir)
+void DatafilesSet::writeDatafiles(const QString& projectDir) const
 {
-    for (const auto* dfile_item : dfileItems())
-        dfile_item->writeDatafiles(projectDir);
+    for (const auto* dfi : m_dfile_items)
+        dfi->saveDatafield(projectDir);
 
     dataFilesCleaner.cleanOldFiles(projectDir, dataItems());
 }
 
 void DatafilesSet::readDatafiles(const QString& projectDir, MessageService* messageService)
 {
-    for (auto* dfile_item : dfileItems())
-        dfile_item->readDatafiles(projectDir, messageService);
+    for (auto* dfi : m_dfile_items)
+        dfi->loadDatafield(projectDir, messageService);
 
     dataFilesCleaner.recollectDataNames(dataItems());
 }
 
-void DatafilesSet::insertDatafileItem(DatafileItem* dfi)
-{
-    m_dfile_items.emplace_back(dfi);
-}
-
-QVector<DatafileItem*> DatafilesSet::dfileItems() const
-{
-    QVector<DatafileItem*> items(m_dfile_items.size());
-    for (int i = 0; i < items.size(); i++)
-        items[i] = m_dfile_items[i].get();
-    return items;
-}
-
-
-QVector<DatafileItem*> DatafilesSet::dfileItems(int rank) const
-{
-    return rank == 1 ? realItems1D() : realItems2D();
-}
-
-QVector<DatafileItem*> DatafilesSet::realItems1D() const
-{
-    QVector<DatafileItem*> vec_1d;
-
-    for (DatafileItem* dfile_item : dfileItems())
-        if (dfile_item->rank() == 1)
-            vec_1d.push_back(dfile_item);
-
-    return vec_1d;
-}
-
-QVector<DatafileItem*> DatafilesSet::realItems2D() const
-{
-    QVector<DatafileItem*> vec_2d;
-
-    for (DatafileItem* dfile_item : dfileItems())
-        if (dfile_item->rank() == 2)
-            vec_2d.push_back(dfile_item);
-
-    return vec_2d;
-}
-
-void DatafilesSet::removeDatafileItem(DatafileItem* dfile_item)
-{
-    ASSERT(dfile_item);
-    int index = dfileItems().indexOf(dfile_item);
-    m_dfile_items.erase(m_dfile_items.begin() + index);
-}
-
 QStringList DatafilesSet::realItemNames() const
 {
     QStringList result;
-    for (DatafileItem* dfile_item : dfileItems())
-        result.append(dfile_item->realItemName());
+    for (DatafileItem* dfi : m_dfile_items)
+        result.append(dfi->realItemName());
     return result;
 }
diff --git a/GUI/Model/Files/DatafilesSet.h b/GUI/Model/Files/DatafilesSet.h
index 3dc4a6f7c70c3ccc4fac6d0ba2dbcbc31f654256..09d7a89966ee06b60ac30d0e18acc18559e5a87a 100644
--- a/GUI/Model/Files/DatafilesSet.h
+++ b/GUI/Model/Files/DatafilesSet.h
@@ -15,13 +15,13 @@
 #ifndef BORNAGAIN_GUI_MODEL_FILES_DATAFILESSET_H
 #define BORNAGAIN_GUI_MODEL_FILES_DATAFILESSET_H
 
+#include "Base/Types/OwningVector.h"
 #include "GUI/Model/Files/DatafilesCleaner.h"
 #include <QObject>
 #include <QXmlStreamWriter>
 
 class DataItem;
 class DatafileItem;
-class InstrumentsSet;
 class MessageService;
 
 //! The DatafilesSet class is a model to store all imported DatafileItem's.
@@ -31,37 +31,28 @@ public:
     explicit DatafilesSet();
     ~DatafilesSet();
 
-    QVector<DataItem*> dataItems() const;
+    void appendDatafileItem(DatafileItem* dfi);
+    void deleteDatafileItemAt(int index);
     void clear();
-
-    void writeTo(QXmlStreamWriter* w) const;
     void readFrom(QXmlStreamReader* r);
-
-    void writeDatafiles(const QString& projectDir);
     void readDatafiles(const QString& projectDir, MessageService* messageService);
+    void setCurrentIndex(int index) { m_current_index = index; }
 
-    void insertDatafileItem(DatafileItem* dfi);
-    QVector<DatafileItem*> dfileItems() const;
-    QVector<DatafileItem*> dfileItems(int rank) const;
-
-    QVector<DatafileItem*> realItems1D() const;
-    QVector<DatafileItem*> realItems2D() const;
-
-    void removeDatafileItem(DatafileItem* realItem);
-
+    size_t size() const { return m_dfile_items.size(); }
+    const OwningVector<DatafileItem>& dfileItems() const { return m_dfile_items; }
+    const DatafileItem* dfileItemAt(int i) const { return m_dfile_items.at(i); }
+    DatafileItem* dfileItemAt(int i) { return m_dfile_items.at(i); }
     QStringList realItemNames() const;
-
     int currentIndex() const { return m_current_index; }
-    void setCurrentIndex(int index) { m_current_index = index; }
-
-    int selectedRank() const { return m_selected_rank; }
-    void setSelectedRank(int rank) { m_selected_rank = rank; }
+    void writeTo(QXmlStreamWriter* w) const;
+    void writeDatafiles(const QString& projectDir) const;
 
 private:
-    DatafilesCleaner dataFilesCleaner;
-    std::vector<std::unique_ptr<DatafileItem>> m_dfile_items;
+    QVector<DataItem*> dataItems() const;
+
+    mutable DatafilesCleaner dataFilesCleaner;
+    OwningVector<DatafileItem> m_dfile_items;
     int m_current_index = -1;
-    int m_selected_rank = -1;
 };
 
 #endif // BORNAGAIN_GUI_MODEL_FILES_DATAFILESSET_H
diff --git a/GUI/Model/Job/JobItem.cpp b/GUI/Model/Job/JobItem.cpp
index 480b4a1bef1d18c3939f008d0d8a6db4988b2009..cd9978723edac4347c3e68c308f8643b136520d1 100644
--- a/GUI/Model/Job/JobItem.cpp
+++ b/GUI/Model/Job/JobItem.cpp
@@ -376,21 +376,21 @@ void JobItem::readFrom(QXmlStreamReader* r)
     }
 }
 
-void JobItem::writeDatafiles(const QString& projectDir) const
+void JobItem::saveDatafields(const QString& projectDir) const
 {
     if (m_dfile_item)
-        m_dfile_item->writeDatafiles(projectDir);
+        m_dfile_item->saveDatafield(projectDir);
 
     if (m_simulated_data_item)
         m_simulated_data_item->saveDatafield(projectDir);
 }
 
-void JobItem::readDatafiles(const QString& projectDir, MessageService* messageService)
+void JobItem::loadDatafields(const QString& projectDir, MessageService* messageService)
 {
     QString realError, simError, errorMessage;
 
     if (m_dfile_item)
-        realError = m_dfile_item->readDatafiles(projectDir, messageService);
+        realError = m_dfile_item->loadDatafield(projectDir, messageService);
 
     if (m_simulated_data_item)
         simError = m_simulated_data_item->loadDatafield(messageService, projectDir, rank());
diff --git a/GUI/Model/Job/JobItem.h b/GUI/Model/Job/JobItem.h
index f3534ce8a4ccef737810c16a49d24d37efc6701e..ecc34c758b90895087e7506446b06255a6470e92 100644
--- a/GUI/Model/Job/JobItem.h
+++ b/GUI/Model/Job/JobItem.h
@@ -108,8 +108,8 @@ public:
     void writeTo(QXmlStreamWriter* w) const;
     void readFrom(QXmlStreamReader* r);
 
-    void writeDatafiles(const QString& projectDir) const;
-    void readDatafiles(const QString& projectDir, MessageService* messageService);
+    void saveDatafields(const QString& projectDir) const;
+    void loadDatafields(const QString& projectDir, MessageService* messageService);
 
 signals:
     void jobSelected(JobItem* item);
diff --git a/GUI/Model/Project/LinkInstrumentManager.cpp b/GUI/Model/Project/LinkInstrumentManager.cpp
index aa9dc779723206f948c549d4621efd338ba8a456..794e0574bdd3677d50a7c6850dad9d53a334e658 100644
--- a/GUI/Model/Project/LinkInstrumentManager.cpp
+++ b/GUI/Model/Project/LinkInstrumentManager.cpp
@@ -86,7 +86,7 @@ LinkInstrumentManager::LinkInstrumentManager(ProjectDocument* document)
             &LinkInstrumentManager::onInstrumentChanged);
 }
 
-bool LinkInstrumentManager::canLinkDataToInstrument(const DatafileItem* dfile_item,
+bool LinkInstrumentManager::canLinkDataToInstrument(const DatafileItem* dfi,
                                                     const QString& identifier,
                                                     QWidget* parent) const
 {
@@ -96,23 +96,23 @@ bool LinkInstrumentManager::canLinkDataToInstrument(const DatafileItem* dfile_it
     if (!instrumentItem)
         return true;
 
-    if (instrumentItem->axdims().size() != dfile_item->axdims().size()) {
+    if (instrumentItem->axdims().size() != dfi->axdims().size()) {
         ::warn(parent, "Cannot link, data is incompatible with the instrument.");
         return false;
     }
 
-    if (instrumentItem->alignedWith(dfile_item))
+    if (instrumentItem->alignedWith(dfi))
         return true;
 
     ASSERT(parent);
     QString message =
-        dfile_item->holdsDimensionalData()
+        dfi->holdsDimensionalData()
             ? "Experimental data carries information on the range/points of measurement."
-            : printShapeMessage(instrumentItem->axdims(), dfile_item->axdims());
+            : printShapeMessage(instrumentItem->axdims(), dfi->axdims());
     if (!QuestionOnInstrumentReshaping(message))
         return false;
 
-    instrumentItem->updateToRealData(dfile_item);
+    instrumentItem->updateToRealData(dfi);
     emit m_doc->instruments()->instrumentChanged(instrumentItem);
     return true;
 }
@@ -121,20 +121,20 @@ void LinkInstrumentManager::onInstrumentChanged(const InstrumentItem* instrument
 {
     // Run through all DatafileItem and refresh linking to match possible change in detector
     // axes definition.
-    for (auto* dfile_item : m_doc->datafiles()->dfileItems())
-        if (dfile_item->instrumentId() == instrument->id()) {
-            if (!instrument->alignedWith(dfile_item)) {
-                dfile_item->unlinkFromInstrument();
-                emit linkToInstrumentChanged(dfile_item);
+    for (auto* dfi : m_doc->datafiles()->dfileItems())
+        if (dfi->instrumentId() == instrument->id()) {
+            if (!instrument->alignedWith(dfi)) {
+                dfi->unlinkFromInstrument();
+                emit linkToInstrumentChanged(dfi);
             } else
-                dfile_item->linkToInstrument(instrument); // link stays same, only data is updated
+                dfi->linkToInstrument(instrument); // link stays same, only data is updated
         }
 }
 
 void LinkInstrumentManager::onInstrumentAddedOrRemoved()
 {
     // remove links in realItems (in case of a linked instrument was removed)
-    for (auto* dfile_item : m_doc->datafiles()->dfileItems())
-        if (!m_doc->instruments()->instrumentExists(dfile_item->instrumentId()))
-            dfile_item->unlinkFromInstrument();
+    for (auto* dfi : m_doc->datafiles()->dfileItems())
+        if (!m_doc->instruments()->instrumentExists(dfi->instrumentId()))
+            dfi->unlinkFromInstrument();
 }
diff --git a/GUI/Model/Project/LinkInstrumentManager.h b/GUI/Model/Project/LinkInstrumentManager.h
index 87367c654156c91f4f25773fd569c1a1e7b2b26b..7be979aecd08050f4c098318adc60e3caf186099 100644
--- a/GUI/Model/Project/LinkInstrumentManager.h
+++ b/GUI/Model/Project/LinkInstrumentManager.h
@@ -35,11 +35,11 @@ public:
     //! quiet defines whether a "not possible" message box is shown if link is not possible. Use
     //! this e.g. for unit tests. The question for adjusting the instrument is not suppressed by
     //! this flag.
-    bool canLinkDataToInstrument(const DatafileItem* dfile_item, const QString& identifier,
+    bool canLinkDataToInstrument(const DatafileItem* dfi, const QString& identifier,
                                  QWidget* parent) const;
 
 signals:
-    void linkToInstrumentChanged(const DatafileItem* dfile_item);
+    void linkToInstrumentChanged(const DatafileItem* dfi);
 
 private:
     void onInstrumentChanged(const InstrumentItem* instrument);
diff --git a/GUI/Model/Project/ProjectDocument.cpp b/GUI/Model/Project/ProjectDocument.cpp
index d2e270b39c42add651d546e5c081c4c8ebafc87b..2a276c31e37603078c9f239b536a263b9a9c2325 100644
--- a/GUI/Model/Project/ProjectDocument.cpp
+++ b/GUI/Model/Project/ProjectDocument.cpp
@@ -126,7 +126,7 @@ void ProjectDocument::saveProjectFileWithData(const QString& projectPullPath)
     writeProject(&file);
     file.close();
 
-    m_jobs->writeDatafiles(GUI::Util::Project::projectDir(projectPullPath));
+    m_jobs->saveAllDatafields(GUI::Util::Project::projectDir(projectPullPath));
     m_datafiles->writeDatafiles(GUI::Util::Project::projectDir(projectPullPath));
 
     const bool autoSave = GUI::Util::Project::isAutosave(projectPullPath);
@@ -155,7 +155,7 @@ ProjectDocument::ReadResult ProjectDocument::loadProjectFileWithData(const QStri
         if (result == ReadResult::error)
             return result;
 
-        m_jobs->readDatafiles(GUI::Util::Project::projectDir(projectPullPath), &messageService);
+        m_jobs->loadAllDatafields(GUI::Util::Project::projectDir(projectPullPath), &messageService);
         m_datafiles->readDatafiles(GUI::Util::Project::projectDir(projectPullPath),
                                    &messageService);
 
diff --git a/GUI/Model/Tune/JobsSet.cpp b/GUI/Model/Tune/JobsSet.cpp
index 783c4c3cdc2a503af9c0fa63b794dcbf3f753a41..2603849a7fabb8cef59aa6bb831b04077bec84f7 100644
--- a/GUI/Model/Tune/JobsSet.cpp
+++ b/GUI/Model/Tune/JobsSet.cpp
@@ -84,18 +84,18 @@ void JobsSet::readFrom(QXmlStreamReader* r)
         throw std::runtime_error(r->errorString().toLatin1());
 }
 
-void JobsSet::writeDatafiles(const QString& projectDir)
+void JobsSet::saveAllDatafields(const QString& projectDir) const
 {
     for (const auto* job : m_job_items)
-        job->writeDatafiles(projectDir);
+        job->saveDatafields(projectDir);
 
     dataFilesCleaner.cleanOldFiles(projectDir, dataItems());
 }
 
-void JobsSet::readDatafiles(const QString& projectDir, MessageService* messageService)
+void JobsSet::loadAllDatafields(const QString& projectDir, MessageService* messageService)
 {
     for (auto* job : m_job_items)
-        job->readDatafiles(projectDir, messageService);
+        job->loadDatafields(projectDir, messageService);
 
     dataFilesCleaner.recollectDataNames(dataItems());
 }
diff --git a/GUI/Model/Tune/JobsSet.h b/GUI/Model/Tune/JobsSet.h
index f14deec715ebbdef5b0c3a22b7f3042eb73add81..7e7c6add852ddaccb6aea4fae9add7e8c66bc872 100644
--- a/GUI/Model/Tune/JobsSet.h
+++ b/GUI/Model/Tune/JobsSet.h
@@ -41,8 +41,8 @@ public:
     void writeTo(QXmlStreamWriter* w) const;
     void readFrom(QXmlStreamReader* r);
 
-    void writeDatafiles(const QString& projectDir);
-    void readDatafiles(const QString& projectDir, MessageService* messageService);
+    void saveAllDatafields(const QString& projectDir) const;
+    void loadAllDatafields(const QString& projectDir, MessageService* messageService);
 
     JobItem* createJobItem();
     void addJobItem(JobItem* job_item);
@@ -76,7 +76,7 @@ private slots:
 private:
     QString generateJobName() const;
 
-    DatafilesCleaner dataFilesCleaner;
+    mutable DatafilesCleaner dataFilesCleaner;
     OwningVector<JobItem> m_job_items;
     int m_current_index = -1;
 };
diff --git a/GUI/View/Canvas/MaskEditorCanvas.h b/GUI/View/Canvas/MaskEditorCanvas.h
index a87d747fe17a3eec8375a1ae8ee9801c4850e176..4d51b99f55d051947c484246bbe2ad06a917a4a3 100644
--- a/GUI/View/Canvas/MaskEditorCanvas.h
+++ b/GUI/View/Canvas/MaskEditorCanvas.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_VIEW_CANVAS_MASKEDITORCANVAS_H
 #define BORNAGAIN_GUI_VIEW_CANVAS_MASKEDITORCANVAS_H
 
-#include "GUI/View/Tool/Canvas2DMode.h"
+#include "GUI/View/Setup/Canvas2DMode.h"
 #include <QWidget>
 #include <memory>
 
diff --git a/GUI/View/Canvas/ProjectedGraphsCanvas.h b/GUI/View/Canvas/ProjectedGraphsCanvas.h
index 13fceb25767a825d59d980127eaa88670500867e..024e53bea18a33a9ac1a023d6bf267cbb1ef4b03 100644
--- a/GUI/View/Canvas/ProjectedGraphsCanvas.h
+++ b/GUI/View/Canvas/ProjectedGraphsCanvas.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_VIEW_CANVAS_PROJECTEDGRAPHSCANVAS_H
 #define BORNAGAIN_GUI_VIEW_CANVAS_PROJECTEDGRAPHSCANVAS_H
 
-#include "GUI/View/Tool/Canvas2DMode.h"
+#include "GUI/View/Setup/Canvas2DMode.h"
 #include <QTabWidget>
 
 class Data2DItem;
diff --git a/GUI/View/Data/DatafilesSelector.cpp b/GUI/View/Data/DatafilesSelector.cpp
index cf2d939922df3d660ec164b584d767bea6673737..0d9ef8060ddc3f18e05427349cdbe3f457ff552a 100644
--- a/GUI/View/Data/DatafilesSelector.cpp
+++ b/GUI/View/Data/DatafilesSelector.cpp
@@ -27,6 +27,7 @@
 #include "GUI/View/Loader/Legacy1dDialog.h"
 #include "GUI/View/Manager/ProjectManager.h"
 #include "GUI/View/Widget/ItemViewOverlayButtons.h"
+#include "GUI/View/Widget/ListItemDelegate.h"
 #include "GUI/View/Widget/StyledToolbar.h"
 #include <QBoxLayout>
 #include <QFileDialog>
@@ -149,6 +150,7 @@ DatafilesSelector::DatafilesSelector(StackedDataFrames* data_frames)
 
     ItemViewOverlayButtons::install(
         m_qview, [this](const QModelIndex& i, bool h) { return getOverlayActions(i, h); });
+    m_qview->setItemDelegate(new ListItemDelegate(this));
 }
 
 QSize DatafilesSelector::sizeHint() const
@@ -163,10 +165,21 @@ QSize DatafilesSelector::minimumSizeHint() const
 
 DatafileItem* DatafilesSelector::currentDatafileItem()
 {
-    return m_qmodel->itemForIndex(currentDatafileIndex());
+    const QModelIndex i = m_qview->selectionModel()->currentIndex();
+    if (!m_qview->selectionModel()->isSelected(i))
+        return nullptr;
+    return m_qmodel->itemForIndex(i);
 }
 
-void DatafilesSelector::setCurrentDatafileItem(DatafileItem* item)
+QModelIndex DatafilesSelector::currentDatafileIndex() const
+{
+    const QModelIndex i = m_qview->selectionModel()->currentIndex();
+    if (!m_qview->selectionModel()->isSelected(i))
+        return {};
+    return i;
+}
+
+void DatafilesSelector::setCurrentDatafileItem(const DatafileItem* item)
 {
     m_qview->selectionModel()->clearSelection();
     QModelIndex index = m_qmodel->indexForItem(item);
@@ -176,41 +189,21 @@ void DatafilesSelector::setCurrentDatafileItem(DatafileItem* item)
 
 void DatafilesSelector::restoreSelection()
 {
-    int lastIndex = gDoc->datafiles()->currentIndex();
-    int lastRank = gDoc->datafiles()->selectedRank();
-    QModelIndex lastUsedIndex = m_qmodel->index(lastIndex, 0, m_qmodel->indexOfHeadline(lastRank));
-
-    if (lastUsedIndex.isValid())
-        m_qview->selectionModel()->setCurrentIndex(lastUsedIndex,
-                                                   QItemSelectionModel::SelectCurrent);
-    else
-        setCurrentDatafileItem(m_qmodel->topMostItem());
-
+    setCurrentDatafileItem(m_qmodel->topMostItem());
     if (currentDatafileItem())
         m_data_frames->setStackedItem(currentDatafileItem()->dataItem());
 }
 
-QModelIndex DatafilesSelector::currentDatafileIndex() const
-{
-    if (!m_qview->selectionModel()->isSelected(m_qview->selectionModel()->currentIndex()))
-        return {};
-    return m_qview->selectionModel()->currentIndex();
-}
-
 QList<QAction*> DatafilesSelector::getOverlayActions(const QModelIndex& index, bool asHover)
 {
-    if (m_qmodel->isHeadline(index)) {
-        if (asHover)
-            return {};
-        return (index == m_qmodel->indexOfHeadline(1)) ? QList<QAction*>({m_import1dData_action})
-                                                       : QList<QAction*>({m_import2dData_action});
-    }
+    if (m_qmodel->isHeadline(index))
+        return {};
 
     // -- index belongs to item
     if (!asHover)
         return {};
 
-    auto* item = m_qmodel->itemForIndex(index);
+    const DatafileItem* item = m_qmodel->itemForIndex(index);
     if (item == nullptr)
         return {};
 
@@ -220,7 +213,8 @@ QList<QAction*> DatafilesSelector::getOverlayActions(const QModelIndex& index, b
     removeAction->setIconText("Remove");
     removeAction->setToolTip("Remove this data");
     connect(removeAction, &QAction::triggered, [this, item] {
-        m_qmodel->removeDatafileItem(item);
+        int row = m_qmodel->indexForItem(item).row();
+        m_qmodel->removeDatafileItemAt(row);
         gDoc->setModified();
     });
 
@@ -232,7 +226,6 @@ void DatafilesSelector::onSelectionChanged()
     updateActionEnabling();
 
     gDoc->datafilesModifier()->setCurrentIndex(currentDatafileIndex().row());
-    gDoc->datafilesModifier()->setSelectedRank(currentDatafileIndex().parent().row() + 1);
 
     DatafileItem* dfi = currentDatafileItem();
     m_editor->setDatafileItem(dfi);
@@ -241,7 +234,7 @@ void DatafilesSelector::onSelectionChanged()
 
 void DatafilesSelector::onContextMenuRequest(const QPoint& point)
 {
-    auto* dfile_item = m_qmodel->itemForIndex(m_qview->indexAt(point));
+    DatafileItem* dfile_item = m_qmodel->itemForIndex(m_qview->indexAt(point));
     updateActionEnabling(dfile_item);
 
     QMenu menu;
@@ -381,7 +374,7 @@ void DatafilesSelector::renameCurrentItem()
 
 void DatafilesSelector::removeCurrentItem()
 {
-    m_qmodel->removeDatafileItem(currentDatafileItem());
+    m_qmodel->removeDatafileItemAt(currentDatafileIndex().row());
     gDoc->setModified();
 }
 
diff --git a/GUI/View/Data/DatafilesSelector.h b/GUI/View/Data/DatafilesSelector.h
index a599a150f0f1b0760fb356fba03376368cee6043..09ffe7578d5d6438ba2d829e3fd37c1bbf87ba48 100644
--- a/GUI/View/Data/DatafilesSelector.h
+++ b/GUI/View/Data/DatafilesSelector.h
@@ -42,7 +42,7 @@ public:
     DatafileItem* currentDatafileItem();
 
 private:
-    void setCurrentDatafileItem(DatafileItem* item);
+    void setCurrentDatafileItem(const DatafileItem* item);
     void restoreSelection();
     void onSelectionChanged();
     void renameCurrentItem();
diff --git a/GUI/View/Instrument/AlphaScanEditor.cpp b/GUI/View/Device/AlphaScanEditor.cpp
similarity index 93%
rename from GUI/View/Instrument/AlphaScanEditor.cpp
rename to GUI/View/Device/AlphaScanEditor.cpp
index 9cee01eb386eee93755a063dc0b95962b157ee06..f3f472c57a4b4f71a0ae41fd0d656ec3c8db53ad 100644
--- a/GUI/View/Instrument/AlphaScanEditor.cpp
+++ b/GUI/View/Device/AlphaScanEditor.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/AlphaScanEditor.cpp
+//! @file      GUI/View/Device/AlphaScanEditor.cpp
 //! @brief     Defines class AlphaScanEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,12 +12,12 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/AlphaScanEditor.h"
+#include "GUI/View/Device/AlphaScanEditor.h"
 #include "GUI/Model/Beam/GrazingScanItem.h"
 #include "GUI/Model/Descriptor/DistributionItems.h"
+#include "GUI/View/Device/DistributionPlot.h"
+#include "GUI/View/Device/DistributionSelector.h"
 #include "GUI/View/Device/SphericalAxisForm.h"
-#include "GUI/View/Instrument/DistributionPlot.h"
-#include "GUI/View/Instrument/DistributionSelector.h"
 
 AlphaScanEditor::AlphaScanEditor(QWidget* parent, GrazingScanItem* item, bool allow_distr)
     : StaticGroupBox("Grazing angles (deg)", parent)
diff --git a/GUI/View/Instrument/AlphaScanEditor.h b/GUI/View/Device/AlphaScanEditor.h
similarity index 84%
rename from GUI/View/Instrument/AlphaScanEditor.h
rename to GUI/View/Device/AlphaScanEditor.h
index 4d1980a0f05d6e702bb448961bad3206c807ffe3..9bca3ff237d9a158a1b06fdf9e24063143ebf566 100644
--- a/GUI/View/Instrument/AlphaScanEditor.h
+++ b/GUI/View/Device/AlphaScanEditor.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/AlphaScanEditor.h
+//! @file      GUI/View/Device/AlphaScanEditor.h
 //! @brief     Defines class AlphaScanEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_ALPHASCANEDITOR_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_ALPHASCANEDITOR_H
+#ifndef BORNAGAIN_GUI_VIEW_DEVICE_ALPHASCANEDITOR_H
+#define BORNAGAIN_GUI_VIEW_DEVICE_ALPHASCANEDITOR_H
 
 #include "GUI/View/Widget/GroupBoxes.h"
 
@@ -45,4 +45,4 @@ private:
     DistributionPlot* m_plot;
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_ALPHASCANEDITOR_H
+#endif // BORNAGAIN_GUI_VIEW_DEVICE_ALPHASCANEDITOR_H
diff --git a/GUI/View/Instrument/DetectorEditor.cpp b/GUI/View/Device/DetectorEditor.cpp
similarity index 96%
rename from GUI/View/Instrument/DetectorEditor.cpp
rename to GUI/View/Device/DetectorEditor.cpp
index 96bfad71429013007d701714907ab159aa142c94..4579dbcac9cdf559af9b299533555757fc4668f5 100644
--- a/GUI/View/Instrument/DetectorEditor.cpp
+++ b/GUI/View/Device/DetectorEditor.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/DetectorEditor.cpp
+//! @file      GUI/View/Device/DetectorEditor.cpp
 //! @brief     Implements class DetectorEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/DetectorEditor.h"
+#include "GUI/View/Device/DetectorEditor.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Detector/DetectorItem.h"
 #include "GUI/Model/Detector/ResolutionFunctionItems.h"
diff --git a/GUI/View/Instrument/DetectorEditor.h b/GUI/View/Device/DetectorEditor.h
similarity index 79%
rename from GUI/View/Instrument/DetectorEditor.h
rename to GUI/View/Device/DetectorEditor.h
index da2e4b8c8266383c51f1e56ef2acc372144a6d90..8b1bbeb8b3ff6fc016553e43c82fa6df3dd05fef 100644
--- a/GUI/View/Instrument/DetectorEditor.h
+++ b/GUI/View/Device/DetectorEditor.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/DetectorEditor.h
+//! @file      GUI/View/Device/DetectorEditor.h
 //! @brief     Defines class DetectorEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_DETECTOREDITOR_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_DETECTOREDITOR_H
+#ifndef BORNAGAIN_GUI_VIEW_DEVICE_DETECTOREDITOR_H
+#define BORNAGAIN_GUI_VIEW_DEVICE_DETECTOREDITOR_H
 
 #include "GUI/View/Widget/GroupBoxes.h"
 
@@ -30,4 +30,4 @@ signals:
     void dataChanged();
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_DETECTOREDITOR_H
+#endif // BORNAGAIN_GUI_VIEW_DEVICE_DETECTOREDITOR_H
diff --git a/GUI/View/Instrument/DistributionEditor.cpp b/GUI/View/Device/DistributionEditor.cpp
similarity index 92%
rename from GUI/View/Instrument/DistributionEditor.cpp
rename to GUI/View/Device/DistributionEditor.cpp
index f9f361a5db633e3ba51785e93fa5bda81afb70ed..bb2b23ac7b625d5ad0f3cac4f7104f550efc4436 100644
--- a/GUI/View/Instrument/DistributionEditor.cpp
+++ b/GUI/View/Device/DistributionEditor.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/DistributionEditor.cpp
+//! @file      GUI/View/Device/DistributionEditor.cpp
 //! @brief     Implements class DistributionEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,10 +12,10 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/DistributionEditor.h"
+#include "GUI/View/Device/DistributionEditor.h"
 #include "GUI/Model/Beam/BeamDistributionItem.h"
 #include "GUI/Model/Descriptor/DistributionItems.h"
-#include "GUI/View/Instrument/DistributionPlot.h"
+#include "GUI/View/Device/DistributionPlot.h"
 
 DistributionEditor::DistributionEditor(const QString& title,
                                        const std::optional<MeanConfig>& mean_config,
diff --git a/GUI/View/Instrument/DistributionEditor.h b/GUI/View/Device/DistributionEditor.h
similarity index 81%
rename from GUI/View/Instrument/DistributionEditor.h
rename to GUI/View/Device/DistributionEditor.h
index 3083023ace62774a4d33108ab223dde80a555211..f01e628ce01d084560a1471579f4f871ae904619 100644
--- a/GUI/View/Instrument/DistributionEditor.h
+++ b/GUI/View/Device/DistributionEditor.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/DistributionEditor.h
+//! @file      GUI/View/Device/DistributionEditor.h
 //! @brief     Defines class DistributionEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,11 +12,11 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONEDITOR_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONEDITOR_H
+#ifndef BORNAGAIN_GUI_VIEW_DEVICE_DISTRIBUTIONEDITOR_H
+#define BORNAGAIN_GUI_VIEW_DEVICE_DISTRIBUTIONEDITOR_H
 
 #include "GUI/Support/Data/ID.h"
-#include "GUI/View/Instrument/DistributionSelector.h" // MeanConfig
+#include "GUI/View/Device/DistributionSelector.h" // MeanConfig
 #include "GUI/View/Widget/GroupBoxes.h"
 #include <optional>
 
@@ -46,4 +46,4 @@ private:
     DistributionPlot* m_plot;
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONEDITOR_H
+#endif // BORNAGAIN_GUI_VIEW_DEVICE_DISTRIBUTIONEDITOR_H
diff --git a/GUI/View/Instrument/DistributionPlot.cpp b/GUI/View/Device/DistributionPlot.cpp
similarity index 98%
rename from GUI/View/Instrument/DistributionPlot.cpp
rename to GUI/View/Device/DistributionPlot.cpp
index 3dc50930f8e4eb1985f69bb6f6819c53a4d2a78f..3fb88903eae00bfc2b765848cb05fe1e12417896 100644
--- a/GUI/View/Instrument/DistributionPlot.cpp
+++ b/GUI/View/Device/DistributionPlot.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/DistributionPlot.cpp
+//! @file      GUI/View/Device/DistributionPlot.cpp
 //! @brief     Implements class DistributionPlot.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/DistributionPlot.h"
+#include "GUI/View/Device/DistributionPlot.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Descriptor/DistributionItems.h"
 #include "GUI/View/Info/CautionSign.h"
diff --git a/GUI/View/Instrument/DistributionPlot.h b/GUI/View/Device/DistributionPlot.h
similarity index 88%
rename from GUI/View/Instrument/DistributionPlot.h
rename to GUI/View/Device/DistributionPlot.h
index 50bb8e1006aa6c97c7580966b3d42c3cb914fccc..a315ff38f3ac543d1efb2946bbb3a41c9eb0cc09 100644
--- a/GUI/View/Instrument/DistributionPlot.h
+++ b/GUI/View/Device/DistributionPlot.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/DistributionPlot.h
+//! @file      GUI/View/Device/DistributionPlot.h
 //! @brief     Defines class DistributionPlot.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONPLOT_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONPLOT_H
+#ifndef BORNAGAIN_GUI_VIEW_DEVICE_DISTRIBUTIONPLOT_H
+#define BORNAGAIN_GUI_VIEW_DEVICE_DISTRIBUTIONPLOT_H
 
 #include <QAction>
 #include <QLabel>
@@ -60,4 +60,4 @@ private:
     CautionSign* m_caution_sign;
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONPLOT_H
+#endif // BORNAGAIN_GUI_VIEW_DEVICE_DISTRIBUTIONPLOT_H
diff --git a/GUI/View/Instrument/DistributionSelector.cpp b/GUI/View/Device/DistributionSelector.cpp
similarity index 97%
rename from GUI/View/Instrument/DistributionSelector.cpp
rename to GUI/View/Device/DistributionSelector.cpp
index 090562fd317752c5817c75fa2a764013f202a770..9dc2c8ddf45062ddc3a983cc6965247668a25982 100644
--- a/GUI/View/Instrument/DistributionSelector.cpp
+++ b/GUI/View/Device/DistributionSelector.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/DistributionSelector.cpp
+//! @file      GUI/View/Device/DistributionSelector.cpp
 //! @brief     Implements class DistributionSelector.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,11 +12,11 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/DistributionSelector.h"
+#include "GUI/View/Device/DistributionSelector.h"
 #include "GUI/Model/Beam/BeamDistributionItem.h"
 #include "GUI/Model/Descriptor/DistributionItems.h"
 #include "GUI/Support/XML/Backup.h"
-#include "GUI/View/Instrument/DistributionPlot.h"
+#include "GUI/View/Device/DistributionPlot.h"
 #include "GUI/View/Numeric/ComboUtil.h"
 #include "GUI/View/Numeric/DoubleSpinBox.h"
 #include "GUI/View/Numeric/NumWidgetUtil.h"
diff --git a/GUI/View/Instrument/DistributionSelector.h b/GUI/View/Device/DistributionSelector.h
similarity index 91%
rename from GUI/View/Instrument/DistributionSelector.h
rename to GUI/View/Device/DistributionSelector.h
index fda3f222ba4623d078cecf935a4e0bc8b98ec311..6a61fbfc3fce8bc03313eb653b4dfc8eb780fa28 100644
--- a/GUI/View/Instrument/DistributionSelector.h
+++ b/GUI/View/Device/DistributionSelector.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/DistributionSelector.h
+//! @file      GUI/View/Device/DistributionSelector.h
 //! @brief     Defines struct MeanConfig and class DistributionSelector.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONSELECTOR_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONSELECTOR_H
+#ifndef BORNAGAIN_GUI_VIEW_DEVICE_DISTRIBUTIONSELECTOR_H
+#define BORNAGAIN_GUI_VIEW_DEVICE_DISTRIBUTIONSELECTOR_H
 
 #include "GUI/Support/Data/ID.h"
 #include <QComboBox>
@@ -67,4 +67,4 @@ private:
     QComboBox* m_distribution_combo;
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONSELECTOR_H
+#endif // BORNAGAIN_GUI_VIEW_DEVICE_DISTRIBUTIONSELECTOR_H
diff --git a/GUI/View/Instrument/GISASBeamEditor.cpp b/GUI/View/Device/GISASBeamEditor.cpp
similarity index 94%
rename from GUI/View/Instrument/GISASBeamEditor.cpp
rename to GUI/View/Device/GISASBeamEditor.cpp
index ae68c38d825c3149e7bc1d5aebed148113393b63..97df4aa6aebfe1baff0e255b47228a67540034af 100644
--- a/GUI/View/Instrument/GISASBeamEditor.cpp
+++ b/GUI/View/Device/GISASBeamEditor.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/GISASBeamEditor.cpp
+//! @file      GUI/View/Device/GISASBeamEditor.cpp
 //! @brief     Implements class GISASBeamEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,13 +12,13 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/GISASBeamEditor.h"
+#include "GUI/View/Device/GISASBeamEditor.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Beam/BeamAngleItems.h"
 #include "GUI/Model/Beam/BeamWavelengthItem.h"
 #include "GUI/Model/Beam/SourceItems.h"
+#include "GUI/View/Device/DistributionEditor.h"
 #include "GUI/View/Device/FootprintForm.h"
-#include "GUI/View/Instrument/DistributionEditor.h"
 #include "GUI/View/Numeric/DoubleSpinBox.h"
 #include <QFormLayout>
 #include <QLineEdit>
diff --git a/GUI/View/Instrument/GISASBeamEditor.h b/GUI/View/Device/GISASBeamEditor.h
similarity index 79%
rename from GUI/View/Instrument/GISASBeamEditor.h
rename to GUI/View/Device/GISASBeamEditor.h
index 133d13c9ca15ecf598bbc7570c645241ec924017..9badf25b1fccdeea5eb6f426ac329884f5dbd22d 100644
--- a/GUI/View/Instrument/GISASBeamEditor.h
+++ b/GUI/View/Device/GISASBeamEditor.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/GISASBeamEditor.h
+//! @file      GUI/View/Device/GISASBeamEditor.h
 //! @brief     Defines class GISASBeamEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_GISASBEAMEDITOR_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_GISASBEAMEDITOR_H
+#ifndef BORNAGAIN_GUI_VIEW_DEVICE_GISASBEAMEDITOR_H
+#define BORNAGAIN_GUI_VIEW_DEVICE_GISASBEAMEDITOR_H
 
 #include "GUI/View/Widget/GroupBoxes.h"
 
@@ -30,4 +30,4 @@ signals:
     void dataChanged();
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_GISASBEAMEDITOR_H
+#endif // BORNAGAIN_GUI_VIEW_DEVICE_GISASBEAMEDITOR_H
diff --git a/GUI/View/Instrument/OffspecDetectorEditor.cpp b/GUI/View/Device/OffspecDetectorEditor.cpp
similarity index 94%
rename from GUI/View/Instrument/OffspecDetectorEditor.cpp
rename to GUI/View/Device/OffspecDetectorEditor.cpp
index 4891469a8ec5a90a8b4e313c09a5226da8c5a62c..4164b8b660e0c530d52873763451ad9303684071 100644
--- a/GUI/View/Instrument/OffspecDetectorEditor.cpp
+++ b/GUI/View/Device/OffspecDetectorEditor.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/OffspecDetectorEditor.cpp
+//! @file      GUI/View/Device/OffspecDetectorEditor.cpp
 //! @brief     Implements class OffspecDetectorEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/OffspecDetectorEditor.h"
+#include "GUI/View/Device/OffspecDetectorEditor.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Detector/OffspecDetectorItem.h"
 #include "GUI/Model/Device/InstrumentItems.h"
diff --git a/GUI/View/Instrument/OffspecDetectorEditor.h b/GUI/View/Device/OffspecDetectorEditor.h
similarity index 79%
rename from GUI/View/Instrument/OffspecDetectorEditor.h
rename to GUI/View/Device/OffspecDetectorEditor.h
index 33a56a5de7fb711fcb7cc574a0f73e56b8f77001..695a94e835ca6b1c2d4907210aab6e8cc3bcdf02 100644
--- a/GUI/View/Instrument/OffspecDetectorEditor.h
+++ b/GUI/View/Device/OffspecDetectorEditor.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/OffspecDetectorEditor.h
+//! @file      GUI/View/Device/OffspecDetectorEditor.h
 //! @brief     Defines class OffspecDetectorEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_OFFSPECDETECTOREDITOR_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_OFFSPECDETECTOREDITOR_H
+#ifndef BORNAGAIN_GUI_VIEW_DEVICE_OFFSPECDETECTOREDITOR_H
+#define BORNAGAIN_GUI_VIEW_DEVICE_OFFSPECDETECTOREDITOR_H
 
 #include "GUI/View/Widget/GroupBoxes.h"
 #include <QFormLayout>
@@ -33,4 +33,4 @@ private:
     QFormLayout* m_form_layout;
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_OFFSPECDETECTOREDITOR_H
+#endif // BORNAGAIN_GUI_VIEW_DEVICE_OFFSPECDETECTOREDITOR_H
diff --git a/GUI/View/Instrument/PolarizationAnalysisEditor.cpp b/GUI/View/Device/PolarizationAnalysisEditor.cpp
similarity index 96%
rename from GUI/View/Instrument/PolarizationAnalysisEditor.cpp
rename to GUI/View/Device/PolarizationAnalysisEditor.cpp
index a72499cde696c27be2648f0f13051a1e0c0a3f61..2eeb5c3f4cebce54eb1c119b8e6a9934b4803756 100644
--- a/GUI/View/Instrument/PolarizationAnalysisEditor.cpp
+++ b/GUI/View/Device/PolarizationAnalysisEditor.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/PolarizationAnalysisEditor.cpp
+//! @file      GUI/View/Device/PolarizationAnalysisEditor.cpp
 //! @brief     Implements class PolarizationAnalysisEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/PolarizationAnalysisEditor.h"
+#include "GUI/View/Device/PolarizationAnalysisEditor.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Device/InstrumentItems.h"
 #include "GUI/View/Numeric/DoubleSpinBox.h"
diff --git a/GUI/View/Instrument/PolarizationAnalysisEditor.h b/GUI/View/Device/PolarizationAnalysisEditor.h
similarity index 82%
rename from GUI/View/Instrument/PolarizationAnalysisEditor.h
rename to GUI/View/Device/PolarizationAnalysisEditor.h
index 944cf1439919967e8d807b7ed9f0fa1fab4b5d68..8d1023b49c12035d88179c243922fc85778ab773 100644
--- a/GUI/View/Instrument/PolarizationAnalysisEditor.h
+++ b/GUI/View/Device/PolarizationAnalysisEditor.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/PolarizationAnalysisEditor.h
+//! @file      GUI/View/Device/PolarizationAnalysisEditor.h
 //! @brief     Defines class PolarizationAnalysisEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_POLARIZATIONANALYSISEDITOR_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_POLARIZATIONANALYSISEDITOR_H
+#ifndef BORNAGAIN_GUI_VIEW_DEVICE_POLARIZATIONANALYSISEDITOR_H
+#define BORNAGAIN_GUI_VIEW_DEVICE_POLARIZATIONANALYSISEDITOR_H
 
 #include "GUI/View/Widget/GroupBoxes.h"
 #include <QFormLayout>
@@ -41,4 +41,4 @@ private:
     InstrumentItem* m_instrument;
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_POLARIZATIONANALYSISEDITOR_H
+#endif // BORNAGAIN_GUI_VIEW_DEVICE_POLARIZATIONANALYSISEDITOR_H
diff --git a/GUI/View/Instrument/ScanEditor.cpp b/GUI/View/Device/ScanEditor.cpp
similarity index 94%
rename from GUI/View/Instrument/ScanEditor.cpp
rename to GUI/View/Device/ScanEditor.cpp
index 700af365ab92753991fcff32492717902f0217cc..f4cdda6c43a10520a3d64e546f858c6ed118dbb6 100644
--- a/GUI/View/Instrument/ScanEditor.cpp
+++ b/GUI/View/Device/ScanEditor.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/ScanEditor.cpp
+//! @file      GUI/View/Device/ScanEditor.cpp
 //! @brief     Defines class ScanEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/ScanEditor.h"
+#include "GUI/View/Device/ScanEditor.h"
 #include "Base/Axis/Frame.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Axis/PointwiseAxisItem.h"
@@ -21,9 +21,9 @@
 #include "GUI/Model/Device/InstrumentItems.h"
 #include "GUI/Model/Device/InstrumentsSet.h"
 #include "GUI/Model/Project/ProjectDocument.h"
+#include "GUI/View/Device/AlphaScanEditor.h"
+#include "GUI/View/Device/DistributionEditor.h"
 #include "GUI/View/Device/FootprintForm.h"
-#include "GUI/View/Instrument/AlphaScanEditor.h"
-#include "GUI/View/Instrument/DistributionEditor.h"
 #include "GUI/View/Numeric/DoubleSpinBox.h"
 #include <QFormLayout>
 #include <QLineEdit>
diff --git a/GUI/View/Instrument/ScanEditor.h b/GUI/View/Device/ScanEditor.h
similarity index 81%
rename from GUI/View/Instrument/ScanEditor.h
rename to GUI/View/Device/ScanEditor.h
index 102d169b642351e7bd7e10e2cdf9fc045deae4ef..5e71b5c72ce011766cf791245e45dc66baa6be7f 100644
--- a/GUI/View/Instrument/ScanEditor.h
+++ b/GUI/View/Device/ScanEditor.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/ScanEditor.h
+//! @file      GUI/View/Device/ScanEditor.h
 //! @brief     Defines class ScanEditor.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_SCANEDITOR_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_SCANEDITOR_H
+#ifndef BORNAGAIN_GUI_VIEW_DEVICE_SCANEDITOR_H
+#define BORNAGAIN_GUI_VIEW_DEVICE_SCANEDITOR_H
 
 #include "GUI/View/Widget/GroupBoxes.h"
 
@@ -32,4 +32,4 @@ signals:
     void dataChanged();
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_SCANEDITOR_H
+#endif // BORNAGAIN_GUI_VIEW_DEVICE_SCANEDITOR_H
diff --git a/GUI/View/FitControl/MinimizerEditor.cpp b/GUI/View/FitControl/MinimizerEditor.cpp
index 057b7d2fa2d36845fa71898757d51a17e00c5c12..ac263aeaadb956832e5a2de8f0a4a3b8839e1d93 100644
--- a/GUI/View/FitControl/MinimizerEditor.cpp
+++ b/GUI/View/FitControl/MinimizerEditor.cpp
@@ -18,9 +18,9 @@
 #include "GUI/Model/Job/JobItem.h"
 #include "GUI/Model/Mini/MinimizerItems.h"
 #include "GUI/Model/Project/ProjectDocument.h"
+#include "GUI/View/Layout/LayoutUtil.h"
 #include "GUI/View/Numeric/ComboUtil.h"
 #include "GUI/View/Numeric/NumWidgetUtil.h"
-#include "GUI/View/Tool/LayoutUtil.h"
 #include <QSpinBox>
 #include <QStandardItemModel>
 
diff --git a/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp b/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp
index 2eba3dc9b0af355ccd0a4d3602c79861dca34da5..c179d52ed5a3f177158f269807aa7d6c80dd315e 100644
--- a/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp
+++ b/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp
@@ -16,7 +16,7 @@
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Device/InstrumentItems.h"
 #include "GUI/View/Device/AxisPropertyForm.h"
-#include "GUI/View/Instrument/ScanEditor.h"
+#include "GUI/View/Device/ScanEditor.h"
 #include <QVBoxLayout>
 
 DepthprobeInstrumentEditor::DepthprobeInstrumentEditor(DepthprobeInstrumentItem* instrument)
diff --git a/GUI/View/Instrument/GISASInstrumentEditor.cpp b/GUI/View/Instrument/GISASInstrumentEditor.cpp
index 87ab326c10df4ba0451d08844f083f77db0132d7..3ea79b2f8d5d0d9376c350c18b9fc2395a39d6e6 100644
--- a/GUI/View/Instrument/GISASInstrumentEditor.cpp
+++ b/GUI/View/Instrument/GISASInstrumentEditor.cpp
@@ -16,9 +16,9 @@
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Device/InstrumentItems.h"
 #include "GUI/View/Device/BackgroundForm.h"
-#include "GUI/View/Instrument/DetectorEditor.h"
-#include "GUI/View/Instrument/GISASBeamEditor.h"
-#include "GUI/View/Instrument/PolarizationAnalysisEditor.h"
+#include "GUI/View/Device/DetectorEditor.h"
+#include "GUI/View/Device/GISASBeamEditor.h"
+#include "GUI/View/Device/PolarizationAnalysisEditor.h"
 
 GISASInstrumentEditor::GISASInstrumentEditor(GISASInstrumentItem* instrument)
 {
diff --git a/GUI/View/Instrument/OffspecInstrumentEditor.cpp b/GUI/View/Instrument/OffspecInstrumentEditor.cpp
index b884fc75737b5cd39d771f3e0f212e9c1ebdb671..eb9772cb32a969409cbd52639cc70e3602cdfa6a 100644
--- a/GUI/View/Instrument/OffspecInstrumentEditor.cpp
+++ b/GUI/View/Instrument/OffspecInstrumentEditor.cpp
@@ -15,9 +15,9 @@
 #include "GUI/View/Instrument/OffspecInstrumentEditor.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Device/InstrumentItems.h"
-#include "GUI/View/Instrument/OffspecDetectorEditor.h"
-#include "GUI/View/Instrument/PolarizationAnalysisEditor.h"
-#include "GUI/View/Instrument/ScanEditor.h"
+#include "GUI/View/Device/OffspecDetectorEditor.h"
+#include "GUI/View/Device/PolarizationAnalysisEditor.h"
+#include "GUI/View/Device/ScanEditor.h"
 
 OffspecInstrumentEditor::OffspecInstrumentEditor(OffspecInstrumentItem* instrument)
 {
diff --git a/GUI/View/Instrument/SpecularInstrumentEditor.cpp b/GUI/View/Instrument/SpecularInstrumentEditor.cpp
index 4e77a8fd7bfef7383b19f323083613c40c53dc3a..dbab910e1ecf4d330acbc588749eea58fe9b8764 100644
--- a/GUI/View/Instrument/SpecularInstrumentEditor.cpp
+++ b/GUI/View/Instrument/SpecularInstrumentEditor.cpp
@@ -16,8 +16,8 @@
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Device/InstrumentItems.h"
 #include "GUI/View/Device/BackgroundForm.h"
-#include "GUI/View/Instrument/PolarizationAnalysisEditor.h"
-#include "GUI/View/Instrument/ScanEditor.h"
+#include "GUI/View/Device/PolarizationAnalysisEditor.h"
+#include "GUI/View/Device/ScanEditor.h"
 
 SpecularInstrumentEditor::SpecularInstrumentEditor(SpecularInstrumentItem* instrument)
 {
diff --git a/GUI/View/Tool/LayoutUtil.cpp b/GUI/View/Layout/LayoutUtil.cpp
similarity index 92%
rename from GUI/View/Tool/LayoutUtil.cpp
rename to GUI/View/Layout/LayoutUtil.cpp
index c99a918671a72d98a6cf865b9f45c197fd1cc734..77dbc769331827a3056a0f554d3d5fbb65176129 100644
--- a/GUI/View/Tool/LayoutUtil.cpp
+++ b/GUI/View/Layout/LayoutUtil.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Tool/LayoutUtil.cpp
+//! @file      GUI/View/Layout/LayoutUtil.cpp
 //! @brief     Implements namespace LayoutUtils.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Tool/LayoutUtil.h"
+#include "GUI/View/Layout/LayoutUtil.h"
 #include <QLayoutItem>
 #include <QWidget>
 
diff --git a/GUI/View/Tool/LayoutUtil.h b/GUI/View/Layout/LayoutUtil.h
similarity index 80%
rename from GUI/View/Tool/LayoutUtil.h
rename to GUI/View/Layout/LayoutUtil.h
index 2e1d6ab46a4ca79b6f5d7a0b927e510505f278e1..c3f7788aadf253d9c1a72660bf7935fe78e0a724 100644
--- a/GUI/View/Tool/LayoutUtil.h
+++ b/GUI/View/Layout/LayoutUtil.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Tool/LayoutUtil.h
+//! @file      GUI/View/Layout/LayoutUtil.h
 //! @brief     Defines namespace GUI::Util::Layout.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_TOOL_LAYOUTUTIL_H
-#define BORNAGAIN_GUI_VIEW_TOOL_LAYOUTUTIL_H
+#ifndef BORNAGAIN_GUI_VIEW_LAYOUT_LAYOUTUTIL_H
+#define BORNAGAIN_GUI_VIEW_LAYOUT_LAYOUTUTIL_H
 
 #include <QLayout>
 
@@ -24,4 +24,4 @@ void clearLayout(QLayout* layout, bool deleteWidgets = true);
 
 } // namespace GUI::Util::Layout
 
-#endif // BORNAGAIN_GUI_VIEW_TOOL_LAYOUTUTIL_H
+#endif // BORNAGAIN_GUI_VIEW_LAYOUT_LAYOUTUTIL_H
diff --git a/GUI/View/Instrument/InstrumentsQListModel.cpp b/GUI/View/List/InstrumentsQListModel.cpp
similarity index 95%
rename from GUI/View/Instrument/InstrumentsQListModel.cpp
rename to GUI/View/List/InstrumentsQListModel.cpp
index aa2818bc57e8abc7aebaf00771608367752827c3..88ad12c6abd9467a88c181879c6a22d8b7f27897 100644
--- a/GUI/View/Instrument/InstrumentsQListModel.cpp
+++ b/GUI/View/List/InstrumentsQListModel.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/InstrumentsQListModel.cpp
+//! @file      GUI/View/List/InstrumentsQListModel.cpp
 //! @brief     Implements class InstrumentsQListModel.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/InstrumentsQListModel.h"
+#include "GUI/View/List/InstrumentsQListModel.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Device/InstrumentItems.h"
 #include "GUI/Model/Device/InstrumentsSet.h"
@@ -126,7 +126,7 @@ QModelIndex InstrumentsQListModel::copyInstrument(const InstrumentItem* source)
     const QString copyName = instruments->suggestInstrumentName(source->instrumentName());
     const int row = instruments->instrumentItems().size();
 
-    beginInsertRows(QModelIndex(), row, row);
+    beginInsertRows({}, row, row);
     InstrumentItem* copy = instruments->insertItemCopy(*source);
     copy->setInstrumentName(copyName);
     emit instruments->instrumentAddedOrRemoved();
@@ -141,7 +141,7 @@ template <class Instrument> QModelIndex InstrumentsQListModel::addNewInstrument(
     const QString name = instruments->suggestInstrumentName(defaultInstrumentName<Instrument>());
     const int row = instruments->instrumentItems().size();
 
-    beginInsertRows(QModelIndex(), row, row);
+    beginInsertRows({}, row, row);
     auto* instrument = instruments->addInstrumentItem<Instrument>();
     instruments->setInstrumentName(instrument, name);
     endInsertRows();
diff --git a/GUI/View/Instrument/InstrumentsQListModel.h b/GUI/View/List/InstrumentsQListModel.h
similarity index 86%
rename from GUI/View/Instrument/InstrumentsQListModel.h
rename to GUI/View/List/InstrumentsQListModel.h
index ec6c3162743305f8f3d4f73c1cafe96adb4d4db1..8b63f264942789595d681647b0b16553fae65ec9 100644
--- a/GUI/View/Instrument/InstrumentsQListModel.h
+++ b/GUI/View/List/InstrumentsQListModel.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/InstrumentsQListModel.h
+//! @file      GUI/View/List/InstrumentsQListModel.h
 //! @brief     Defines class InstrumentsQListModel.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_INSTRUMENTSQLISTMODEL_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_INSTRUMENTSQLISTMODEL_H
+#ifndef BORNAGAIN_GUI_VIEW_LIST_INSTRUMENTSQLISTMODEL_H
+#define BORNAGAIN_GUI_VIEW_LIST_INSTRUMENTSQLISTMODEL_H
 
 #include <QAbstractListModel>
 
@@ -47,4 +47,4 @@ private:
     void onInstrumentNameChanged(const InstrumentItem* instrument);
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_INSTRUMENTSQLISTMODEL_H
+#endif // BORNAGAIN_GUI_VIEW_LIST_INSTRUMENTSQLISTMODEL_H
diff --git a/GUI/View/Instrument/InstrumentsQListView.cpp b/GUI/View/List/InstrumentsQListView.cpp
similarity index 95%
rename from GUI/View/Instrument/InstrumentsQListView.cpp
rename to GUI/View/List/InstrumentsQListView.cpp
index dcc040afe36b280f462d6b4faff0f2c98b0d3ac2..bd168035dd27c6696d41a10ca5faca587fbb1c72 100644
--- a/GUI/View/Instrument/InstrumentsQListView.cpp
+++ b/GUI/View/List/InstrumentsQListView.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/InstrumentsQListView.cpp
+//! @file      GUI/View/List/InstrumentsQListView.cpp
 //! @brief     Implements class InstrumentsQListView.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,17 +12,18 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Instrument/InstrumentsQListView.h"
+#include "GUI/View/List/InstrumentsQListView.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/Device/InstrumentItems.h"
 #include "GUI/Model/Device/InstrumentXML.h"
 #include "GUI/Model/Device/InstrumentsSet.h"
 #include "GUI/Model/Project/ProjectDocument.h"
-#include "GUI/View/Instrument/InstrumentsQListModel.h"
 #include "GUI/View/Layout/ApplicationSettings.h"
+#include "GUI/View/List/InstrumentsQListModel.h"
 #include "GUI/View/Setup/FrameActions.h"
-#include "GUI/View/Tool/Globals.h"
 #include "GUI/View/Widget/FileDialog.h"
+#include "GUI/View/Widget/ItemViewOverlayButtons.h"
+#include "GUI/View/Widget/ListItemDelegate.h"
 #include <QMessageBox>
 #include <QVBoxLayout>
 #include <iostream>
@@ -37,6 +38,7 @@ InstrumentsQListView::InstrumentsQListView()
     setSelectionMode(QAbstractItemView::SingleSelection);
 
     setModel(m_model);
+    setItemDelegate(new ListItemDelegate(this));
 
     connect(gActions->new_gisas_instrument, &QAction::triggered, this,
             &InstrumentsQListView::onNewGisas);
diff --git a/GUI/View/Instrument/InstrumentsQListView.h b/GUI/View/List/InstrumentsQListView.h
similarity index 85%
rename from GUI/View/Instrument/InstrumentsQListView.h
rename to GUI/View/List/InstrumentsQListView.h
index bfd4c86ee1a5e7113f332785a48273c3c76c8a52..4a3e5b75657d4c95686b034957505e4e922ee407 100644
--- a/GUI/View/Instrument/InstrumentsQListView.h
+++ b/GUI/View/List/InstrumentsQListView.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Instrument/InstrumentsQListView.h
+//! @file      GUI/View/List/InstrumentsQListView.h
 //! @brief     Defines class InstrumentsQListView.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_INSTRUMENTSQLISTVIEW_H
-#define BORNAGAIN_GUI_VIEW_INSTRUMENT_INSTRUMENTSQLISTVIEW_H
+#ifndef BORNAGAIN_GUI_VIEW_LIST_INSTRUMENTSQLISTVIEW_H
+#define BORNAGAIN_GUI_VIEW_LIST_INSTRUMENTSQLISTVIEW_H
 
 #include <QListView>
 
@@ -59,4 +59,4 @@ private:
     static QString m_xml_dir;
 };
 
-#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_INSTRUMENTSQLISTVIEW_H
+#endif // BORNAGAIN_GUI_VIEW_LIST_INSTRUMENTSQLISTVIEW_H
diff --git a/GUI/View/Sample/SamplesQListView.cpp b/GUI/View/List/SamplesQListView.cpp
similarity index 85%
rename from GUI/View/Sample/SamplesQListView.cpp
rename to GUI/View/List/SamplesQListView.cpp
index af9add0586d67d055fdcb9bba109d789d5856406..66b812e71d5fe6ca8f93f503c34611a9797ae8f5 100644
--- a/GUI/View/Sample/SamplesQListView.cpp
+++ b/GUI/View/List/SamplesQListView.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Sample/SamplesQListView.cpp
+//! @file      GUI/View/List/SamplesQListView.cpp
 //! @brief     Implements class SamplesQListView.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,57 +12,20 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Sample/SamplesQListView.h"
+#include "GUI/View/List/SamplesQListView.h"
 #include "Base/Util/SysUtil.h"
 #include "GUI/Model/FromCore/GUIExamplesFactory.h"
 #include "GUI/Model/Project/ProjectDocument.h"
 #include "GUI/Model/Sample/SampleItem.h"
 #include "GUI/Model/Sample/SamplesSet.h"
 #include "GUI/View/Layout/ApplicationSettings.h"
-#include "GUI/View/Sample/SamplesQModel.h"
-#include "GUI/View/Tool/ItemDelegateForHTML.h"
+#include "GUI/View/List/SamplesQModel.h"
 #include "GUI/View/Widget/ItemViewOverlayButtons.h"
+#include "GUI/View/Widget/ListItemDelegate.h"
 #include <QAction>
 #include <QMenu>
 #include <QPainter>
 
-namespace {
-
-class ItemDelegateForSampleTree : public ItemDelegateForHTML {
-public:
-    ItemDelegateForSampleTree(QObject* parent)
-        : ItemDelegateForHTML(parent)
-    {
-    }
-
-protected:
-    void paint(QPainter* painter, const QStyleOptionViewItem& option,
-               const QModelIndex& index) const override
-    {
-        ItemDelegateForHTML::paint(painter, option, index);
-
-        QStyleOptionViewItem options = option;
-        initStyleOption(&options, index);
-
-        painter->save();
-
-        painter->setPen(QPen(Qt::lightGray, 1));
-        painter->drawLine(options.rect.left(), options.rect.bottom(), options.rect.right(),
-                          options.rect.bottom());
-        painter->restore();
-    }
-
-    QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override
-    {
-        auto s = ItemDelegateForHTML::sizeHint(option, index);
-        s.setHeight(std::max(s.height(), 32));
-        return s;
-    }
-};
-
-} // namespace
-
-
 SamplesQListView::SamplesQListView()
     : m_model(new SamplesQModel)
     , m_new_sample_action(new QAction(this))
@@ -77,7 +40,7 @@ SamplesQListView::SamplesQListView()
 
     ItemViewOverlayButtons::install(
         this, [this](const QModelIndex& i, bool h) { return getOverlayActions(i, h); });
-    setItemDelegate(new ItemDelegateForSampleTree(this));
+    setItemDelegate(new ListItemDelegate(this));
 
     connect(selectionModel(), &QItemSelectionModel::currentChanged, this,
             &SamplesQListView::onCurrentChanged);
diff --git a/GUI/View/Sample/SamplesQListView.h b/GUI/View/List/SamplesQListView.h
similarity index 90%
rename from GUI/View/Sample/SamplesQListView.h
rename to GUI/View/List/SamplesQListView.h
index 9f1dcec76d2db79776d210f6a80e7b3186e41483..932caaca934caf183cff9bb1429c9590312b68ba 100644
--- a/GUI/View/Sample/SamplesQListView.h
+++ b/GUI/View/List/SamplesQListView.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Sample/SamplesQListView.h
+//! @file      GUI/View/List/SamplesQListView.h
 //! @brief     Defines class SamplesQListView.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_SAMPLE_SAMPLESQLISTVIEW_H
-#define BORNAGAIN_GUI_VIEW_SAMPLE_SAMPLESQLISTVIEW_H
+#ifndef BORNAGAIN_GUI_VIEW_LIST_SAMPLESQLISTVIEW_H
+#define BORNAGAIN_GUI_VIEW_LIST_SAMPLESQLISTVIEW_H
 
 #include <QListView>
 
@@ -64,4 +64,4 @@ private:
     QAction* m_choose_from_library_action;
 };
 
-#endif // BORNAGAIN_GUI_VIEW_SAMPLE_SAMPLESQLISTVIEW_H
+#endif // BORNAGAIN_GUI_VIEW_LIST_SAMPLESQLISTVIEW_H
diff --git a/GUI/View/Sample/SamplesQModel.cpp b/GUI/View/List/SamplesQModel.cpp
similarity index 98%
rename from GUI/View/Sample/SamplesQModel.cpp
rename to GUI/View/List/SamplesQModel.cpp
index b01f51471cabdc7952f63c75289c4ef359ee9b60..54b89e8703cc14506ee37eb68e231c5b21003aa4 100644
--- a/GUI/View/Sample/SamplesQModel.cpp
+++ b/GUI/View/List/SamplesQModel.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Sample/SamplesQModel.cpp
+//! @file      GUI/View/List/SamplesQModel.cpp
 //! @brief     Implements class SamplesQModel.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Sample/SamplesQModel.h"
+#include "GUI/View/List/SamplesQModel.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Model/FromCore/GUIExamplesFactory.h"
 #include "GUI/Model/FromCore/ItemizeSample.h"
diff --git a/GUI/View/Sample/SamplesQModel.h b/GUI/View/List/SamplesQModel.h
similarity index 91%
rename from GUI/View/Sample/SamplesQModel.h
rename to GUI/View/List/SamplesQModel.h
index 0e9116d7759e5d597069c69be83c752e85d5e4eb..9c89cb9867eaa37bc5fb90c5626f5de39850f6c3 100644
--- a/GUI/View/Sample/SamplesQModel.h
+++ b/GUI/View/List/SamplesQModel.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Sample/SamplesQModel.h
+//! @file      GUI/View/List/SamplesQModel.h
 //! @brief     Defines class SamplesQModel.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_SAMPLE_SAMPLESQMODEL_H
-#define BORNAGAIN_GUI_VIEW_SAMPLE_SAMPLESQMODEL_H
+#ifndef BORNAGAIN_GUI_VIEW_LIST_SAMPLESQMODEL_H
+#define BORNAGAIN_GUI_VIEW_LIST_SAMPLESQMODEL_H
 
 #include <QAbstractItemModel>
 
@@ -60,4 +60,4 @@ private:
     SamplesSet* m_sample_items = nullptr;
 };
 
-#endif // BORNAGAIN_GUI_VIEW_SAMPLE_SAMPLESQMODEL_H
+#endif // BORNAGAIN_GUI_VIEW_LIST_SAMPLESQMODEL_H
diff --git a/GUI/View/Sample/LayerForm.cpp b/GUI/View/Sample/LayerForm.cpp
index 0697d62d42e9a5c2bb741ab8efe5aea36d0337ad..05775784bd28862cf06db4e14128c7b1aa85997b 100644
--- a/GUI/View/Sample/LayerForm.cpp
+++ b/GUI/View/Sample/LayerForm.cpp
@@ -23,7 +23,7 @@
 #include "GUI/View/Sample/MaterialInplaceForm.h"
 #include "GUI/View/Sample/ParticleLayoutForm.h"
 #include "GUI/View/Tool/ActionFactory.h"
-#include "GUI/View/Tool/WidgetMoverButton.h"
+#include "GUI/View/Widget/WidgetMoverButton.h"
 #include <QLineEdit>
 #include <QMenu>
 #include <QPushButton>
diff --git a/GUI/View/Sample/MaterialInplaceForm.cpp b/GUI/View/Sample/MaterialInplaceForm.cpp
index fadd537b0fc06ef3509732108803cd91aefde9a8..2025a5b5b626e292f2a3422d0bf3ff3a3d6bc120 100644
--- a/GUI/View/Sample/MaterialInplaceForm.cpp
+++ b/GUI/View/Sample/MaterialInplaceForm.cpp
@@ -20,13 +20,12 @@
 #include "GUI/Model/Sample/LayerItem.h"
 #include "GUI/Model/Sample/SampleItem.h"
 #include "GUI/Support/XML/Backup.h"
+#include "GUI/View/Layout/LayoutUtil.h"
 #include "GUI/View/Material/MaterialEditorDialog.h"
 #include "GUI/View/Numeric/DoubleSpinBox.h"
 #include "GUI/View/Sample/LayerEditorUtil.h"
 #include "GUI/View/Sample/SampleEditorController.h"
 #include "GUI/View/Sample/SampleForm.h"
-#include "GUI/View/Tool/Globals.h"
-#include "GUI/View/Tool/LayoutUtil.h"
 #include <QLabel>
 #include <QPushButton>
 
diff --git a/GUI/View/Sample/SampleForm.cpp b/GUI/View/Sample/SampleForm.cpp
index 9a96268f335f42ad67c87302ce4e83fc858bf794..161096b982b379f6e5f8589c993a1cd94e0e3f88 100644
--- a/GUI/View/Sample/SampleForm.cpp
+++ b/GUI/View/Sample/SampleForm.cpp
@@ -15,6 +15,7 @@
 #include "GUI/View/Sample/SampleForm.h"
 #include "GUI/Model/Sample/SampleItem.h"
 #include "GUI/View/Layout/ApplicationSettings.h"
+#include "GUI/View/Layout/LayoutUtil.h"
 #include "GUI/View/Sample/CompoundForm.h"
 #include "GUI/View/Sample/CoreAndShellForm.h"
 #include "GUI/View/Sample/HeinzFormLayout.h"
@@ -24,7 +25,6 @@
 #include "GUI/View/Sample/ParticleLayoutForm.h"
 #include "GUI/View/Sample/SampleEditorController.h"
 #include "GUI/View/Tool/ActionFactory.h"
-#include "GUI/View/Tool/LayoutUtil.h"
 #include "GUI/View/Widget/GroupBoxes.h"
 #include <QBoxLayout>
 #include <QLabel>
diff --git a/GUI/View/Sample/SelectionContainerForm.cpp b/GUI/View/Sample/SelectionContainerForm.cpp
index 99cf3a2d386419639ca6957913fe6a3095f65df7..364cc977bd26faa372aa5514cf6c01062ab15956 100644
--- a/GUI/View/Sample/SelectionContainerForm.cpp
+++ b/GUI/View/Sample/SelectionContainerForm.cpp
@@ -17,7 +17,7 @@
 #include "GUI/Model/Sample/ProfileItems.h"
 #include "GUI/Model/Sample/RotationItems.h"
 #include "GUI/Model/Sample/RoughnessItems.h"
-#include "GUI/View/Tool/LayoutUtil.h"
+#include "GUI/View/Layout/LayoutUtil.h"
 
 ISelectionContainerForm::ISelectionContainerForm(QWidget* parent, SampleEditorController* ec)
     : QWidget(parent)
diff --git a/GUI/View/Scene/MaskGraphicsScene.h b/GUI/View/Scene/MaskGraphicsScene.h
index 433077756e7335c5e9dc23188de7c64cf78c5c7b..81e444b7779c458405b045cc7ae31cffbe0d677d 100644
--- a/GUI/View/Scene/MaskGraphicsScene.h
+++ b/GUI/View/Scene/MaskGraphicsScene.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_VIEW_SCENE_MASKGRAPHICSSCENE_H
 #define BORNAGAIN_GUI_VIEW_SCENE_MASKGRAPHICSSCENE_H
 
-#include "GUI/View/Tool/Canvas2DMode.h"
+#include "GUI/View/Setup/Canvas2DMode.h"
 #include <QGraphicsScene>
 #include <QItemSelection>
 #include <QItemSelectionModel>
diff --git a/GUI/View/Scene/MaskGraphicsView.h b/GUI/View/Scene/MaskGraphicsView.h
index 5d0cd1881e5e3699ae7ad955ecea61a04e756f65..438018e5f04d6562b147abb05249c6a72d3801fe 100644
--- a/GUI/View/Scene/MaskGraphicsView.h
+++ b/GUI/View/Scene/MaskGraphicsView.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_VIEW_SCENE_MASKGRAPHICSVIEW_H
 #define BORNAGAIN_GUI_VIEW_SCENE_MASKGRAPHICSVIEW_H
 
-#include "GUI/View/Tool/Canvas2DMode.h"
+#include "GUI/View/Setup/Canvas2DMode.h"
 #include <QGraphicsView>
 #include <QWheelEvent>
 
diff --git a/GUI/View/Setup/AxesPanel.cpp b/GUI/View/Setup/AxesPanel.cpp
index 1c546a67e63b0e562e2f89e37d96dff4b4605202..1e61c7e6e4f51277527c42856e6decee95505569 100644
--- a/GUI/View/Setup/AxesPanel.cpp
+++ b/GUI/View/Setup/AxesPanel.cpp
@@ -20,9 +20,9 @@
 #include "GUI/Model/Job/DataSource.h"
 #include "GUI/Model/Project/ProjectDocument.h"
 #include "GUI/Support/Data/ComboProperty.h"
+#include "GUI/View/Layout/LayoutUtil.h"
 #include "GUI/View/Numeric/ComboUtil.h"
 #include "GUI/View/Numeric/NumWidgetUtil.h"
-#include "GUI/View/Tool/LayoutUtil.h"
 #include "GUI/View/Widget/GroupBoxes.h"
 #include <QCheckBox>
 #include <QFormLayout>
diff --git a/GUI/View/Setup/AxisPanel.cpp b/GUI/View/Setup/AxisPanel.cpp
index ad504826d2efd4b2d767a4985ea7dd19bb7148ff..06d90a3eb9fd36d9837c17ab3187b3baa58ca3e2 100644
--- a/GUI/View/Setup/AxisPanel.cpp
+++ b/GUI/View/Setup/AxisPanel.cpp
@@ -24,9 +24,9 @@
 #include "GUI/Model/Job/DataSource.h"
 #include "GUI/Model/Project/ProjectDocument.h"
 #include "GUI/Support/Data/ComboProperty.h"
+#include "GUI/View/Layout/LayoutUtil.h"
 #include "GUI/View/Numeric/DoubleSpinBox.h"
 #include "GUI/View/Numeric/NumWidgetUtil.h"
-#include "GUI/View/Tool/LayoutUtil.h"
 #include "GUI/View/Widget/GroupBoxes.h"
 #include <QAction>
 #include <QCheckBox>
diff --git a/GUI/View/Tool/Canvas2DMode.h b/GUI/View/Setup/Canvas2DMode.h
similarity index 88%
rename from GUI/View/Tool/Canvas2DMode.h
rename to GUI/View/Setup/Canvas2DMode.h
index 9b25fdd64f7072f91ad2776af88f2f0d237cbbf2..135c2b63f3e3dc84e0982b8675718a6c311b23e9 100644
--- a/GUI/View/Tool/Canvas2DMode.h
+++ b/GUI/View/Setup/Canvas2DMode.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Tool/Canvas2DMode.h
+//! @file      GUI/View/Setup/Canvas2DMode.h
 //! @brief     Defines namespace Canvas2DMode.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_TOOL_CANVAS2DMODE_H
-#define BORNAGAIN_GUI_VIEW_TOOL_CANVAS2DMODE_H
+#ifndef BORNAGAIN_GUI_VIEW_SETUP_CANVAS2DMODE_H
+#define BORNAGAIN_GUI_VIEW_SETUP_CANVAS2DMODE_H
 
 //! Various flags for MaskEditor operation
 
@@ -66,4 +66,4 @@ inline bool isLineMode(Flag m)
 
 } // namespace Canvas2DMode
 
-#endif // BORNAGAIN_GUI_VIEW_TOOL_CANVAS2DMODE_H
+#endif // BORNAGAIN_GUI_VIEW_SETUP_CANVAS2DMODE_H
diff --git a/GUI/View/Setup/DataToolbar.h b/GUI/View/Setup/DataToolbar.h
index 749bbfbb2304222d2198bbbaf2f25d95e1257eaf..2160f9d89df1832ede731f0e17999e16b8de7822 100644
--- a/GUI/View/Setup/DataToolbar.h
+++ b/GUI/View/Setup/DataToolbar.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_VIEW_SETUP_DATATOOLBAR_H
 #define BORNAGAIN_GUI_VIEW_SETUP_DATATOOLBAR_H
 
-#include "GUI/View/Tool/Canvas2DMode.h"
+#include "GUI/View/Setup/Canvas2DMode.h"
 #include <QButtonGroup>
 #include <QToolBar>
 
diff --git a/GUI/View/Setup/MasksPanel.cpp b/GUI/View/Setup/MasksPanel.cpp
index eced7ace42c930505d7675663c025f129659bdd9..01a789f83949790ed3f61345d9e115d6ac1e8150 100644
--- a/GUI/View/Setup/MasksPanel.cpp
+++ b/GUI/View/Setup/MasksPanel.cpp
@@ -18,8 +18,8 @@
 #include "GUI/Model/Mask/MasksQModel.h"
 #include "GUI/Model/Mask/MasksSet.h"
 #include "GUI/Model/Project/ProjectDocument.h"
+#include "GUI/View/Layout/LayoutUtil.h"
 #include "GUI/View/Numeric/DoubleSpinBox.h"
-#include "GUI/View/Tool/LayoutUtil.h"
 #include "GUI/View/Widget/GroupBoxes.h"
 #include <QCheckBox>
 #include <QLineEdit>
diff --git a/GUI/View/Tool/ItemDelegateForHTML.cpp b/GUI/View/Tool/ItemDelegateForHTML.cpp
deleted file mode 100644
index 32e65749969961cbcf7414da8cae172cc76e7581..0000000000000000000000000000000000000000
--- a/GUI/View/Tool/ItemDelegateForHTML.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      GUI/View/Tool/ItemDelegateForHTML.cpp
-//! @brief     Implements class ItemDelegateForHTML.
-//!
-//! @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/View/Tool/ItemDelegateForHTML.h"
-#include <QAbstractItemView>
-#include <QAbstractTextDocumentLayout>
-#include <QApplication>
-#include <QPainter>
-#include <QTextDocument>
-
-namespace {
-
-bool hasHtml(const QString& t)
-{
-    return t.contains("<") && t.contains(">");
-}
-
-QSize mySizeHint(const QString& text)
-{
-    QTextDocument doc;
-    doc.setHtml(text);
-    doc.setTextWidth(10000 /*options.rect.width()*/);
-    QSize size = QSize(doc.idealWidth(), doc.size().height());
-    return size;
-}
-
-} // namespace
-
-
-ItemDelegateForHTML::ItemDelegateForHTML(QObject* parent)
-    : QStyledItemDelegate(parent)
-{
-}
-
-void ItemDelegateForHTML::paint(QPainter* painter, const QStyleOptionViewItem& option,
-                                const QModelIndex& index) const
-{
-    QStyleOptionViewItem options = option;
-    initStyleOption(&options, index);
-    if (!hasHtml(options.text)) {
-        QStyledItemDelegate::paint(painter, option, index);
-        return;
-    }
-
-    painter->save();
-    QTextDocument doc;
-    doc.setHtml(options.text);
-
-    options.text = "";
-
-    const QWidget* widget = option.widget;
-    QStyle* style = widget ? widget->style() : QApplication::style();
-    style->drawControl(QStyle::CE_ItemViewItem, &options, painter, widget);
-
-    // shift text right to make icon visible
-    QSize iconSize = options.icon.actualSize(options.rect.size());
-    painter->translate(options.rect.left() + iconSize.width(), options.rect.top());
-    QRect clip(0, 0, options.rect.width() + iconSize.width(), options.rect.height());
-
-    painter->setClipRect(clip);
-    QAbstractTextDocumentLayout::PaintContext ctx;
-
-    // set text color (see qcommonstyle.cpp, QCommonStyle::drawControl, case CE_ItemViewItem)
-    QPalette::ColorGroup cg =
-        options.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
-    if (cg == QPalette::Normal && !(options.state & QStyle::State_Active))
-        cg = QPalette::Inactive;
-    ctx.palette.setColor(QPalette::Text, option.palette.color(cg, QPalette::Text));
-
-    ctx.clip = clip;
-    doc.documentLayout()->draw(painter, ctx);
-    painter->restore();
-}
-
-QSize ItemDelegateForHTML::sizeHint(const QStyleOptionViewItem& option,
-                                    const QModelIndex& index) const
-{
-    QSize s = QStyledItemDelegate::sizeHint(option, index);
-
-    // get size of parent; this is the minimum size
-    const int h = QStyledItemDelegate::sizeHint(option, index).height();
-    s.setHeight(std::max(s.height(), h));
-
-    QStyleOptionViewItem options = option;
-    initStyleOption(&options, index);
-
-    auto s2 = mySizeHint(options.text);
-    s.setHeight(std::max(s.height(), s2.height() + 10));
-    s.setWidth(s2.width() + h); // +h: icon
-
-    return s;
-}
diff --git a/GUI/View/Views/DataView.cpp b/GUI/View/Views/DataView.cpp
index 42827b2bbcfa1b6348c6d831985049bb6a5224aa..dd455d73dbc8575c383e00d4367c7441030ceeca 100644
--- a/GUI/View/Views/DataView.cpp
+++ b/GUI/View/Views/DataView.cpp
@@ -38,6 +38,6 @@ DataView::DataView()
     splitter->setCollapsible(0, false);
     splitter->setCollapsible(1, false);
 
-    if (selector->currentDatafileItem())
-        stacked_frames->setStackedItem(selector->currentDatafileItem()->dataItem());
+    if (DatafileItem* dfi = selector->currentDatafileItem())
+        stacked_frames->setStackedItem(dfi->dataItem());
 }
diff --git a/GUI/View/Views/InstrumentView.cpp b/GUI/View/Views/InstrumentView.cpp
index 4a77e4763d28be296757957c597a2f0bdf2bea55..ee652cc19273cff295253ec2d5122b658fe322ec 100644
--- a/GUI/View/Views/InstrumentView.cpp
+++ b/GUI/View/Views/InstrumentView.cpp
@@ -19,10 +19,10 @@
 #include "GUI/Model/Project/ProjectDocument.h"
 #include "GUI/View/Instrument/DepthprobeInstrumentEditor.h"
 #include "GUI/View/Instrument/GISASInstrumentEditor.h"
-#include "GUI/View/Instrument/InstrumentsQListView.h"
 #include "GUI/View/Instrument/OffspecInstrumentEditor.h"
 #include "GUI/View/Instrument/SpecularInstrumentEditor.h"
 #include "GUI/View/Layout/ApplicationSettings.h"
+#include "GUI/View/List/InstrumentsQListView.h"
 #include "GUI/View/Setup/FrameActions.h"
 #include "GUI/View/Widget/GroupBoxes.h"
 #include "GUI/View/Widget/StyledToolbar.h"
diff --git a/GUI/View/Views/ProjectsView.cpp b/GUI/View/Views/ProjectsView.cpp
index 5490696e4c371faf36b3455ed409801bea2ef958..a68d2dad786bd32c23bfd08a369b78d3b02b3c41 100644
--- a/GUI/View/Views/ProjectsView.cpp
+++ b/GUI/View/Views/ProjectsView.cpp
@@ -14,8 +14,8 @@
 
 #include "GUI/View/Views/ProjectsView.h"
 #include "GUI/Support/Util/Path.h"
+#include "GUI/View/Layout/LayoutUtil.h"
 #include "GUI/View/Manager/ProjectManager.h"
-#include "GUI/View/Tool/LayoutUtil.h"
 #include "GUI/View/Widget/GroupBoxes.h"
 #include "GUI/View/Widget/StyledToolbar.h"
 #include <QCommandLinkButton>
diff --git a/GUI/View/Views/SampleView.cpp b/GUI/View/Views/SampleView.cpp
index f40c0d98bc5ffea5b62ab704ddc6fa78aadbab8b..107761dbd6f257d4cb522626e02c117ab8db70cb 100644
--- a/GUI/View/Views/SampleView.cpp
+++ b/GUI/View/Views/SampleView.cpp
@@ -20,10 +20,10 @@
 #include "GUI/Model/Sample/SampleItem.h"
 #include "GUI/View/Layout/ApplicationSettings.h"
 #include "GUI/View/Layout/mainwindow_constants.h"
+#include "GUI/View/List/SamplesQListView.h"
 #include "GUI/View/Realspace/RealspacePanel.h"
 #include "GUI/View/Realspace/RealspaceWidget.h"
 #include "GUI/View/Sample/SampleEditor.h"
-#include "GUI/View/Sample/SamplesQListView.h"
 #include "GUI/View/Sample/ScriptPanel.h"
 #include "GUI/View/Widget/StyledToolbar.h"
 #include <QBoxLayout>
diff --git a/GUI/View/Views/SimulationView.cpp b/GUI/View/Views/SimulationView.cpp
index 082c1b156d4f619947a0499d4d3c1bb8c50cc3d9..3c99d37fd3327d151d67821a9df4f5e40ff2db46 100644
--- a/GUI/View/Views/SimulationView.cpp
+++ b/GUI/View/Views/SimulationView.cpp
@@ -409,6 +409,8 @@ const InstrumentItem* SimulationView::selectedInstrumentItem() const
 
 const DatafileItem* SimulationView::selectedDatafileItem() const
 {
-    return gDoc->datafiles()->dfileItems().value(m_real_data_combo->currentIndex() - 1,
-                                                 nullptr); // -1: "None"
+    const int idx = m_real_data_combo->currentIndex() - 1;
+    if (idx < 0 || idx > (int)gDoc->datafiles()->size())
+        return nullptr; // usage: -1 stands for "None"
+    return gDoc->datafiles()->dfileItemAt(idx);
 }
diff --git a/GUI/View/Widget/ItemViewOverlayButtons.cpp b/GUI/View/Widget/ItemViewOverlayButtons.cpp
index b2b83f9661fba69fbd17ee289df85d1f88006469..b6b1ca262db2a78b7092f647219262b46e5163ab 100644
--- a/GUI/View/Widget/ItemViewOverlayButtons.cpp
+++ b/GUI/View/Widget/ItemViewOverlayButtons.cpp
@@ -17,7 +17,6 @@
 #include <QBoxLayout>
 #include <QKeyEvent>
 #include <QMenu>
-#include <QStyledItemDelegate>
 #include <QToolButton>
 
 namespace {
@@ -26,8 +25,6 @@ class ItemViewOverlayWidget : public QWidget {
 public:
     ItemViewOverlayWidget(QAbstractItemView* view, const QModelIndex& index);
 
-    static int heightForDelegate();
-
     void setHover(bool b);
     void create();
     void hover(bool h);
@@ -45,19 +42,6 @@ private:
     Qt::Alignment m_horizontal_alignment;
 };
 
-class ItemViewOverlayDelegate : public QStyledItemDelegate {
-public:
-    QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override
-    {
-        QSize s = QStyledItemDelegate::sizeHint(option, index);
-        if (index.parent().isValid()) {
-            const int h = ItemViewOverlayWidget::heightForDelegate();
-            s.setHeight(std::max(s.height(), h));
-        }
-
-        return s;
-    }
-};
 
 ItemViewOverlayWidget::ItemViewOverlayWidget(QAbstractItemView* view, const QModelIndex& index)
     : QWidget(view)
@@ -74,14 +58,6 @@ void ItemViewOverlayWidget::setHover(bool b)
     m_hover = b;
 }
 
-int ItemViewOverlayWidget::heightForDelegate()
-{
-    QToolButton btn;
-    const int size = QApplication::style()->pixelMetric(QStyle::PM_ToolBarIconSize);
-    btn.setIconSize(QSize(size, size));
-    return btn.sizeHint().height() + 6; // 3px on top and bottom
-}
-
 void ItemViewOverlayWidget::enterEvent(QEnterEvent*)
 {
     hover(true);
@@ -101,7 +77,6 @@ void ItemViewOverlayWidget::mouseDoubleClickEvent(QMouseEvent* ev)
         ev->accept();
         return;
     }
-
     ev->ignore();
 }
 
@@ -152,20 +127,18 @@ void ItemViewOverlayWidget::setHorizontalAlignment(Qt::Alignment a)
     m_horizontal_alignment = a;
 }
 
+
 } // namespace
 
+
 void ItemViewOverlayButtons::install(QAbstractItemView* view, FnGetActions fnGetActions)
 {
     auto* h = new ItemViewOverlayButtons(view);
     h->m_get_actions = fnGetActions;
     h->m_view = view;
-    auto* d = new ItemViewOverlayDelegate;
-    view->setItemDelegate(d);
     view->installEventFilter(h);
     h->update();
 
-    connect(d, &QAbstractItemDelegate::closeEditor, h, &ItemViewOverlayButtons::update);
-
     connect(view->model(), &QAbstractItemModel::modelReset, h, &ItemViewOverlayButtons::update,
             Qt::QueuedConnection);
     connect(view->model(), &QAbstractItemModel::rowsInserted, h, &ItemViewOverlayButtons::update,
@@ -195,32 +168,20 @@ ItemViewOverlayButtons::ItemViewOverlayButtons(QObject* parent)
 {
 }
 
-void ItemViewOverlayButtons::updateRecursive(const QModelIndex& index)
-{
-    const auto hoverIfNecessary = [&](QModelIndex i) {
-        QPoint viewPortMousePos = m_view->mapFromGlobal(QCursor::pos());
-        if (m_view->indexAt(viewPortMousePos) == i)
-            if (auto* w = dynamic_cast<ItemViewOverlayWidget*>(m_view->indexWidget(i)))
-                w->hover(true);
-    };
-
-    if (m_view->indexWidget(index) == nullptr)
-        installOverlay(index);
-    hoverIfNecessary(index);
-
-    auto* m = m_view->model();
-    for (int childRow = 0; childRow < m->rowCount(index); childRow++)
-        updateRecursive(m->index(childRow, 0, index));
-}
-
-
 void ItemViewOverlayButtons::update()
 {
     if (m_view->model() == nullptr)
         return;
     auto* m = m_view->model();
-    for (int row = 0; row < m->rowCount(); row++)
-        updateRecursive(m->index(row, 0));
+    for (int row = 0; row < m->rowCount(); row++) {
+        const QModelIndex index = m->index(row, 0);
+        if (m_view->indexWidget(index) == nullptr)
+            installOverlay(index);
+        QPoint viewPortMousePos = m_view->mapFromGlobal(QCursor::pos());
+        if (m_view->indexAt(viewPortMousePos) == index)
+            if (auto* w = dynamic_cast<ItemViewOverlayWidget*>(m_view->indexWidget(index)))
+                w->hover(true);
+    }
 }
 
 void ItemViewOverlayButtons::installOverlay(const QModelIndex& index)
diff --git a/GUI/View/Widget/ItemViewOverlayButtons.h b/GUI/View/Widget/ItemViewOverlayButtons.h
index ca909ca1bb40421a8ade4b5d6c453f67eec7deda..815d037dfa5ea5e3c949b1b4e87295f5db69898e 100644
--- a/GUI/View/Widget/ItemViewOverlayButtons.h
+++ b/GUI/View/Widget/ItemViewOverlayButtons.h
@@ -20,6 +20,11 @@
 #include <QObject>
 #include <functional>
 
+//! Supports action buttons in the single rows of a list view.
+//! Buttons may be permanent or only show up when hovered over.
+//!
+//! In feb24, this code was restricted from self-made views to list views.
+
 class ItemViewOverlayButtons : public QObject {
     Q_OBJECT
 public:
@@ -31,7 +36,6 @@ private:
     bool eventFilter(QObject* obj, QEvent* event) override;
 
     ItemViewOverlayButtons(QObject* parent);
-    void updateRecursive(const QModelIndex& index);
     void update();
     void installOverlay(const QModelIndex& index);
 
diff --git a/GUI/View/Widget/ListItemDelegate.cpp b/GUI/View/Widget/ListItemDelegate.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7b3f1aab855a3dab86bffa3878c720ef04c9aee4
--- /dev/null
+++ b/GUI/View/Widget/ListItemDelegate.cpp
@@ -0,0 +1,70 @@
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      GUI/View/Widget/ListItemDelegate.cpp
+//! @brief     Implements class ListItemDelegate.
+//!
+//! @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/View/Widget/ListItemDelegate.h"
+#include <QPainter>
+#include <QTextDocument>
+
+namespace {
+
+QSize mySizeHint(const QString& text)
+{
+    QTextDocument doc;
+    doc.setHtml(text);
+    doc.setTextWidth(10000 /*options.rect.width()*/);
+    QSize size = QSize(doc.idealWidth(), doc.size().height());
+    return size;
+}
+
+} // namespace
+
+
+ListItemDelegate::ListItemDelegate(QObject* parent)
+    : QStyledItemDelegate(parent)
+{
+}
+
+void ListItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
+                             const QModelIndex& index) const
+{
+    QStyleOptionViewItem options = option;
+    initStyleOption(&options, index);
+
+    QStyledItemDelegate::paint(painter, option, index);
+
+    painter->save();
+    painter->setPen(QPen(Qt::lightGray, 1));
+    painter->drawLine(options.rect.left(), options.rect.bottom(), options.rect.right(),
+                      options.rect.bottom());
+    painter->restore();
+}
+
+QSize ListItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+    QSize s = QStyledItemDelegate::sizeHint(option, index);
+
+    // get size of parent; this is the minimum size
+    const int h = QStyledItemDelegate::sizeHint(option, index).height();
+    s.setHeight(std::max(s.height(), h));
+
+    QStyleOptionViewItem options = option;
+    initStyleOption(&options, index);
+
+    auto s2 = mySizeHint(options.text);
+    s.setHeight(std::max(s.height(), s2.height() + 10));
+    s.setHeight(std::max(s.height(), 32));
+    s.setWidth(s2.width() + h); // +h: icon
+
+    return s;
+}
diff --git a/GUI/View/Tool/ItemDelegateForHTML.h b/GUI/View/Widget/ListItemDelegate.h
similarity index 66%
rename from GUI/View/Tool/ItemDelegateForHTML.h
rename to GUI/View/Widget/ListItemDelegate.h
index 3e6fdbec1988901360c54c229e720e3d24c42cb2..c80e68e15177f0c081e4adc7ae9a5f02549a5edc 100644
--- a/GUI/View/Tool/ItemDelegateForHTML.h
+++ b/GUI/View/Widget/ListItemDelegate.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Tool/ItemDelegateForHTML.h
-//! @brief     Defines class ItemDelegateForHTML.
+//! @file      GUI/View/Widget/ListItemDelegate.h
+//! @brief     Defines class ListItemDelegate.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,16 +12,17 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_TOOL_ITEMDELEGATEFORHTML_H
-#define BORNAGAIN_GUI_VIEW_TOOL_ITEMDELEGATEFORHTML_H
+#ifndef BORNAGAIN_GUI_VIEW_WIDGET_LISTITEMDELEGATE_H
+#define BORNAGAIN_GUI_VIEW_WIDGET_LISTITEMDELEGATE_H
 
 #include <QStyledItemDelegate>
 
-//! For representing HTML text in an item */
-class ItemDelegateForHTML : public QStyledItemDelegate {
+//! Styling for items in list.
+
+class ListItemDelegate : public QStyledItemDelegate {
     Q_OBJECT
 public:
-    ItemDelegateForHTML(QObject* parent);
+    ListItemDelegate(QObject* parent);
 
 protected:
     void paint(QPainter* painter, const QStyleOptionViewItem& option,
@@ -29,5 +30,4 @@ protected:
     QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
 };
 
-
-#endif // BORNAGAIN_GUI_VIEW_TOOL_ITEMDELEGATEFORHTML_H
+#endif // BORNAGAIN_GUI_VIEW_WIDGET_LISTITEMDELEGATE_H
diff --git a/GUI/View/Tool/WidgetMoverButton.cpp b/GUI/View/Widget/WidgetMoverButton.cpp
similarity index 98%
rename from GUI/View/Tool/WidgetMoverButton.cpp
rename to GUI/View/Widget/WidgetMoverButton.cpp
index ae8dd9cf5ffd744f51a9144c82ed886d4668b499..d7c264b9a6134977df58ff22a32786c9be545b4e 100644
--- a/GUI/View/Tool/WidgetMoverButton.cpp
+++ b/GUI/View/Widget/WidgetMoverButton.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Tool/WidgetMoverButton.cpp
+//! @file      GUI/View/Widget/WidgetMoverButton.cpp
 //! @brief     Implements class WidgetMoverButton.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/View/Tool/WidgetMoverButton.h"
+#include "GUI/View/Widget/WidgetMoverButton.h"
 #include "Base/Util/Assert.h"
 #include <QLayout>
 #include <QMouseEvent>
diff --git a/GUI/View/Tool/WidgetMoverButton.h b/GUI/View/Widget/WidgetMoverButton.h
similarity index 92%
rename from GUI/View/Tool/WidgetMoverButton.h
rename to GUI/View/Widget/WidgetMoverButton.h
index ae7c998e913ddc32c8842951c6faa464f3068cd9..3799a89d94d88397f38acb0ef3f22af48b879b66 100644
--- a/GUI/View/Tool/WidgetMoverButton.h
+++ b/GUI/View/Widget/WidgetMoverButton.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/View/Tool/WidgetMoverButton.h
+//! @file      GUI/View/Widget/WidgetMoverButton.h
 //! @brief     Defines class WidgetMoverButton.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_VIEW_TOOL_WIDGETMOVERBUTTON_H
-#define BORNAGAIN_GUI_VIEW_TOOL_WIDGETMOVERBUTTON_H
+#ifndef BORNAGAIN_GUI_VIEW_WIDGET_WIDGETMOVERBUTTON_H
+#define BORNAGAIN_GUI_VIEW_WIDGET_WIDGETMOVERBUTTON_H
 
 #include <QMap>
 #include <QPropertyAnimation>
@@ -70,4 +70,4 @@ private:
 };
 
 
-#endif // BORNAGAIN_GUI_VIEW_TOOL_WIDGETMOVERBUTTON_H
+#endif // BORNAGAIN_GUI_VIEW_WIDGET_WIDGETMOVERBUTTON_H
diff --git a/Tests/Unit/GUI/TestDatafilesModel.cpp b/Tests/Unit/GUI/TestDatafilesModel.cpp
index ab5e81639689a1a3006798eb1f8dc0954d066c8b..57d8b28d21f24f5d25e3b125700a518503a99f20 100644
--- a/Tests/Unit/GUI/TestDatafilesModel.cpp
+++ b/Tests/Unit/GUI/TestDatafilesModel.cpp
@@ -83,23 +83,22 @@ TEST(TestDatafilesSet, saveXMLData)
 
     // add specular DatafileItems with non-default parameters
     auto* spec1 = new DatafileItem("spec1", df1);
-    model1.insertDatafileItem(spec1);
+    model1.appendDatafileItem(spec1);
     spec1->linkToInstrument(instrument_model.addInstrumentItem<SpecularInstrumentItem>());
 
     // add second specular DatafileItem
     auto* spec2 = new DatafileItem("spec2", df2);
-    model1.insertDatafileItem(spec2);
+    model1.appendDatafileItem(spec2);
 
     // add 2D DatafileItems with non-default parameters
     auto* intensity1 = new DatafileItem("GISAS", df2);
     auto* intensity2 = new DatafileItem("Offspec", df2);
-    model1.insertDatafileItem(intensity1);
-    model1.insertDatafileItem(intensity2);
+    model1.appendDatafileItem(intensity1);
+    model1.appendDatafileItem(intensity2);
     intensity1->linkToInstrument(instrument_model.addInstrumentItem<GISASInstrumentItem>());
     intensity2->linkToInstrument(instrument_model.addInstrumentItem<OffspecInstrumentItem>());
 
     // set non-default top-level model parameters
-    model1.setSelectedRank(2);
     model1.setCurrentIndex(1);
 
     // save data to project files
diff --git a/Tests/Unit/GUI/TestJobModel.cpp b/Tests/Unit/GUI/TestJobModel.cpp
index e0a76a9ca5ffd8150776e421dc790f2e0f9de1e7..9fd1395fff140702d3fab5f1a70f7f01b73ef6e2 100644
--- a/Tests/Unit/GUI/TestJobModel.cpp
+++ b/Tests/Unit/GUI/TestJobModel.cpp
@@ -65,7 +65,7 @@ TEST(TestJobsSet, saveNonXMLData)
     job_item->updateFileName();
 
     // save first time
-    jobs.writeDatafiles(projectDir);
+    jobs.saveAllDatafields(projectDir);
     QTest::qSleep(10);
 
     // check existence of data on disk
@@ -82,7 +82,7 @@ TEST(TestJobsSet, saveNonXMLData)
 
     // modify data and save the project.
     job_item->simulatedDataItem()->setDatafield(UTest::GUI::makeData2D(103.));
-    jobs.writeDatafiles(projectDir);
+    jobs.saveAllDatafields(projectDir);
     QTest::qSleep(10);
 
     // ensure that the simulated data has been changed
@@ -96,7 +96,7 @@ TEST(TestJobsSet, saveNonXMLData)
     // rename job and check that file on disk changed the name
     job_item->batchInfo()->setJobName("new_job");
     job_item->updateFileName();
-    jobs.writeDatafiles(projectDir);
+    jobs.saveAllDatafields(projectDir);
     QTest::qSleep(10);
 
     // check existence of new files on disk
diff --git a/Tests/Unit/GUI/TestLinkInstrument.cpp b/Tests/Unit/GUI/TestLinkInstrument.cpp
index 0fc793d3a34c0c05fdc0bd47a256166ded66e4e4..ef972f4a43838b0874828a94e375ffdc519de76a 100644
--- a/Tests/Unit/GUI/TestLinkInstrument.cpp
+++ b/Tests/Unit/GUI/TestLinkInstrument.cpp
@@ -13,8 +13,6 @@
 #include "GUI/Model/Project/ProjectDocument.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include "Tests/Unit/GUI/Utils.h"
-#include <QSignalSpy>
-#include <QTest>
 
 QList<DatafileItem*> linkedRealDataItems(DatafilesSet& realModel,
                                          const InstrumentItem* instrumentItem)
@@ -22,12 +20,12 @@ QList<DatafileItem*> linkedRealDataItems(DatafilesSet& realModel,
     ASSERT(instrumentItem);
 
     QList<DatafileItem*> result;
-    for (auto* dfile_item : realModel.dfileItems()) {
-        const QString linkedIdentifier = dfile_item->instrumentId();
+    for (auto* dfi : realModel.dfileItems()) {
+        const QString linkedIdentifier = dfi->instrumentId();
         const QString instrumentIdentifier = instrumentItem->id();
 
         if (linkedIdentifier == instrumentIdentifier)
-            result.append(dfile_item);
+            result.append(dfi);
     }
     return result;
 }
diff --git a/Tests/Unit/GUI/Utils.cpp b/Tests/Unit/GUI/Utils.cpp
index 7c91a191041a30fdba892a62415d6c38ae522527..9b382b174b547fee4a8002648b334557f54f66bd 100644
--- a/Tests/Unit/GUI/Utils.cpp
+++ b/Tests/Unit/GUI/Utils.cpp
@@ -57,14 +57,14 @@ Datafield UTest::GUI::makeData2D(double value, int nx, double x_min, double x_ma
 DatafileItem* UTest::GUI::createRealData1D(const QString& name, DatafilesSet& model, double value)
 {
     auto* dfi = new DatafileItem(name, makeData1D(value));
-    model.insertDatafileItem(dfi);
+    model.appendDatafileItem(dfi);
     return dfi;
 }
 
 DatafileItem* UTest::GUI::createRealData2D(const QString& name, DatafilesSet& model, double value)
 {
     auto* dfi = new DatafileItem(name, makeData2D(value));
-    model.insertDatafileItem(dfi);
+    model.appendDatafileItem(dfi);
     return dfi;
 }
 
diff --git a/auto/Wrap/libBornAgainSample.py b/auto/Wrap/libBornAgainSample.py
index 6a86acb46a9e2b4f1981f2613900f94e1b352c07..9e881cbff67652dc085ac3cedb103013a73d624f 100644
--- a/auto/Wrap/libBornAgainSample.py
+++ b/auto/Wrap/libBornAgainSample.py
@@ -2853,6 +2853,23 @@ class IParticle(ISampleNode):
 
 # Register IParticle in _libBornAgainSample:
 _libBornAgainSample.IParticle_swigregister(IParticle)
+class ShapeIndexes(object):
+    r"""Proxy of C++ ShapeIndexes class."""
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+    min = property(_libBornAgainSample.ShapeIndexes_min_get, _libBornAgainSample.ShapeIndexes_min_set, doc=r"""min : I3""")
+    max = property(_libBornAgainSample.ShapeIndexes_max_get, _libBornAgainSample.ShapeIndexes_max_set, doc=r"""max : I3""")
+    basisIndexes = property(_libBornAgainSample.ShapeIndexes_basisIndexes_get, _libBornAgainSample.ShapeIndexes_basisIndexes_set, doc=r"""basisIndexes : std::vector<(I3,std::allocator<(I3)>)>""")
+    k_pairs = property(_libBornAgainSample.ShapeIndexes_k_pairs_get, _libBornAgainSample.ShapeIndexes_k_pairs_set, doc=r"""k_pairs : std::vector<(std::vector<(std::vector<(std::pair<(int,int)>,std::allocator<(std::pair<(int,int)>)>)>,std::allocator<(std::vector<(std::pair<(int,int)>,std::allocator<(std::pair<(int,int)>)>)>)>)>,std::allocator<(std::vector<(std::vector<(std::pair<(int,int)>,std::allocator<(std::pair<(int,int)>)>)>,std::allocator<(std::vector<(std::pair<(int,int)>,std::allocator<(std::pair<(int,int)>)>)>)>)>)>)>""")
+
+    def __init__(self):
+        r"""__init__(ShapeIndexes self) -> ShapeIndexes"""
+        _libBornAgainSample.ShapeIndexes_swiginit(self, _libBornAgainSample.new_ShapeIndexes())
+    __swig_destroy__ = _libBornAgainSample.delete_ShapeIndexes
+
+# Register ShapeIndexes in _libBornAgainSample:
+_libBornAgainSample.ShapeIndexes_swigregister(ShapeIndexes)
 class Mesocrystal(IParticle):
     r"""Proxy of C++ Mesocrystal class."""
 
diff --git a/auto/Wrap/libBornAgainSample_wrap.cpp b/auto/Wrap/libBornAgainSample_wrap.cpp
index c2a7c3c4499655abfeb2498c7736337ad1908ba9..261fb5d1064dc4fb94f2e4a97e1e56f124ad5345 100644
--- a/auto/Wrap/libBornAgainSample_wrap.cpp
+++ b/auto/Wrap/libBornAgainSample_wrap.cpp
@@ -3739,68 +3739,71 @@ namespace Swig {
 #define SWIGTYPE_p_SawtoothRippleBox swig_types[95]
 #define SWIGTYPE_p_SawtoothRippleGauss swig_types[96]
 #define SWIGTYPE_p_SawtoothRippleLorentz swig_types[97]
-#define SWIGTYPE_p_SimpleSelectionRule swig_types[98]
-#define SWIGTYPE_p_Span swig_types[99]
-#define SWIGTYPE_p_Sphere swig_types[100]
-#define SWIGTYPE_p_Spheroid swig_types[101]
-#define SWIGTYPE_p_SpinMatrix swig_types[102]
-#define SWIGTYPE_p_SquareLattice2D swig_types[103]
-#define SWIGTYPE_p_TruncatedCube swig_types[104]
-#define SWIGTYPE_p_TruncatedSphere swig_types[105]
-#define SWIGTYPE_p_TruncatedSpheroid swig_types[106]
-#define SWIGTYPE_p_Vec3T_double_t swig_types[107]
-#define SWIGTYPE_p_Vec3T_int_t swig_types[108]
-#define SWIGTYPE_p_Vec3T_std__complexT_double_t_t swig_types[109]
-#define SWIGTYPE_p_WavevectorInfo swig_types[110]
-#define SWIGTYPE_p_allocator_type swig_types[111]
-#define SWIGTYPE_p_char swig_types[112]
-#define SWIGTYPE_p_difference_type swig_types[113]
-#define SWIGTYPE_p_first_type swig_types[114]
-#define SWIGTYPE_p_int swig_types[115]
-#define SWIGTYPE_p_key_type swig_types[116]
-#define SWIGTYPE_p_long_long swig_types[117]
-#define SWIGTYPE_p_mapped_type swig_types[118]
-#define SWIGTYPE_p_p_PyObject swig_types[119]
-#define SWIGTYPE_p_second_type swig_types[120]
-#define SWIGTYPE_p_short swig_types[121]
-#define SWIGTYPE_p_signed_char swig_types[122]
-#define SWIGTYPE_p_size_type swig_types[123]
-#define SWIGTYPE_p_std__allocatorT_INode_const_p_t swig_types[124]
-#define SWIGTYPE_p_std__allocatorT_Vec3T_double_t_t swig_types[125]
-#define SWIGTYPE_p_std__allocatorT_double_t swig_types[126]
-#define SWIGTYPE_p_std__allocatorT_int_t swig_types[127]
-#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[128]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[129]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[130]
-#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[131]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_t_t swig_types[132]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_t_t swig_types[133]
-#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[134]
-#define SWIGTYPE_p_std__complexT_double_t swig_types[135]
-#define SWIGTYPE_p_std__functionT_double_fdoubleF_t swig_types[136]
-#define SWIGTYPE_p_std__invalid_argument swig_types[137]
-#define SWIGTYPE_p_std__lessT_std__string_t swig_types[138]
-#define SWIGTYPE_p_std__mapT_std__string_double_t swig_types[139]
-#define SWIGTYPE_p_std__pairT_double_double_t swig_types[140]
-#define SWIGTYPE_p_std__vectorT_INode_const_p_t swig_types[141]
-#define SWIGTYPE_p_std__vectorT_ParaMeta_std__allocatorT_ParaMeta_t_t swig_types[142]
-#define SWIGTYPE_p_std__vectorT_Vec3T_double_t_t swig_types[143]
-#define SWIGTYPE_p_std__vectorT_double_t swig_types[144]
-#define SWIGTYPE_p_std__vectorT_int_t swig_types[145]
-#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_t swig_types[146]
-#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_t swig_types[147]
-#define SWIGTYPE_p_std__vectorT_std__string_t swig_types[148]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_double_t_t swig_types[149]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_int_t_t swig_types[150]
-#define SWIGTYPE_p_std__vectorT_unsigned_long_t swig_types[151]
-#define SWIGTYPE_p_swig__SwigPyIterator swig_types[152]
-#define SWIGTYPE_p_unsigned_char swig_types[153]
-#define SWIGTYPE_p_unsigned_int swig_types[154]
-#define SWIGTYPE_p_unsigned_long_long swig_types[155]
-#define SWIGTYPE_p_unsigned_short swig_types[156]
-#define SWIGTYPE_p_value_type swig_types[157]
-static swig_type_info *swig_types[159];
-static swig_module_info swig_module = {swig_types, 158, 0, 0, 0, 0};
+#define SWIGTYPE_p_ShapeIndexes swig_types[98]
+#define SWIGTYPE_p_SimpleSelectionRule swig_types[99]
+#define SWIGTYPE_p_Span swig_types[100]
+#define SWIGTYPE_p_Sphere swig_types[101]
+#define SWIGTYPE_p_Spheroid swig_types[102]
+#define SWIGTYPE_p_SpinMatrix swig_types[103]
+#define SWIGTYPE_p_SquareLattice2D swig_types[104]
+#define SWIGTYPE_p_TruncatedCube swig_types[105]
+#define SWIGTYPE_p_TruncatedSphere swig_types[106]
+#define SWIGTYPE_p_TruncatedSpheroid swig_types[107]
+#define SWIGTYPE_p_Vec3T_double_t swig_types[108]
+#define SWIGTYPE_p_Vec3T_int_t swig_types[109]
+#define SWIGTYPE_p_Vec3T_std__complexT_double_t_t swig_types[110]
+#define SWIGTYPE_p_WavevectorInfo swig_types[111]
+#define SWIGTYPE_p_allocator_type swig_types[112]
+#define SWIGTYPE_p_char swig_types[113]
+#define SWIGTYPE_p_difference_type swig_types[114]
+#define SWIGTYPE_p_first_type swig_types[115]
+#define SWIGTYPE_p_int swig_types[116]
+#define SWIGTYPE_p_key_type swig_types[117]
+#define SWIGTYPE_p_long_long swig_types[118]
+#define SWIGTYPE_p_mapped_type swig_types[119]
+#define SWIGTYPE_p_p_PyObject swig_types[120]
+#define SWIGTYPE_p_second_type swig_types[121]
+#define SWIGTYPE_p_short swig_types[122]
+#define SWIGTYPE_p_signed_char swig_types[123]
+#define SWIGTYPE_p_size_type swig_types[124]
+#define SWIGTYPE_p_std__allocatorT_INode_const_p_t swig_types[125]
+#define SWIGTYPE_p_std__allocatorT_Vec3T_double_t_t swig_types[126]
+#define SWIGTYPE_p_std__allocatorT_double_t swig_types[127]
+#define SWIGTYPE_p_std__allocatorT_int_t swig_types[128]
+#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[129]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[130]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[131]
+#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[132]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_t_t swig_types[133]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_t_t swig_types[134]
+#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[135]
+#define SWIGTYPE_p_std__complexT_double_t swig_types[136]
+#define SWIGTYPE_p_std__functionT_double_fdoubleF_t swig_types[137]
+#define SWIGTYPE_p_std__invalid_argument swig_types[138]
+#define SWIGTYPE_p_std__lessT_std__string_t swig_types[139]
+#define SWIGTYPE_p_std__mapT_std__string_double_t swig_types[140]
+#define SWIGTYPE_p_std__pairT_double_double_t swig_types[141]
+#define SWIGTYPE_p_std__vectorT_INode_const_p_t swig_types[142]
+#define SWIGTYPE_p_std__vectorT_ParaMeta_std__allocatorT_ParaMeta_t_t swig_types[143]
+#define SWIGTYPE_p_std__vectorT_Vec3T_double_t_t swig_types[144]
+#define SWIGTYPE_p_std__vectorT_Vec3T_int_t_std__allocatorT_Vec3T_int_t_t_t swig_types[145]
+#define SWIGTYPE_p_std__vectorT_double_t swig_types[146]
+#define SWIGTYPE_p_std__vectorT_int_t swig_types[147]
+#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_t swig_types[148]
+#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_t swig_types[149]
+#define SWIGTYPE_p_std__vectorT_std__string_t swig_types[150]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_double_t_t swig_types[151]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_int_t_t swig_types[152]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_std__allocatorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_t_t swig_types[153]
+#define SWIGTYPE_p_std__vectorT_unsigned_long_t swig_types[154]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[155]
+#define SWIGTYPE_p_unsigned_char swig_types[156]
+#define SWIGTYPE_p_unsigned_int swig_types[157]
+#define SWIGTYPE_p_unsigned_long_long swig_types[158]
+#define SWIGTYPE_p_unsigned_short swig_types[159]
+#define SWIGTYPE_p_value_type swig_types[160]
+static swig_type_info *swig_types[162];
+static swig_module_info swig_module = {swig_types, 161, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
@@ -38180,6 +38183,290 @@ SWIGINTERN PyObject *IParticle_swigregister(PyObject *SWIGUNUSEDPARM(self), PyOb
   return SWIG_Py_Void();
 }
 
+SWIGINTERN PyObject *_wrap_ShapeIndexes_min_set(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *arg1 = (ShapeIndexes *) 0 ;
+  I3 *arg2 = (I3 *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  (void)self;
+  if (!SWIG_Python_UnpackTuple(args, "ShapeIndexes_min_set", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ShapeIndexes, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ShapeIndexes_min_set" "', argument " "1"" of type '" "ShapeIndexes *""'"); 
+  }
+  arg1 = reinterpret_cast< ShapeIndexes * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_Vec3T_int_t, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ShapeIndexes_min_set" "', argument " "2"" of type '" "I3 *""'"); 
+  }
+  arg2 = reinterpret_cast< I3 * >(argp2);
+  if (arg1) (arg1)->min = *arg2;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ShapeIndexes_min_get(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *arg1 = (ShapeIndexes *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  I3 *result = 0 ;
+  
+  (void)self;
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ShapeIndexes, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ShapeIndexes_min_get" "', argument " "1"" of type '" "ShapeIndexes *""'"); 
+  }
+  arg1 = reinterpret_cast< ShapeIndexes * >(argp1);
+  result = (I3 *)& ((arg1)->min);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Vec3T_int_t, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ShapeIndexes_max_set(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *arg1 = (ShapeIndexes *) 0 ;
+  I3 *arg2 = (I3 *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  (void)self;
+  if (!SWIG_Python_UnpackTuple(args, "ShapeIndexes_max_set", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ShapeIndexes, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ShapeIndexes_max_set" "', argument " "1"" of type '" "ShapeIndexes *""'"); 
+  }
+  arg1 = reinterpret_cast< ShapeIndexes * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_Vec3T_int_t, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ShapeIndexes_max_set" "', argument " "2"" of type '" "I3 *""'"); 
+  }
+  arg2 = reinterpret_cast< I3 * >(argp2);
+  if (arg1) (arg1)->max = *arg2;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ShapeIndexes_max_get(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *arg1 = (ShapeIndexes *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  I3 *result = 0 ;
+  
+  (void)self;
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ShapeIndexes, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ShapeIndexes_max_get" "', argument " "1"" of type '" "ShapeIndexes *""'"); 
+  }
+  arg1 = reinterpret_cast< ShapeIndexes * >(argp1);
+  result = (I3 *)& ((arg1)->max);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Vec3T_int_t, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ShapeIndexes_basisIndexes_set(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *arg1 = (ShapeIndexes *) 0 ;
+  std::vector< I3,std::allocator< I3 > > *arg2 = (std::vector< I3,std::allocator< I3 > > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  (void)self;
+  if (!SWIG_Python_UnpackTuple(args, "ShapeIndexes_basisIndexes_set", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ShapeIndexes, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ShapeIndexes_basisIndexes_set" "', argument " "1"" of type '" "ShapeIndexes *""'"); 
+  }
+  arg1 = reinterpret_cast< ShapeIndexes * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_std__vectorT_Vec3T_int_t_std__allocatorT_Vec3T_int_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ShapeIndexes_basisIndexes_set" "', argument " "2"" of type '" "std::vector< I3,std::allocator< I3 > > *""'"); 
+  }
+  arg2 = reinterpret_cast< std::vector< I3,std::allocator< I3 > > * >(argp2);
+  if (arg1) (arg1)->basisIndexes = *arg2;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ShapeIndexes_basisIndexes_get(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *arg1 = (ShapeIndexes *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  std::vector< I3,std::allocator< I3 > > *result = 0 ;
+  
+  (void)self;
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ShapeIndexes, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ShapeIndexes_basisIndexes_get" "', argument " "1"" of type '" "ShapeIndexes *""'"); 
+  }
+  arg1 = reinterpret_cast< ShapeIndexes * >(argp1);
+  result = (std::vector< I3,std::allocator< I3 > > *)& ((arg1)->basisIndexes);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_Vec3T_int_t_std__allocatorT_Vec3T_int_t_t_t, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ShapeIndexes_k_pairs_set(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *arg1 = (ShapeIndexes *) 0 ;
+  std::vector< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > >,std::allocator< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > > > > *arg2 = (std::vector< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > >,std::allocator< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > > > > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  (void)self;
+  if (!SWIG_Python_UnpackTuple(args, "ShapeIndexes_k_pairs_set", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ShapeIndexes, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ShapeIndexes_k_pairs_set" "', argument " "1"" of type '" "ShapeIndexes *""'"); 
+  }
+  arg1 = reinterpret_cast< ShapeIndexes * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_std__vectorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_std__allocatorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ShapeIndexes_k_pairs_set" "', argument " "2"" of type '" "std::vector< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > >,std::allocator< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > > > > *""'"); 
+  }
+  arg2 = reinterpret_cast< std::vector< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > >,std::allocator< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > > > > * >(argp2);
+  if (arg1) (arg1)->k_pairs = *arg2;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ShapeIndexes_k_pairs_get(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *arg1 = (ShapeIndexes *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  std::vector< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > >,std::allocator< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > > > > *result = 0 ;
+  
+  (void)self;
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ShapeIndexes, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ShapeIndexes_k_pairs_get" "', argument " "1"" of type '" "ShapeIndexes *""'"); 
+  }
+  arg1 = reinterpret_cast< ShapeIndexes * >(argp1);
+  result = (std::vector< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > >,std::allocator< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > > > > *)& ((arg1)->k_pairs);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_std__allocatorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_t_t, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_ShapeIndexes(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *result = 0 ;
+  
+  (void)self;
+  if (!SWIG_Python_UnpackTuple(args, "new_ShapeIndexes", 0, 0, 0)) SWIG_fail;
+  {
+    try {
+      result = (ShapeIndexes *)new ShapeIndexes();
+    } catch (const std::exception& ex) {
+      // message shown in the Python interpreter
+      const std::string msg {
+        "BornAgain C++ Exception: " + std::string(ex.what())
+      };
+      SWIG_exception(SWIG_RuntimeError, msg.c_str());
+    }
+  }
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ShapeIndexes, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_ShapeIndexes(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ShapeIndexes *arg1 = (ShapeIndexes *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  (void)self;
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ShapeIndexes, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ShapeIndexes" "', argument " "1"" of type '" "ShapeIndexes *""'"); 
+  }
+  arg1 = reinterpret_cast< ShapeIndexes * >(argp1);
+  {
+    try {
+      delete arg1;
+    } catch (const std::exception& ex) {
+      // message shown in the Python interpreter
+      const std::string msg {
+        "BornAgain C++ Exception: " + std::string(ex.what())
+      };
+      SWIG_exception(SWIG_RuntimeError, msg.c_str());
+    }
+  }
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *ShapeIndexes_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_ShapeIndexes, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *ShapeIndexes_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  return SWIG_Python_InitShadowInstance(args);
+}
+
 SWIGINTERN PyObject *_wrap_new_Mesocrystal(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   Crystal *arg1 = 0 ;
@@ -71375,6 +71662,18 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "IParticle_rotate", _wrap_IParticle_rotate, METH_VARARGS, "IParticle_rotate(IParticle self, IRotation rotation) -> IParticle"},
 	 { "IParticle_swigregister", IParticle_swigregister, METH_O, NULL},
+	 { "ShapeIndexes_min_set", _wrap_ShapeIndexes_min_set, METH_VARARGS, "ShapeIndexes_min_set(ShapeIndexes self, I3 * min)"},
+	 { "ShapeIndexes_min_get", _wrap_ShapeIndexes_min_get, METH_O, "ShapeIndexes_min_get(ShapeIndexes self) -> I3 *"},
+	 { "ShapeIndexes_max_set", _wrap_ShapeIndexes_max_set, METH_VARARGS, "ShapeIndexes_max_set(ShapeIndexes self, I3 * max)"},
+	 { "ShapeIndexes_max_get", _wrap_ShapeIndexes_max_get, METH_O, "ShapeIndexes_max_get(ShapeIndexes self) -> I3 *"},
+	 { "ShapeIndexes_basisIndexes_set", _wrap_ShapeIndexes_basisIndexes_set, METH_VARARGS, "ShapeIndexes_basisIndexes_set(ShapeIndexes self, std::vector< I3,std::allocator< I3 > > * basisIndexes)"},
+	 { "ShapeIndexes_basisIndexes_get", _wrap_ShapeIndexes_basisIndexes_get, METH_O, "ShapeIndexes_basisIndexes_get(ShapeIndexes self) -> std::vector< I3,std::allocator< I3 > > *"},
+	 { "ShapeIndexes_k_pairs_set", _wrap_ShapeIndexes_k_pairs_set, METH_VARARGS, "ShapeIndexes_k_pairs_set(ShapeIndexes self, std::vector< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > >,std::allocator< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > > > > * k_pairs)"},
+	 { "ShapeIndexes_k_pairs_get", _wrap_ShapeIndexes_k_pairs_get, METH_O, "ShapeIndexes_k_pairs_get(ShapeIndexes self) -> std::vector< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > >,std::allocator< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > > > > *"},
+	 { "new_ShapeIndexes", _wrap_new_ShapeIndexes, METH_NOARGS, "new_ShapeIndexes() -> ShapeIndexes"},
+	 { "delete_ShapeIndexes", _wrap_delete_ShapeIndexes, METH_O, "delete_ShapeIndexes(ShapeIndexes self)"},
+	 { "ShapeIndexes_swigregister", ShapeIndexes_swigregister, METH_O, NULL},
+	 { "ShapeIndexes_swiginit", ShapeIndexes_swiginit, METH_VARARGS, NULL},
 	 { "new_Mesocrystal", _wrap_new_Mesocrystal, METH_VARARGS, "new_Mesocrystal(Crystal crystal, IFormFactor formfactor) -> Mesocrystal"},
 	 { "delete_Mesocrystal", _wrap_delete_Mesocrystal, METH_O, "delete_Mesocrystal(Mesocrystal self)"},
 	 { "Mesocrystal_clone", _wrap_Mesocrystal_clone, METH_O, "Mesocrystal_clone(Mesocrystal self) -> Mesocrystal"},
@@ -73563,6 +73862,7 @@ static swig_type_info _swigt__p_RoughnessModelWrap__RoughnessModel = {"_p_Roughn
 static swig_type_info _swigt__p_SawtoothRippleBox = {"_p_SawtoothRippleBox", "SawtoothRippleBox *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SawtoothRippleGauss = {"_p_SawtoothRippleGauss", "SawtoothRippleGauss *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SawtoothRippleLorentz = {"_p_SawtoothRippleLorentz", "SawtoothRippleLorentz *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ShapeIndexes = {"_p_ShapeIndexes", "ShapeIndexes *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SimpleSelectionRule = {"_p_SimpleSelectionRule", "SimpleSelectionRule *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Span = {"_p_Span", "Span *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Sphere = {"_p_Sphere", "Sphere *", 0, 0, (void*)0, 0};
@@ -73609,6 +73909,7 @@ static swig_type_info _swigt__p_std__pairT_double_double_t = {"_p_std__pairT_dou
 static swig_type_info _swigt__p_std__vectorT_INode_const_p_t = {"_p_std__vectorT_INode_const_p_t", "std::vector< INode const *,std::allocator< INode const * > > *|std::vector< INode const * > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_ParaMeta_std__allocatorT_ParaMeta_t_t = {"_p_std__vectorT_ParaMeta_std__allocatorT_ParaMeta_t_t", "std::vector< ParaMeta,std::allocator< ParaMeta > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_Vec3T_double_t_t = {"_p_std__vectorT_Vec3T_double_t_t", "std::vector< Vec3< double >,std::allocator< Vec3< double > > > *|std::vector< Vec3< double > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__vectorT_Vec3T_int_t_std__allocatorT_Vec3T_int_t_t_t = {"_p_std__vectorT_Vec3T_int_t_std__allocatorT_Vec3T_int_t_t_t", "std::vector< I3,std::allocator< I3 > > *|std::vector< Vec3< int >,std::allocator< Vec3< int > > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_double_t = {"_p_std__vectorT_double_t", "std::vector< double,std::allocator< double > > *|std::vector< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_int_t = {"_p_std__vectorT_int_t", "std::vector< int,std::allocator< int > > *|std::vector< int > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_std__complexT_double_t_t = {"_p_std__vectorT_std__complexT_double_t_t", "std::vector< std::complex< double >,std::allocator< std::complex< double > > > *|std::vector< std::complex< double > > *", 0, 0, (void*)0, 0};
@@ -73616,6 +73917,7 @@ static swig_type_info _swigt__p_std__vectorT_std__pairT_double_double_t_t = {"_p
 static swig_type_info _swigt__p_std__vectorT_std__string_t = {"_p_std__vectorT_std__string_t", "std::vector< std::string,std::allocator< std::string > > *|std::vector< std::string > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_std__vectorT_double_t_t = {"_p_std__vectorT_std__vectorT_double_t_t", "std::vector< std::vector< double,std::allocator< double > > > *|std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *|std::vector< std::vector< double > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_std__vectorT_int_t_t = {"_p_std__vectorT_std__vectorT_int_t_t", "std::vector< std::vector< int,std::allocator< int > > > *|std::vector< std::vector< int,std::allocator< int > >,std::allocator< std::vector< int,std::allocator< int > > > > *|std::vector< std::vector< int > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__vectorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_std__allocatorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_t_t = {"_p_std__vectorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_std__allocatorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_t_t", "std::vector< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > >,std::allocator< std::vector< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > >,std::allocator< std::vector< std::pair< int,int >,std::allocator< std::pair< int,int > > > > > > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_unsigned_long_t = {"_p_std__vectorT_unsigned_long_t", "std::vector< unsigned long,std::allocator< unsigned long > > *|std::vector< unsigned long > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_swig__SwigPyIterator = {"_p_swig__SwigPyIterator", "swig::SwigPyIterator *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "uint8_t *|uint_fast8_t *|uint_least8_t *|unsigned char *", 0, 0, (void*)0, 0};
@@ -73723,6 +74025,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_SawtoothRippleBox,
   &_swigt__p_SawtoothRippleGauss,
   &_swigt__p_SawtoothRippleLorentz,
+  &_swigt__p_ShapeIndexes,
   &_swigt__p_SimpleSelectionRule,
   &_swigt__p_Span,
   &_swigt__p_Sphere,
@@ -73769,6 +74072,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_std__vectorT_INode_const_p_t,
   &_swigt__p_std__vectorT_ParaMeta_std__allocatorT_ParaMeta_t_t,
   &_swigt__p_std__vectorT_Vec3T_double_t_t,
+  &_swigt__p_std__vectorT_Vec3T_int_t_std__allocatorT_Vec3T_int_t_t_t,
   &_swigt__p_std__vectorT_double_t,
   &_swigt__p_std__vectorT_int_t,
   &_swigt__p_std__vectorT_std__complexT_double_t_t,
@@ -73776,6 +74080,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_std__vectorT_std__string_t,
   &_swigt__p_std__vectorT_std__vectorT_double_t_t,
   &_swigt__p_std__vectorT_std__vectorT_int_t_t,
+  &_swigt__p_std__vectorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_std__allocatorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_t_t,
   &_swigt__p_std__vectorT_unsigned_long_t,
   &_swigt__p_swig__SwigPyIterator,
   &_swigt__p_unsigned_char,
@@ -73883,6 +74188,7 @@ static swig_cast_info _swigc__p_RoughnessModelWrap__RoughnessModel[] = {  {&_swi
 static swig_cast_info _swigc__p_SawtoothRippleBox[] = {  {&_swigt__p_SawtoothRippleBox, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SawtoothRippleGauss[] = {  {&_swigt__p_SawtoothRippleGauss, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SawtoothRippleLorentz[] = {  {&_swigt__p_SawtoothRippleLorentz, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ShapeIndexes[] = {  {&_swigt__p_ShapeIndexes, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SimpleSelectionRule[] = {  {&_swigt__p_SimpleSelectionRule, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Span[] = {  {&_swigt__p_Span, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Sphere[] = {  {&_swigt__p_Sphere, 0, 0, 0},{0, 0, 0, 0}};
@@ -73929,6 +74235,7 @@ static swig_cast_info _swigc__p_std__pairT_double_double_t[] = {  {&_swigt__p_st
 static swig_cast_info _swigc__p_std__vectorT_INode_const_p_t[] = {  {&_swigt__p_std__vectorT_INode_const_p_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_ParaMeta_std__allocatorT_ParaMeta_t_t[] = {  {&_swigt__p_std__vectorT_ParaMeta_std__allocatorT_ParaMeta_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_Vec3T_double_t_t[] = {  {&_swigt__p_std__vectorT_Vec3T_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT_Vec3T_int_t_std__allocatorT_Vec3T_int_t_t_t[] = {  {&_swigt__p_std__vectorT_Vec3T_int_t_std__allocatorT_Vec3T_int_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_double_t[] = {  {&_swigt__p_std__vectorT_double_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_int_t[] = {  {&_swigt__p_std__vectorT_int_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_std__complexT_double_t_t[] = {  {&_swigt__p_std__vectorT_std__complexT_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
@@ -73936,6 +74243,7 @@ static swig_cast_info _swigc__p_std__vectorT_std__pairT_double_double_t_t[] = {
 static swig_cast_info _swigc__p_std__vectorT_std__string_t[] = {  {&_swigt__p_std__vectorT_std__string_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_std__vectorT_double_t_t[] = {  {&_swigt__p_std__vectorT_std__vectorT_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_std__vectorT_int_t_t[] = {  {&_swigt__p_std__vectorT_std__vectorT_int_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_std__allocatorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_t_t[] = {  {&_swigt__p_std__vectorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_std__allocatorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_unsigned_long_t[] = {  {&_swigt__p_std__vectorT_unsigned_long_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_swig__SwigPyIterator[] = {  {&_swigt__p_swig__SwigPyIterator, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_unsigned_char[] = {  {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}};
@@ -74043,6 +74351,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_SawtoothRippleBox,
   _swigc__p_SawtoothRippleGauss,
   _swigc__p_SawtoothRippleLorentz,
+  _swigc__p_ShapeIndexes,
   _swigc__p_SimpleSelectionRule,
   _swigc__p_Span,
   _swigc__p_Sphere,
@@ -74089,6 +74398,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_std__vectorT_INode_const_p_t,
   _swigc__p_std__vectorT_ParaMeta_std__allocatorT_ParaMeta_t_t,
   _swigc__p_std__vectorT_Vec3T_double_t_t,
+  _swigc__p_std__vectorT_Vec3T_int_t_std__allocatorT_Vec3T_int_t_t_t,
   _swigc__p_std__vectorT_double_t,
   _swigc__p_std__vectorT_int_t,
   _swigc__p_std__vectorT_std__complexT_double_t_t,
@@ -74096,6 +74406,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_std__vectorT_std__string_t,
   _swigc__p_std__vectorT_std__vectorT_double_t_t,
   _swigc__p_std__vectorT_std__vectorT_int_t_t,
+  _swigc__p_std__vectorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_std__allocatorT_std__vectorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_std__allocatorT_std__vectorT_std__pairT_int_int_t_std__allocatorT_std__pairT_int_int_t_t_t_t_t_t_t,
   _swigc__p_std__vectorT_unsigned_long_t,
   _swigc__p_swig__SwigPyIterator,
   _swigc__p_unsigned_char,