From b823dff7bde4a972b27b6c6d9abc7447b7bc8bcb Mon Sep 17 00:00:00 2001
From: Meixner <andre.meixner@kit.edu>
Date: Wed, 27 Nov 2024 11:49:30 +0100
Subject: [PATCH] Updated ArvizProfileManager

---
 .../ArViz/ArVizWidgetController.cpp           |  19 +-
 .../gui-plugins/ArViz/ArVizWidgetController.h |   4 +-
 .../ArViz/ArvizProfileManagerWidget.cpp       | 288 ++++++++++++++++++
 .../ArViz/ArvizProfileManagerWidget.h         | 138 +++++++++
 .../RobotAPI/gui-plugins/ArViz/CMakeLists.txt |   4 +-
 .../ArViz/HiddenCoinLayerManagerWidget.cpp    | 153 ----------
 .../ArViz/HiddenCoinLayerManagerWidget.h      |  92 ------
 7 files changed, 440 insertions(+), 258 deletions(-)
 create mode 100644 source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.cpp
 create mode 100644 source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h
 delete mode 100644 source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.cpp
 delete mode 100644 source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.h

diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
index 1633da37a..d7d1680c5 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
@@ -23,6 +23,7 @@
 #include "ArVizWidgetController.h"
 
 #include <ArmarXCore/observers/variant/Variant.h>
+#include "RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h"
 
 #include <SimoxUtility/algorithm/string/string_tools.h>
 
@@ -93,9 +94,9 @@ namespace armarx
         connect(this, &This::connectGui, this, &This::onConnectGui, Qt::QueuedConnection);
         connect(this, &This::disconnectGui, this, &This::onDisconnectGui, Qt::QueuedConnection);
 
-        hiddenCoinLayerWidget = new HiddenCoinLayerManagerWidget();
-        widget.verticalLayout->addWidget(hiddenCoinLayerWidget);
-        connect(hiddenCoinLayerWidget, &HiddenCoinLayerManagerWidget::hiddenLayersReset, this, &This::updateHiddenLayers);
+        arvizeProfileLayerWidget = new ArvizProfileManagerWidget();
+        widget.verticalLayout->addWidget(arvizeProfileLayerWidget);
+        connect(arvizeProfileLayerWidget, &ArvizProfileManagerWidget::layersReset, this, &This::updateHiddenLayers);
 
         // Layer info tree.
 
@@ -187,7 +188,7 @@ namespace armarx
                     QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
                     const std::string layer = layerItem->text(0).toStdString();
                     const viz::CoinLayerID layerID(component, layer);
-                    const bool visible = not hiddenCoinLayerWidget->isHidden(layerID);
+                    const bool visible = not arvizeProfileLayerWidget->isHidden(layerID);
                     layerItem->setCheckState(0, visible ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
                     parentChecked &= visible;
                     visualizer.showLayer(layerID, visible);
@@ -235,7 +236,7 @@ namespace armarx
                     {
                         layerItem->setCheckState(0, componentCheck);
                     }
-                    hiddenCoinLayerWidget->update(component, componentCheck == Qt::Checked);
+                    arvizeProfileLayerWidget->update(component, componentCheck == Qt::Checked);
                 }
                 return;
             }
@@ -249,7 +250,7 @@ namespace armarx
 
                 viz::CoinLayerID layerID(component, layer);
 
-                hiddenCoinLayerWidget->update(layerID, layerVisible);
+                arvizeProfileLayerWidget->update(layerID, layerVisible);
 
                 visualizer.showLayer(layerID, layerVisible);
             }
@@ -297,7 +298,7 @@ namespace armarx
                     // Create a new item
                     currentItem = new QTreeWidgetItem(tree);
                     currentItem->setText(0, QString::fromStdString(component));
-                    currentItem->setCheckState(0, hiddenCoinLayerWidget->isHidden(entry) ? Qt::Unchecked : Qt::Checked);
+                    currentItem->setCheckState(0, arvizeProfileLayerWidget->isHidden(entry) ? Qt::Unchecked : Qt::Checked);
 
                     componentWasNew = true;
                 }
