From 2fec2bd3ba445e87523dc68d70d9ab4224a0a283 Mon Sep 17 00:00:00 2001
From: Tobias Bodmer <Tobias.Bodmer@gmx.de>
Date: Thu, 12 Jan 2023 12:41:48 +0100
Subject: [PATCH] Convert IntEnum && list #elements && list conv fix

Implement IntEnum parsing by both value and string name. The String name
is hadled first.
Also added a feature which displays the contained number of children at
the otherwise empty value field for lists.

Fixed a bug, where the converter visitor sometimes didn't get
called with the visit() method.

Also AronTreeWidgetConverter recursively called itself when listTypes
were involved.
---
 .../AronTreeWidgetController.cpp              | 12 ++---
 .../visitors/AronTreeWidgetContextMenu.cpp    | 45 +++++++++++++++++++
 .../visitors/AronTreeWidgetContextMenu.h      | 21 ++++++---
 .../visitors/AronTreeWidgetConverter.cpp      | 45 ++++++++++++++++++-
 .../visitors/AronTreeWidgetSetter.cpp         |  9 ++++
 5 files changed, 118 insertions(+), 14 deletions(-)

diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.cpp
index c6349abd2..3399138ef 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.cpp
@@ -23,10 +23,6 @@ namespace armarx
                 &QTreeWidget::itemDoubleClicked,
                 this,
                 &AronTreeWidgetController::onTreeWidgetItemDoubleClicked);
-        connect(tree,
-                &QTreeWidget::itemChanged,
-                this,
-                &AronTreeWidgetController::onTreeWidgetItemChanged);
 
         if (type) // if there is a type set, we create a tree widget from the type
         {
@@ -48,12 +44,18 @@ namespace armarx
         {
             new QTreeWidgetItem(parent, {QString::fromStdString("No args")});
         }
+
+        // connect change handling after args init
+        connect(tree,
+                &QTreeWidget::itemChanged,
+                this,
+                &AronTreeWidgetController::onTreeWidgetItemChanged);
     }
 
     aron::data::DictPtr
     AronTreeWidgetController::convertToAron() const
     {
-        if (parent)
+        if (parent && type)
         {
             AronTreeWidgetConverterVisitor v(parent, 0);
             aron::type::visit(v, type);
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.cpp
index c58319633..3f484b85d 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.cpp
@@ -19,6 +19,29 @@ namespace armarx
     {
     }
 
+    QString
+    AronTreeWidgetContextMenuVisitor::generateNumElementsText(int num)
+    {
+        QString numElemsText = "<";
+        if (num == 0)
+        {
+            numElemsText.append("no");
+        }
+        else
+        {
+            numElemsText.append(QString::number(num));
+        }
+        if (num > 1 || num == 0)
+        {
+            numElemsText.append(" elements>");
+        }
+        else
+        {
+            numElemsText.append(" element>");
+        }
+        return numElemsText;
+    }
+
     void
     AronTreeWidgetContextMenuVisitor::addDeleteAction()
     {
@@ -54,6 +77,13 @@ namespace armarx
                 std::string numberString = std::to_string(i);
                 castedContainer->child(i)->setText(0, numberString.c_str());
             }
+            // This displays the number of children also when the list is collapsed
+            QString numElemsText = generateNumElementsText(castedContainer->childCount());
+            containerPtr->setText(1, numElemsText);
+            // set italic
+            auto currFont = castedContainer->font(1);
+            currFont.setItalic(true);
+            castedContainer->setFont(1, currFont);
         }
     }
 
@@ -82,6 +112,21 @@ namespace armarx
         {
             throw std::runtime_error("Creation of TreeElementChild failed unexpectedly");
         }
+        // if it is a list, we update the number of children at the top
+        auto* castedContainer = AronTreeWidgetItem::DynamicCast(parentItem);
+
+        // if the parent item is a List, we need to redo the numbers
+        if (castedContainer &&
+            castedContainer->aronType->getDescriptor() == aron::type::Descriptor::LIST)
+        {
+            // This displays the number of children also when the list is collapsed
+            auto numElemsText = generateNumElementsText(castedContainer->childCount());
+            castedContainer->setText(1, numElemsText);
+            // set italic
+            auto currFont = castedContainer->font(1);
+            currFont.setItalic(true);
+            castedContainer->setFont(1, currFont);
+        }
     }
 
     void
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.h
index f3fa29ff8..bc35df3cb 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.h
@@ -1,29 +1,36 @@
 #pragma once
 
 
-#include <RobotAPI/libraries/aron/core/type/variant/All.h>
+#include <QAction>
+
 #include <RobotAPI/libraries/aron/core/data/variant/All.h>
+#include <RobotAPI/libraries/aron/core/type/variant/All.h>
 #include <RobotAPI/libraries/aron/core/type/visitor/variant/VariantVisitor.h>
