From 566b4c6eb06b0ccfa79bb21981a6eade46c02d81 Mon Sep 17 00:00:00 2001
From: Fabian Paus <fabian.paus@kit.edu>
Date: Mon, 14 Oct 2019 14:42:27 +0200
Subject: [PATCH] Fix layer selection

---
 .../components/ArVizExample/ArVizExample.cpp  | 397 +++++++++---------
 .../ArViz/ArVizWidgetController.cpp           |  84 ++--
 2 files changed, 261 insertions(+), 220 deletions(-)

diff --git a/source/RobotAPI/components/ArVizExample/ArVizExample.cpp b/source/RobotAPI/components/ArVizExample/ArVizExample.cpp
index 80a2202ca..a7df9fd38 100644
--- a/source/RobotAPI/components/ArVizExample/ArVizExample.cpp
+++ b/source/RobotAPI/components/ArVizExample/ArVizExample.cpp
@@ -90,228 +90,235 @@ void ArVizExample::update()
     {
         double timeInSeconds = TimeUtil::GetTime().toSecondsDouble();
 
-        viz::LayerUpdate layer;
-        layer.component = getName();
-        layer.name = "Example";
-#if 0
-#endif
-        {
-            viz::ElementBoxPtr box(new viz::ElementBox);
-            box->id = "box";
-            box->action = viz::Element_UPDATE;
-
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.x() = 100.0f * std::sin(timeInSeconds);
-            box->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
-            box->color = armarx::viz::Color{255, 255, 0, 0};
-            box->size = frost(Eigen::Vector3f(100.0f, 100.0f, 100.0f));
-
-            layer.elements.push_back(box);
-        }
         {
-            viz::ElementCylinderPtr cyl(new viz::ElementCylinder);
-            cyl->id = "cylinder";
-            cyl->action = viz::Element_UPDATE;
-
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.y() = 100.0f * std::sin(timeInSeconds);
-            pos.x() = 150.0f;
-            cyl->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
-            cyl->color = armarx::viz::Color{255, 0, 255, 0};
-            cyl->radius = 50.0f;
-            cyl->height = 100.0f;
-
-            layer.elements.push_back(cyl);
-        }
+            viz::LayerUpdate layer;
+            layer.component = getName();
+            layer.name = "Test";
 
-        {
-            viz::ElementPosePtr pose(new viz::ElementPose);
-            pose->id = "pose";
-            pose->action = viz::Element_UPDATE;
-
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.z() = 100.0f * std::sin(timeInSeconds);
-            pos.x() = -150.0f;
-            pose->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
-            pose->color = armarx::viz::Color{255, 0, 0, 0};
-            pose->scale = 1.0f;
-
-            layer.elements.push_back(pose);
-        }
-        {
-            viz::ElementTextPtr text(new viz::ElementText);
-            text->id = "text";
-            text->action = viz::Element_UPDATE;
+            {
+                viz::ElementBoxPtr box(new viz::ElementBox);
+                box->id = "box";
+                box->action = viz::Element_UPDATE;
 
-            text->text = "Test Text";
-            text->scale = 4.0f;
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.x() = 100.0f * std::sin(timeInSeconds);
+                box->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
+                box->color = armarx::viz::Color{255, 255, 0, 0};
+                box->size = frost(Eigen::Vector3f(100.0f, 100.0f, 100.0f));
 
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.z() = +300.0f;
-            text->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
-            text->color = armarx::viz::Color{255, 0, 0, 0};
+                layer.elements.push_back(box);
+            }
+            {
+                viz::ElementCylinderPtr cyl(new viz::ElementCylinder);
+                cyl->id = "cylinder";
+                cyl->action = viz::Element_UPDATE;
+
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.y() = 100.0f * std::sin(timeInSeconds);
+                pos.x() = 150.0f;
+                cyl->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
+                cyl->color = armarx::viz::Color{255, 0, 255, 0};
+                cyl->radius = 50.0f;
+                cyl->height = 100.0f;
+
+                layer.elements.push_back(cyl);
+            }
 
-            layer.elements.push_back(text);
-        }
-        {
-            viz::ElementArrowPtr arrow(new viz::ElementArrow);
-            arrow->id = "arrow";
-            arrow->action = viz::Element_UPDATE;
-
-            float modTime = std::fmod(timeInSeconds, 2.0 * M_PI);
-            arrow->length = 200.0f + 100.0f * std::sin(modTime);
-
-            Eigen::AngleAxisf dirRot(modTime, Eigen::Vector3f::UnitZ());
-            Eigen::Vector3f direction = dirRot * Eigen::Vector3f::UnitX();
-            // Calculate rotation to achieve direction
-            Eigen::Vector3f naturalDir = Eigen::Vector3f::UnitY();
-            Eigen::Vector3f cross = naturalDir.cross(direction);
-            float angle = std::acos(naturalDir.dot(direction));
-            if (cross.squaredNorm() < 1.0e-12)
             {
-                // Directions are almost colinear ==> Do no rotation
-                cross = Eigen::Vector3f::UnitX();
-                angle = 0.0f;
+                viz::ElementPosePtr pose(new viz::ElementPose);
+                pose->id = "pose";
+                pose->action = viz::Element_UPDATE;
+
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.z() = 100.0f * std::sin(timeInSeconds);
+                pos.x() = -150.0f;
+                pose->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
+                pose->color = armarx::viz::Color{255, 0, 0, 0};
+                pose->scale = 1.0f;
+
+                layer.elements.push_back(pose);
             }
-            Eigen::Vector3f axis = cross.normalized();
-            Eigen::Quaternionf ori(Eigen::AngleAxisf(angle, axis));
+            {
+                viz::ElementTextPtr text(new viz::ElementText);
+                text->id = "text";
+                text->action = viz::Element_UPDATE;
+
+                text->text = "Test Text";
+                text->scale = 4.0f;
 
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.z() = +300.0f;
-            pos.x() = -500.0f;
-            arrow->pose = makeGlobalPose(pos, ori);
-            arrow->color = armarx::viz::Color{255, 0, 0, 255};
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.z() = +300.0f;
+                text->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
+                text->color = armarx::viz::Color{255, 0, 0, 0};
 
-            layer.elements.push_back(arrow);
+                layer.elements.push_back(text);
+            }
+            {
+                viz::ElementArrowPtr arrow(new viz::ElementArrow);
+                arrow->id = "arrow";
+                arrow->action = viz::Element_UPDATE;
+
+                float modTime = std::fmod(timeInSeconds, 2.0 * M_PI);
+                arrow->length = 200.0f + 100.0f * std::sin(modTime);
+
+                Eigen::AngleAxisf dirRot(modTime, Eigen::Vector3f::UnitZ());
+                Eigen::Vector3f direction = dirRot * Eigen::Vector3f::UnitX();
+                // Calculate rotation to achieve direction
+                Eigen::Vector3f naturalDir = Eigen::Vector3f::UnitY();
+                Eigen::Vector3f cross = naturalDir.cross(direction);
+                float angle = std::acos(naturalDir.dot(direction));
+                if (cross.squaredNorm() < 1.0e-12)
+                {
+                    // Directions are almost colinear ==> Do no rotation
+                    cross = Eigen::Vector3f::UnitX();
+                    angle = 0.0f;
+                }
+                Eigen::Vector3f axis = cross.normalized();
+                Eigen::Quaternionf ori(Eigen::AngleAxisf(angle, axis));
+
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.z() = +300.0f;
+                pos.x() = -500.0f;
+                arrow->pose = makeGlobalPose(pos, ori);
+                arrow->color = armarx::viz::Color{255, 0, 0, 255};
+
+                layer.elements.push_back(arrow);
+            }
+            topic->updateLayers({layer});
         }
         {
-            viz::ElementArrowCirclePtr circle(new viz::ElementArrowCircle);
-            circle->id = "circle";
-            circle->action = viz::Element_UPDATE;
-
-            float modTime = std::fmod(timeInSeconds, 2.0 * M_PI);
-            circle->completion = std::sin(modTime);
+            viz::LayerUpdate layer;
+            layer.component = getName();
+            layer.name = "Example";
+            {
+                viz::ElementArrowCirclePtr circle(new viz::ElementArrowCircle);
+                circle->id = "circle";
+                circle->action = viz::Element_UPDATE;
 
-            circle->radius = 100.0f;
-            circle->width = 10.0f;
+                float modTime = std::fmod(timeInSeconds, 2.0 * M_PI);
+                circle->completion = std::sin(modTime);
 
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.z() = +300.0f;
-            circle->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
-            circle->color = armarx::viz::Color{200, 255, 0, 255};
+                circle->radius = 100.0f;
+                circle->width = 10.0f;
 
-            layer.elements.push_back(circle);
-        }
-        {
-            viz::ElementPolygonPtr poly(new viz::ElementPolygon);
-            poly->id = "poly";
-            poly->action = viz::Element_UPDATE;
-
-            poly->color = armarx::viz::Color{128, 0, 128, 255};
-            poly->lineColor = {255, 0, 0, 255};
-            poly->lineWidth = 10.0f;
-
-            float t = 1.0f + std::sin(timeInSeconds);
-            float offset = 50.0f * t;
-            poly->points.push_back(armarx::Vector3f{-200.0f - offset, -200.0f - offset, 0.0f});
-            poly->points.push_back(armarx::Vector3f{-200.0f, +200.0f, 0.0f});
-            poly->points.push_back(armarx::Vector3f{+200.0f + offset, +200.0f + offset, 0.0f});
-            poly->points.push_back(armarx::Vector3f{+200.0f, -200.0f, 0.0f});
-
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.z() = +1000.0f;
-            poly->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
-
-            layer.elements.push_back(poly);
-        }
-        {
-            viz::ElementPolygonPtr poly(new viz::ElementPolygon);
-            poly->id = "poly2";
-            poly->action = viz::Element_UPDATE;
-
-            poly->color = armarx::viz::Color{128, 255, 128, 0};
-            poly->lineColor = {255, 255, 0, 0};
-            poly->lineWidth = 0.0f;
-
-            float t = 1.0f + std::sin(timeInSeconds);
-            float offset = 20.0f * t;
-            poly->points.push_back(armarx::Vector3f{-100.0f - offset, -100.0f - offset, 0.0f});
-            poly->points.push_back(armarx::Vector3f{-100.0f, +100.0f, 0.0f});
-            poly->points.push_back(armarx::Vector3f{+100.0f + offset, +100.0f + offset, 0.0f});
-            poly->points.push_back(armarx::Vector3f{+100.0f, -100.0f, 0.0f});
-
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.z() = +1500.0f;
-            poly->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
-
-            layer.elements.push_back(poly);
-        }
-        {
-            viz::ElementMeshPtr mesh(new viz::ElementMesh);
-            mesh->id = "mesh";
-            mesh->action = viz::Element_UPDATE;
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.z() = +300.0f;
+                circle->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
+                circle->color = armarx::viz::Color{200, 255, 0, 255};
 
-            armarx::Vector3f vertices[] =
+                layer.elements.push_back(circle);
+            }
             {
-                {-100.0f, -100.0f, 0.0f},
-                {-100.0f, +100.0f, 0.0f},
-                {+100.0f, +100.0f, 0.0f},
-                {+100.0f, +100.0f, 200.0f},
-            };
-            armarx::viz::Color colors[] =
+                viz::ElementPolygonPtr poly(new viz::ElementPolygon);
+                poly->id = "poly";
+                poly->action = viz::Element_UPDATE;
+
+                poly->color = armarx::viz::Color{128, 0, 128, 255};
+                poly->lineColor = {255, 0, 0, 255};
+                poly->lineWidth = 10.0f;
+
+                float t = 1.0f + std::sin(timeInSeconds);
+                float offset = 50.0f * t;
+                poly->points.push_back(armarx::Vector3f{-200.0f - offset, -200.0f - offset, 0.0f});
+                poly->points.push_back(armarx::Vector3f{-200.0f, +200.0f, 0.0f});
+                poly->points.push_back(armarx::Vector3f{+200.0f + offset, +200.0f + offset, 0.0f});
+                poly->points.push_back(armarx::Vector3f{+200.0f, -200.0f, 0.0f});
+
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.z() = +1000.0f;
+                poly->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
+
+                layer.elements.push_back(poly);
+            }
             {
-                {255, 255, 0, 0},
-                {255, 0, 255, 0},
-                {255, 0, 0, 255},
-            };
-            armarx::viz::Face faces[] =
+                viz::ElementPolygonPtr poly(new viz::ElementPolygon);
+                poly->id = "poly2";
+                poly->action = viz::Element_UPDATE;
+
+                poly->color = armarx::viz::Color{128, 255, 128, 0};
+                poly->lineColor = {255, 255, 0, 0};
+                poly->lineWidth = 0.0f;
+
+                float t = 1.0f + std::sin(timeInSeconds);
+                float offset = 20.0f * t;
+                poly->points.push_back(armarx::Vector3f{-100.0f - offset, -100.0f - offset, 0.0f});
+                poly->points.push_back(armarx::Vector3f{-100.0f, +100.0f, 0.0f});
+                poly->points.push_back(armarx::Vector3f{+100.0f + offset, +100.0f + offset, 0.0f});
+                poly->points.push_back(armarx::Vector3f{+100.0f, -100.0f, 0.0f});
+
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.z() = +1500.0f;
+                poly->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
+
+                layer.elements.push_back(poly);
+            }
             {
+                viz::ElementMeshPtr mesh(new viz::ElementMesh);
+                mesh->id = "mesh";
+                mesh->action = viz::Element_UPDATE;
+
+                armarx::Vector3f vertices[] =
                 {
-                    0, 1, 2,
-                    0, 1, 2,
-                },
+                    {-100.0f, -100.0f, 0.0f},
+                    {-100.0f, +100.0f, 0.0f},
+                    {+100.0f, +100.0f, 0.0f},
+                    {+100.0f, +100.0f, 200.0f},
+                };
+                armarx::viz::Color colors[] =
                 {
-                    1, 2, 3,
-                    0, 1, 2,
-                },
-            };
-            std::size_t verticesSize = sizeof(vertices) / sizeof(vertices[0]);
-            mesh->vertices.assign(vertices, vertices + verticesSize);
-            std::size_t colorsSize = sizeof(colors) / sizeof(colors[0]);
-            mesh->colors.assign(colors, colors + colorsSize);
-            std::size_t facesSize = sizeof(faces) / sizeof(faces[0]);
-            mesh->faces.assign(faces, faces + facesSize);
-
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.z() = +1000.0f;
-            pos.x() = -500.0f;
-            mesh->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
-
-            layer.elements.push_back(mesh);
-        }
-        {
-            viz::ElementRobotPtr robot(new viz::ElementRobot);
-            robot->id = "robot";
-            robot->action = viz::Element_UPDATE;
+                    {255, 255, 0, 0},
+                    {255, 0, 255, 0},
+                    {255, 0, 0, 255},
+                };
+                armarx::viz::Face faces[] =
+                {
+                    {
+                        0, 1, 2,
+                        0, 1, 2,
+                    },
+                    {
+                        1, 2, 3,
+                        0, 1, 2,
+                    },
+                };
+                std::size_t verticesSize = sizeof(vertices) / sizeof(vertices[0]);
+                mesh->vertices.assign(vertices, vertices + verticesSize);
+                std::size_t colorsSize = sizeof(colors) / sizeof(colors[0]);
+                mesh->colors.assign(colors, colors + colorsSize);
+                std::size_t facesSize = sizeof(faces) / sizeof(faces[0]);
+                mesh->faces.assign(faces, faces + facesSize);
+
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.z() = +1000.0f;
+                pos.x() = -500.0f;
+                mesh->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
+
+                layer.elements.push_back(mesh);
+            }
+            {
+                viz::ElementRobotPtr robot(new viz::ElementRobot);
+                robot->id = "robot";
+                robot->action = viz::Element_UPDATE;
 
-            robot->project = "Armar6RT";
-            robot->filename = "Armar6RT/robotmodel/Armar6-SH/Armar6-SH.xml";
+                robot->project = "Armar6RT";
+                robot->filename = "Armar6RT/robotmodel/Armar6-SH/Armar6-SH.xml";
 
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.x() = 500.0f;
-            robot->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
+                Eigen::Vector3f pos = Eigen::Vector3f::Zero();
+                pos.x() = 500.0f;
+                robot->pose = makeGlobalPose(pos, Eigen::Quaternionf::Identity());
 
-            float value = 0.5f * (1.0f + std::sin(timeInSeconds));
-            robot->jointValues["ArmR2_Sho1"] = value;
-            robot->jointValues["ArmR3_Sho2"] = value;
+                float value = 0.5f * (1.0f + std::sin(timeInSeconds));
+                robot->jointValues["ArmR2_Sho1"] = value;
+                robot->jointValues["ArmR3_Sho2"] = value;
 
-            //robot->drawStyle = viz::ModelDrawStyle_FULL_MODEL;
-            robot->color = armarx::viz::Color{255, 128, 128, 255};
+                //robot->drawStyle = viz::ModelDrawStyle_FULL_MODEL;
+                robot->color = armarx::viz::Color{255, 128, 128, 255};
 
-            layer.elements.push_back(robot);
+                layer.elements.push_back(robot);
+            }
+            topic->updateLayers({layer});
         }
 