@@ -319,7 +320,7 @@ namespace armarx
                 std::string const& layer = entry.second;
                 QTreeWidgetItem* layerItem = new QTreeWidgetItem;
                 layerItem->setText(0, QString::fromStdString(layer));
-                layerItem->setCheckState(0, hiddenCoinLayerWidget->isHidden(entry) ? Qt::Unchecked : Qt::Checked);
+                layerItem->setCheckState(0, arvizeProfileLayerWidget->isHidden(entry) ? Qt::Unchecked : Qt::Checked);
 
                 if (currentItem)
                 {
@@ -341,7 +342,7 @@ namespace armarx
             else
             {
                 // Item exists already ==> make sure that it is not shown if necessary
-                if (hiddenCoinLayerWidget->isHidden(iter->first) or iter->second->checkState(0) == Qt::Unchecked)
+                if (arvizeProfileLayerWidget->isHidden(iter->first) or iter->second->checkState(0) == Qt::Unchecked)
                 {
                     visualizer.showLayer(iter->first, false);
                 }
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
index d81dc69bc..783ff4bcd 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
@@ -36,7 +36,7 @@
 #include <ArmarXCore/core/system/ImportExportComponent.h>
 
 #include "LayerInfoTree.h"
-#include "HiddenCoinLayerManagerWidget.h"
+#include "ArvizProfileManagerWidget.h"
 
 
 namespace armarx
@@ -228,7 +228,7 @@ namespace armarx
 
         std::vector<double> timings;
 
-        HiddenCoinLayerManagerWidget* hiddenCoinLayerWidget;
+        ArvizProfileManagerWidget* arvizeProfileLayerWidget;
 
     public:
         static QIcon GetWidgetIcon()
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.cpp b/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.cpp
new file mode 100644
index 000000000..e060e715c
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.cpp
@@ -0,0 +1,288 @@
+#include "ArvizProfileManagerWidget.h"
+#include <string>
+
+
+#include <QVBoxLayout>
+#include <QMessageBox>
+#include <QBoxLayout>
+#include <QLabel>
+#include <QFormLayout>
+#include <QDialogButtonBox>
+#include <QPushButton>
+#include <qboxlayout.h>
+#include <qchar.h>
+#include <qradiobutton.h>
+
+#include <ArmarXCore/core/system/ArmarXDataPath.h>
+#include <ArmarXCore/core/logging/Logging.h>
+
+namespace armarx
+{
+
+ProfileDialog::ProfileDialog(QWidget *parent, const QString &name, bool additive, bool addDialog)
+    : QDialog(parent)
+{
+    setWindowTitle(addDialog ? "Add Profile" : "Edit Profile");
+
+    // Set up UI components
+    nameInput = new QLineEdit(this);
+    nameInput->setText(name);
+
+    additiveRadioButton = new QRadioButton("Save added layers", this);
+    additiveRadioButton->setChecked(additive);
+    substractiveRadioButton = new QRadioButton("Save removed layers", this);
+    substractiveRadioButton->setChecked(not additive);
+
+    // Save/Cancel buttons
+    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel, this);
+    connect(buttonBox, &QDialogButtonBox::accepted, this, &ProfileDialog::accept);
+    connect(buttonBox, &QDialogButtonBox::rejected, this, &ProfileDialog::reject);
+
+    // Delete button
+    deleteButton = new QPushButton("Delete", this);
+    connect(deleteButton, &QPushButton::clicked, this, &ProfileDialog::deleteProfile);
+
+    // Layouts
+    QFormLayout *formLayout = new QFormLayout;
+    formLayout->addRow("Profile Name:", nameInput);
+    formLayout->addRow(additiveRadioButton);
+    formLayout->addRow(substractiveRadioButton);
+
+    QHBoxLayout *mainLayout = new QHBoxLayout;
+    mainLayout->addLayout(formLayout);
+    mainLayout->addWidget(buttonBox);
+    mainLayout->addWidget(deleteButton);
+
+    setLayout(mainLayout);
+}
+
+ProfileDialog::~ProfileDialog()
+{
+}
+
+QString ProfileDialog::getName() const
+{
+    return nameInput->text();
+}
+
+bool ProfileDialog::isAdditive() const
+{
+    return additiveRadioButton->isChecked();
+}
+
+void ProfileDialog::deleteProfile()
+{
+    // Handle the profile deletion
+    emit deleteProfileSignal();
+    reject(); // Close the dialog after deletion
+}
+
+
+
+ArvizProfileManagerWidget::ArvizProfileManagerWidget(QWidget* parent) :
+    QWidget(parent), 
+    settings(QString((armarx::ArmarXDataPath::GetDefaultUserConfigPath() + "/ArvizProfileManager.conf").c_str()),
+             QSettings::NativeFormat),
+    currentProfile(Profile())
+{
+    QHBoxLayout* layout = new QHBoxLayout(this);
+
+    // Setup UI elements
+    layersComboBox = new QComboBox(this);
+    connect(layersComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), 
+           this, &ArvizProfileManagerWidget::onLayersSelected);
+
+    addButton = new QPushButton("Add", this);
+    editButton = new QPushButton("Edit", this);
+    saveButton = new QPushButton("Save", this);
+
+    layout->addWidget(new QLabel("Arviz Profile: "));
+    layout->addWidget(layersComboBox);
+    layout->addWidget(addButton);
+    layout->addWidget(editButton);
+    layout->addWidget(saveButton);
+
+    setLayout(layout);
+
+    connect(addButton, &QPushButton::clicked, this, &ArvizProfileManagerWidget::addProfile);
+    connect(editButton, &QPushButton::clicked, this, &ArvizProfileManagerWidget::editProfile);
+    connect(saveButton, &QPushButton::clicked, this, &ArvizProfileManagerWidget::saveCurrentLayers);
+
+    loadLayerNames();
+}
+
+void ArvizProfileManagerWidget::onLayersSelected(int index) 
+{
+    const QString name = layersComboBox->currentText();
+
+    loadProfile(name);
+    emit layersReset();
+}
+
+void ArvizProfileManagerWidget::saveCurrentLayers() 
+{
+    const QString name = layersComboBox->currentText();
+    if (name.isEmpty()) 
+    {
+        QMessageBox::warning(this, "Warning", "Please enter a valid name.");
+        return;
+    }
+
+    if (saveProfile(name, currentProfile)) 
+    {
+        if (layersComboBox->findText(name) == -1) 
+        {
+            layersComboBox->addItem(name);
+        }
+        layersComboBox->setCurrentText(name);
+    }
+}
+
+void ArvizProfileManagerWidget::deleteCurrentLayersSave() 
+{
+    const QString name = layersComboBox->currentText();
+    settings.remove(name);
+
+    const int index = layersComboBox->currentIndex();
+    layersComboBox->removeItem(index);
+    settings.remove(name);
+
+    if (layersComboBox->count() == 0)
+    {
+        editButton->setDisabled(true);
+        saveButton->setDisabled(true);
+    }
+
+    emit layersReset();
+}
+
+void ArvizProfileManagerWidget::addProfile() 
+{
+    if (dialog == nullptr || !dialog->isVisible()) 
+    {
+        const QString defaultName = "Profile";
+        const bool defaultAdditive = false;
+        QString name = defaultName;
+        unsigned int counter = 2;
+        while (layersComboBox->count() > 0 and layersComboBox->findText(name) >= 0)
+        {
+            name = defaultName + QString::fromStdString(std::to_string(counter++));
+        }
+        dialog = new ProfileDialog(this, name, defaultAdditive, true);
+        const int result = dialog->exec();
+
+        if (result == QDialog::Accepted) 
+        {
+            if (layersComboBox->findText(dialog->getName()) >= 0)
+            {
+                ARMARX_WARNING << "Profile with name " << dialog->getName().toStdString() << " already exists!";
+                return;
+            }
+            currentProfile.layers = {};
+            currentProfile.additive = dialog->isAdditive();
+            saveProfile(dialog->getName(), currentProfile);
+            loadLayerNames();
+
+            layersComboBox->setCurrentText(dialog->getName());
+            onLayersSelected(0);
+        } 
+        else 
+        {
+            // do nothing
+        }
+    } 
+    else 
+    {
+        QMessageBox::information(this, "Dialog Already Open", "The dialog is already open.");
+    }
+}
+
+void ArvizProfileManagerWidget::editProfile()
+{
+    if (layersComboBox->count() > 0)
+    {
+        if (dialog == nullptr || !dialog->isVisible()) 
+        {
+            dialog = new ProfileDialog(this, layersComboBox->currentText(), currentProfile.additive, false);
+            connect(dialog, &ProfileDialog::deleteProfileSignal, this, &ArvizProfileManagerWidget::deleteCurrentLayersSave);
+            const int result = dialog->exec();
+
+            if (result == QDialog::Accepted) 
+            {
+                currentProfile.additive = dialog->isAdditive();
+                settings.remove(layersComboBox->currentText());
+                saveProfile(dialog->getName(), currentProfile);
+                loadLayerNames();
+                layersComboBox->setCurrentText(dialog->getName());
+                emit layersReset();
+            } 
+            else 
+            {
+                // do nothing
+            }
+        } 
+        else 
+        {
+            QMessageBox::information(this, "Dialog Already Open", "The dialog is already open.");
+        }
+    }
+}
+
+void ArvizProfileManagerWidget::loadLayerNames() 
+{
+    layersComboBox->clear();
+    for (const QString& groups : settings.childGroups()) 
+    {
+        layersComboBox->addItem(groups);
+    }
+    if (layersComboBox->count() == 0)
+    {
+        editButton->setDisabled(true);
+        saveButton->setDisabled(true);
+    }
+    else 
+    {
+        editButton->setEnabled(true);
+        saveButton->setEnabled(true);
+    }
+}
+
+void ArvizProfileManagerWidget::loadProfile(const QString& name)
+{
+    std::scoped_lock lock(mtx);
+    currentProfile.layers.clear();
+    
+    settings.beginGroup(name);
+    currentProfile.additive  = settings.value("additive").toBool();
+    const int size = settings.beginReadArray("layers");
+    for (int i = 0; i < size; ++i) 
+    {
+        settings.setArrayIndex(i);
+        QString first = settings.value("component").toString();
+        QString second = settings.value("layer").toString();
+        currentProfile.layers.insert({first.toStdString(), second.toStdString()});
+    }
+    settings.endArray();
+    settings.endGroup();
+    editButton->setEnabled(true);
+}
+
+bool ArvizProfileManagerWidget::saveProfile(const QString& name, const Profile& profile) 
+{
+    settings.beginGroup(name);
+    settings.setValue("additive", profile.additive);
+    settings.remove("layers");
+    settings.beginWriteArray("layers", profile.layers.size());
+    int i = 0;
+    for (const auto& pair : profile.layers)
+    {
+        settings.setArrayIndex(i++);
+        settings.setValue("component", QString::fromStdString(pair.first));
+        settings.setValue("layer", QString::fromStdString(pair.second));
+    }
+    settings.endArray();
+    settings.endGroup();
+    return true;
+}
+
+}
\ No newline at end of file
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h b/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h
new file mode 100644
index 000000000..b7924a97a
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h
@@ -0,0 +1,138 @@
+#pragma once
+
+#include <QWidget>
+#include <QDialog>
+#include <QComboBox>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QSettings>
+#include <QString>
+#include <QCheckBox>
+#include <qradiobutton.h>
+
+#include <mutex>
+#include <unordered_set>
+#include <string>
+#include <utility>
+
+#include <RobotAPI/components/ArViz/Coin/Visualizer.h>
+
+namespace armarx
+{
+    struct pair_hash 
+    {
+        template <typename T1, typename T2>
+        std::size_t operator ()(const std::pair<T1, T2>& p) const 
+        {
+            auto h1 = std::hash<T1>{}(p.first);
+            auto h2 = std::hash<T2>{}(p.second);
+            return h1 ^ (h2 << 1);
+        }
+    };
+
+    using Layers = std::unordered_set<viz::CoinLayerID, pair_hash>;
+
+    struct Profile
+    {
+        Layers layers;
+        bool additive = false;
+    };
+
+
+    class ProfileDialog : public QDialog
+    {
+        Q_OBJECT
+
+    public:
+        explicit ProfileDialog(QWidget *parent = nullptr, const QString &name = "", bool additive = false, bool addDialog = true);
+        ~ProfileDialog();
+
+        QString getName() const;
+        bool isAdditive() const;
+
+    signals:
+        void deleteProfileSignal();
+
+    private slots:
+        void deleteProfile();
+
+    private:
+        QLineEdit *nameInput;
+        QRadioButton *additiveRadioButton;
+        QRadioButton *substractiveRadioButton;
+        QPushButton *deleteButton;
+    };
+
+
+    class ArvizProfileManagerWidget : public QWidget 
+    {
+        Q_OBJECT
+
+    public:
+        explicit ArvizProfileManagerWidget(QWidget* parent = nullptr);
+
+        inline void update(const viz::CoinLayerID& layerID, bool visible)
+        {
+            std::scoped_lock lock(mtx);
+
+            if (visible and currentProfile.layers.count(layerID) > 0)
+            {
+                currentProfile.layers.erase(layerID);
+                currentProfile.layers.erase({layerID.first, "*"});
+            }
+            else if (not visible)
+            {
+                currentProfile.layers.insert(layerID);
+            }
+        }
+
+        inline void update(const std::string& componentName, bool visible)
+        {
+            update({componentName, "*"}, visible);
+        }
+
+        inline bool isHidden(const viz::CoinLayerID& layerID) const
+        {
+            std::scoped_lock lock(mtx);
+
+            const bool result = currentProfile.layers.count(layerID) > 0 or currentProfile.layers.count({layerID.first, "*"}) > 0;
+
+            if (currentProfile.additive)
+            {
+                return not result;
+            }
+            else 
+            {
+                return result;
+            }
+        }
+
+    signals:
+        // Signal emitted when the saveLayer is reset (reselected)
+        void layersReset();
+
+    private slots:
+        void onLayersSelected(int index);
+        void saveCurrentLayers();
+        void deleteCurrentLayersSave();
+
+        void addProfile();
+        void editProfile();
+
+    private:
+        void loadLayerNames();
+        void loadProfile(const QString& name);
+        bool saveProfile(const QString& name, const Profile& profile);
+
+        ProfileDialog* dialog = nullptr;
+        QComboBox* layersComboBox;
+        QPushButton* addButton;
+        QPushButton* editButton;
+        QPushButton* saveButton;
+        QSettings settings;
+        mutable std::mutex mtx;
+
+        Profile currentProfile;
+    };
+
+}
\ No newline at end of file
diff --git a/source/RobotAPI/gui-plugins/ArViz/CMakeLists.txt b/source/RobotAPI/gui-plugins/ArViz/CMakeLists.txt
index 318b4d9bd..94928007f 100644
--- a/source/RobotAPI/gui-plugins/ArViz/CMakeLists.txt
+++ b/source/RobotAPI/gui-plugins/ArViz/CMakeLists.txt
@@ -10,7 +10,7 @@ armarx_build_if(ArmarXGui_FOUND "ArmarXGui not available")
 set(SOURCES
     ArVizGuiPlugin.cpp
     ArVizWidgetController.cpp
-    HiddenCoinLayerManagerWidget.cpp
+    ArvizProfileManagerWidget.cpp
 
     LayerInfoTree.cpp
 )