-#include <QAction>
 
 class QTreeWidget;
 class QPoint;
 
-namespace armarx {
+namespace armarx
+{
 
     class AronTreeWidgetItem;
 
-    class AronTreeWidgetContextMenuVisitor :
-            public armarx::aron::type::ConstVariantVisitor
+    class AronTreeWidgetContextMenuVisitor : public armarx::aron::type::ConstVariantVisitor
     {
     public:
         AronTreeWidgetItem* parentItem;
         QTreeWidget* contextMenuParent;
         const QPoint& pos;
         int index;
+        // helper that generates a string on how many items are available
+        // its used most often in this class, that's why its defined here
+        static QString generateNumElementsText(int num);
 
         AronTreeWidgetContextMenuVisitor() = delete;
-        AronTreeWidgetContextMenuVisitor(AronTreeWidgetItem* i, const QPoint& pos, QTreeWidget* contextMenuParent, int x);
+        AronTreeWidgetContextMenuVisitor(AronTreeWidgetItem* i,
+                                         const QPoint& pos,
+                                         QTreeWidget* contextMenuParent,
+                                         int x);
 
         void visitAronVariant(const aron::type::ObjectPtr&) final;
         void visitAronVariant(const aron::type::DictPtr&) final;
@@ -57,4 +64,4 @@ namespace armarx {
         void addAddAction();
         void executeAddElement();
     };
-}
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
index 2db39c494..5a5d52c03 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
@@ -100,10 +100,12 @@ namespace armarx
         auto createdAronList = std::make_shared<aron::data::List>(i->getPath());
         createdAron = createdAronList;
         auto* elem = parentItem->child(index);
-
+        auto childrenTypes = i->getChildren();
+        ARMARX_CHECK(childrenTypes.size() == 1);
         for (int j = 0; j < elem->childCount(); ++j)
         {
             AronTreeWidgetConverterVisitor convVisitor(elem, j);
+            aron::type::visit(convVisitor, childrenTypes[0]);
             if (convVisitor.createdAron && !convVisitor.errorOccured)
             {
                 createdAronList->addElement(convVisitor.createdAron);
@@ -147,6 +149,8 @@ namespace armarx
         for (int j = 0; j < (int)i->childrenSize(); ++j)
         {
             AronTreeWidgetConverterVisitor convVisitor(currElem, j);
+            aron::type::visit(convVisitor, i);
+
             if (convVisitor.createdAron && !convVisitor.errorOccured)
             {
                 createdAronTuple->addElement(convVisitor.createdAron);
@@ -235,7 +239,42 @@ namespace armarx
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::IntEnumPtr& i)
     {
-        // TODO
+        auto crAron = std::make_shared<aron::data::Int>(i->getPath());
+        createdAron = crAron;
+        auto valueMap = i->getAcceptedValueMap();
+        QTreeWidgetItem* el = parentItem->child(index);
+        std::string toParse = el->text(1).toStdString();
+        auto searchRes = valueMap.find(toParse);
+        if (searchRes != valueMap.end())
+        {
+            crAron->setValue(searchRes->second);
+            return;
+        }
+        // maybe its the number directly
+        auto accVals = i->getAcceptedValues();
+        int res;
+        try
+        {
+            res = simox::alg::to_<int>(toParse);
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            errorOccured = true;
+            ARMARX_VERBOSE << "Failed to parse IntEnum: Could not convert  \'" << toParse
+                           << "\' to an int. It also was not one of the accepted strings.";
+            return;
+        }
+        if (std::find(accVals.begin(), accVals.end(), res) != accVals.end())
+        {
+
+            crAron->setValue(res);
+        }
+        else
+        {
+            errorOccured = true;
+            ARMARX_VERBOSE << "Parsed int " << res
+                           << "but this int is not part of the accepted values.";
+        }
     }
 
     void
@@ -258,6 +297,8 @@ namespace armarx
         }
         catch (const simox::error::SimoxError& err)
         {
+
+
             errorOccured = true;
             ARMARX_VERBOSE << "Conversion from String to Int failed. Error:\"" << err.what()
                            << "\"";
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
index 20c7ef98d..63b29b930 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
@@ -26,6 +26,7 @@
 
 #include <RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/EditMatrixWidget.h>
 
+#include "AronTreeWidgetContextMenu.h"
 #include "AronTreeWidgetCreator.h"
 
 //visitors
@@ -129,6 +130,14 @@ namespace armarx
 
                 ++x;
             }
+            // This displays the number of children also when the list is collapsed
+            QString numElemsText =
+                AronTreeWidgetContextMenuVisitor::generateNumElementsText(i->getElements().size());
+            aronTreeWidget->setText(1, numElemsText);
+            // set italic
+            auto currFont = aronTreeWidget->font(1);
+            currFont.setItalic(true);
+            aronTreeWidget->setFont(1, currFont);
         }
     }
 
-- 
GitLab