-        topic->updateLayers({layer});
 
         c.waitForCycleDuration();
     }
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
index a8716ed3f..df517e280 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
@@ -78,18 +78,21 @@ void armarx::ArVizWidgetController::onDisconnectComponent()
 void ArVizWidgetController::layerTreeChanged(QTreeWidgetItem* item, int /*column*/)
 {
     // Iterate over all items and activate/deactivate layers accordingly
-    for (QTreeWidgetItemIterator compIter(widget.layerTree); *compIter; ++compIter)
+    int componentCount = widget.layerTree->topLevelItemCount();
+    for (int compIndex = 0; compIndex < componentCount; ++compIndex)
     {
-        QTreeWidgetItem* componentItem = *compIter;
+        QTreeWidgetItem* componentItem = widget.layerTree->topLevelItem(compIndex);
         std::string component = componentItem->text(0).toStdString();
         Qt::CheckState componentCheck = componentItem->checkState(0);
+        int layerCount = componentItem->childCount();
 
         if (componentItem == item)
         {
             // The parent was selected or deselected, so all children should be set accordingly
-            for (QTreeWidgetItemIterator layerIter(componentItem); *layerIter; ++layerIter)
+            ARMARX_VERBOSE << "Setting all children of " << component << " to " << (componentCheck == Qt::Checked);
+            for (int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
             {
-                QTreeWidgetItem* layerItem = *layerIter;
+                QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
                 if (layerItem->checkState(0) != componentCheck)
                 {
                     layerItem->setCheckState(0, componentCheck);
@@ -98,16 +101,15 @@ void ArVizWidgetController::layerTreeChanged(QTreeWidgetItem* item, int /*column
             return;
         }
 
-        for (QTreeWidgetItemIterator layerIter(componentItem); *layerIter; ++layerIter)
+        for (int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
         {
-            QTreeWidgetItem* layerItem = *layerIter;
+            QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
             std::string layer = layerItem->text(0).toStdString();
             bool layerVisible = (layerItem->checkState(0) == Qt::Checked);
-
-            bool visible = layerVisible;
+            ARMARX_VERBOSE << "Layer: " << layer << ", Visible: " << layerVisible;
 
             viz::CoinLayerID layerID(component, layer);
-            visualizer.showLayer(layerID, visible);
+            visualizer.showLayer(layerID, layerVisible);
         }
     }
 }
@@ -115,35 +117,67 @@ void ArVizWidgetController::layerTreeChanged(QTreeWidgetItem* item, int /*column
 void ArVizWidgetController::layersChanged(std::vector<viz::CoinLayerID> const& layers)
 {
     QTreeWidget* tree = widget.layerTree;
-    QTreeWidgetItem* currentItem = nullptr;
 
-    // TODO: We need to keep the state of the old tree items
-    // HACK: Just remove all the children before adding them again
-    tree->clear();
+    std::map<std::string, QTreeWidgetItem*> currentComponents;
+    std::map<viz::CoinLayerID, QTreeWidgetItem*> currentLayers;
+    for (QTreeWidgetItemIterator compIter(widget.layerTree); *compIter; ++compIter)
+    {
+        QTreeWidgetItem* componentItem = *compIter;
+        std::string component = componentItem->text(0).toStdString();
+        currentComponents.emplace(component, componentItem);
+
+        for (QTreeWidgetItemIterator layerIter(componentItem); *layerIter; ++layerIter)
+        {
+            QTreeWidgetItem* layerItem = *layerIter;
+            std::string layer = layerItem->text(0).toStdString();
+
+            viz::CoinLayerID layerID(component, layer);
+            currentLayers.emplace(layerID, layerItem);
+        }
+    }
 
+    // We need to determine which layers are new and where to append them
+    QTreeWidgetItem* currentItem = nullptr;
     std::string currentComponent;
     for (auto& entry : layers)
     {
         std::string const& component = entry.first;
         if (component != currentComponent)
         {
-            // Create a new item
-            currentItem = new QTreeWidgetItem(tree);
-            currentItem->setText(0, QString::fromStdString(component));
-            // A new item is visible by default
-            currentItem->setCheckState(0, Qt::Checked);
+            auto iter = currentComponents.find(component);
+            if (iter == currentComponents.end())
+            {
+                // Create a new item
+                currentItem = new QTreeWidgetItem(tree);
+                currentItem->setText(0, QString::fromStdString(component));
+                // A new item is visible by default
+                currentItem->setCheckState(0, Qt::Checked);
+            }
+            else
+            {
+                // Item exists already
+                currentItem = iter->second;
+            }
 
             currentComponent = component;
         }
 
-        std::string const& layer = entry.second;
-        QTreeWidgetItem* layerItem = new QTreeWidgetItem;
-        layerItem->setText(0, QString::fromStdString(layer));
-        // A new item is visible by default
-        // TODO: Take into account the old state!
-        layerItem->setCheckState(0, Qt::Checked);
+        auto iter = currentLayers.find(entry);
+        if (iter == currentLayers.end())
+        {
+            // Create a new item
+            std::string const& layer = entry.second;
+            QTreeWidgetItem* layerItem = new QTreeWidgetItem;
+            layerItem->setText(0, QString::fromStdString(layer));
+            // A new item is visible by default
+            layerItem->setCheckState(0, Qt::Checked);
 
-        currentItem->addChild(layerItem);
+            currentItem->addChild(layerItem);
+        }
+        else
+        {
+            // Item exists already == nothing to be done
+        }
     }
 }
 
-- 
GitLab