@@ -19,7 +19,7 @@ set(SOURCES
 set(HEADERS
     ArVizGuiPlugin.h
     ArVizWidgetController.h
-    HiddenCoinLayerManagerWidget.h
+    ArvizProfileManagerWidget.h
 
     LayerInfoTree.h
 )
diff --git a/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.cpp b/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.cpp
deleted file mode 100644
index 95ca8de3d..000000000
--- a/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-#include "HiddenCoinLayerManagerWidget.h"
-
-#include <ArmarXCore/core/logging/Logging.h>
-#include <QVBoxLayout>
-#include <QMessageBox>
-
-#include <ArmarXCore/core/system/ArmarXDataPath.h>
-#include <qboxlayout.h>
-#include <qlabel.h>
-
-namespace armarx
-{
-
-HiddenCoinLayerManagerWidget::HiddenCoinLayerManagerWidget(QWidget* parent) :
-    QWidget(parent), 
-    settings(QString((armarx::ArmarXDataPath::GetDefaultUserConfigPath() + "/ArvizHiddenCoinLayerManager.conf").c_str()),
-             QSettings::NativeFormat),
-    hiddenLayers(HiddenLayers{})
-{
-    QHBoxLayout* layout = new QHBoxLayout(this);
-
-    // Setup UI elements
-    hiddenLayersComboBox = new QComboBox(this);
-    hiddenLayersComboBox->addItem("default");
-    connect(hiddenLayersComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), 
-           this, &HiddenCoinLayerManagerWidget::onHiddenLayersSelected);
-
-    nameEdit = new QLineEdit(this);
-    saveButton = new QPushButton("Save", this);
-    deleteButton = new QPushButton("Delete", this);
-
-    layout->addWidget(new QLabel("Arviz Layer Saves: "));
-    layout->addWidget(hiddenLayersComboBox);
-    layout->addWidget(nameEdit);
-    layout->addWidget(saveButton);
-    layout->addWidget(deleteButton);
-    setLayout(layout);
-
-    connect(saveButton, &QPushButton::clicked, this, &HiddenCoinLayerManagerWidget::saveCurrentHiddenLayers);
-    connect(deleteButton, &QPushButton::clicked, this, &HiddenCoinLayerManagerWidget::deleteCurrentHiddenLayersSave);
-
-    loadHiddenLayerNames();
-    loadDefaultHiddenLayer();
-}
-
-void HiddenCoinLayerManagerWidget::onHiddenLayersSelected(int index) 
-{
-    const QString name = hiddenLayersComboBox->currentText();
-
-    loadHiddenLayers(name);
-    emit hiddenLayersReset();
-}
-
-void HiddenCoinLayerManagerWidget::saveCurrentHiddenLayers() 
-{
-    const QString name = nameEdit->text();
-    if (name.isEmpty() or name == "default") 
-    {
-        QMessageBox::warning(this, "Warning", "Please enter a valid name.");
-        return;
-    }
-
-    if (saveHiddenLayers(name, hiddenLayers)) 
-    {
-        if (hiddenLayersComboBox->findText(name) == -1) 
-        {
-            hiddenLayersComboBox->addItem(name);
-        }
-        hiddenLayersComboBox->setCurrentText(name);
-    }
-}
-
-void HiddenCoinLayerManagerWidget::deleteCurrentHiddenLayersSave() 
-{
-    const QString name = hiddenLayersComboBox->currentText();
-    if (name == "default") 
-    {
-        QMessageBox::warning(this, "Warning", "Cannot delete the default.");
-        return;
-    }
-
-    settings.remove(name);
-
-    int index = hiddenLayersComboBox->currentIndex();
-    hiddenLayersComboBox->removeItem(index);
-    loadDefaultHiddenLayer();
-    emit hiddenLayersReset();
-}
-
-void HiddenCoinLayerManagerWidget::loadHiddenLayerNames() 
-{
-    for (const QString& groups : settings.childGroups()) 
-    {
-        hiddenLayersComboBox->addItem(groups);
-    }
-}
-
-void HiddenCoinLayerManagerWidget::loadDefaultHiddenLayer() 
-{
-    hiddenLayersComboBox->setCurrentText("default");
-    hiddenLayers.clear();
-}
-
-void HiddenCoinLayerManagerWidget::loadHiddenLayers(const QString& name)
-{
-    std::scoped_lock lock(mtx);
-    hiddenLayers.clear();
-    
-    if (name != "default")
-    {
-        settings.beginGroup(name);
-        const int size = settings.beginReadArray("layers");
-        for (int i = 0; i < size; ++i) 
-        {
-            settings.setArrayIndex(i);
-            QString first = settings.value("component").toString();
-            QString second = settings.value("layer").toString();
-            hiddenLayers.insert({first.toStdString(), second.toStdString()});
-        }
-        settings.endArray();
-        settings.endGroup();
-
-        nameEdit->setText(name);
-        deleteButton->setEnabled(true);
-    }
-    else 
-    {
-        deleteButton->setEnabled(false);
-    }
-}
-
-bool HiddenCoinLayerManagerWidget::saveHiddenLayers(const QString& name, const HiddenLayers& hiddenLayers) 
-{
-    if (name != "default")
-    {
-        settings.beginGroup(name);
-        settings.remove("layers");
-        settings.beginWriteArray("layers", hiddenLayers.size());
-        int i = 0;
-        for (const auto& pair : hiddenLayers)
-        {
-            settings.setArrayIndex(i++);
-            settings.setValue("component", QString::fromStdString(pair.first));
-            settings.setValue("layer", QString::fromStdString(pair.second));
-        }
-        settings.endArray();
-        settings.endGroup();
-        return true;
-    }
-    return false;
-}
-
-}
\ No newline at end of file
diff --git a/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.h b/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.h
deleted file mode 100644
index f10140d09..000000000
--- a/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#pragma once
-
-#include <QWidget>
-#include <QComboBox>
-#include <QPushButton>
-#include <QLineEdit>
-#include <QSettings>
-#include <QString>
-
-#include <mutex>
-#include <qobjectdefs.h>
-#include <shared_mutex>
-#include <unordered_set>
-#include <string>
-#include <utility>
-
-#include <RobotAPI/components/ArViz/Coin/Visualizer.h>
-
-namespace armarx
-{
-    struct pair_hash 
-    {
-        template <typename T1, typename T2>
-        std::size_t operator ()(const std::pair<T1, T2>& p) const 
-        {
-            auto h1 = std::hash<T1>{}(p.first);
-            auto h2 = std::hash<T2>{}(p.second);
-            return h1 ^ (h2 << 1);
-        }
-    };
-
-    using HiddenLayers = std::unordered_set<viz::CoinLayerID, pair_hash>;
-
-    class HiddenCoinLayerManagerWidget : public QWidget 
-    {
-        Q_OBJECT
-
-    public:
-        explicit HiddenCoinLayerManagerWidget(QWidget* parent = nullptr);
-
-        inline void update(const viz::CoinLayerID& layerID, bool visible)
-        {
-            std::scoped_lock lock(mtx);
-
-            if (visible and hiddenLayers.count(layerID) > 0)
-            {
-                hiddenLayers.erase(layerID);
-                hiddenLayers.erase({layerID.first, "*"});
-            }
-            else if (not visible)
-            {
-                hiddenLayers.insert(layerID);
-            }
-        }
-
-        inline void update(const std::string& componentName, bool visible)
-        {
-            update({componentName, "*"}, visible);
-        }
-
-        inline bool isHidden(const viz::CoinLayerID& layerID) const
-        {
-            std::scoped_lock lock(mtx);
-
-            return hiddenLayers.count(layerID) > 0 or hiddenLayers.count({layerID.first, "*"}) > 0;
-        }
-
-    signals:
-        // Signal emitted when the saveHiddenLayer is reset (reselected)
-        void hiddenLayersReset();
-
-    private slots:
-        void onHiddenLayersSelected(int index);
-        void saveCurrentHiddenLayers();
-        void deleteCurrentHiddenLayersSave();
-
-    private:
-        void loadHiddenLayerNames();
-        void loadDefaultHiddenLayer();
-        void loadHiddenLayers(const QString& name);
-        bool saveHiddenLayers(const QString& name, const HiddenLayers& hiddenLayers);
-
-        QComboBox* hiddenLayersComboBox;
-        QLineEdit* nameEdit;
-        QPushButton* saveButton;
-        QPushButton* deleteButton;
-        QSettings settings;
-        mutable std::mutex mtx;
-        HiddenLayers hiddenLayers;
-    };
-
-}
\ No newline at end of file
-- 
GitLab