From 138a52d54c6ec47823859b9061668f08b025fca0 Mon Sep 17 00:00:00 2001
From: Peter Albrecht <albrecpe@gmail.com>
Date: Tue, 24 Oct 2023 16:19:47 +0200
Subject: [PATCH] Implemented skill search

---
 .../SkillManagerMonitorWidget.ui              |  3 ++
 .../SkillManagerMonitorWidgetController.cpp   | 43 +++++++++++++++++++
 .../SkillManagerMonitorWidgetController.h     |  5 +++
 3 files changed, 51 insertions(+)

diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
index 88c594cea..5ff285285 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
@@ -154,6 +154,9 @@
         <item row="4" column="0">
          <widget class="QLineEdit" name="lineEditSearch">
           <property name="text">
+           <string/>
+          </property>
+          <property name="placeholderText">
            <string>Search...</string>
           </property>
          </widget>
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
index 4b7833160..01cb60a2d 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
@@ -22,8 +22,11 @@
 
 #include "SkillManagerMonitorWidgetController.h"
 
+#include <regex>
 #include <string>
 
+#include <boost/algorithm/string.hpp>
+
 #include <RobotAPI/libraries/skills/core/Skill.h>
 
 #include "aronTreeWidget/visitors/AronTreeWidgetConverter.h"
@@ -142,6 +145,7 @@ namespace armarx
         widget.doubleSpinBoxUpdateFreq->setMaximum(20);
         widget.doubleSpinBoxUpdateFreq->setSingleStep(0.5);
         widget.doubleSpinBoxUpdateFreq->setSuffix(" Hz");
+        this->currentSkillSearch = QString("");
 
         refreshSkillsResultTimer = new QTimer(this);
         updateTimerFrequency();
@@ -189,6 +193,15 @@ namespace armarx
                 &QPushButton::clicked,
                 this,
                 &SkillManagerMonitorWidgetController::refreshSkills);
+        connect(widget.pushButtonSearch,
+                &QPushButton::clicked,
+                this,
+                &SkillManagerMonitorWidgetController::searchSkills);
+        // alternatively run search when pressing enter
+        connect(widget.lineEditSearch,
+                &QLineEdit::returnPressed,
+                this,
+                &SkillManagerMonitorWidgetController::searchSkills);
     }
 
     SkillManagerMonitorWidgetController::~SkillManagerMonitorWidgetController()
@@ -235,6 +248,12 @@ namespace armarx
         refreshSkillsResultTimer->setInterval(f);
     }
 
+    void
+    SkillManagerMonitorWidgetController::searchSkills()
+    {
+        this->currentSkillSearch = widget.lineEditSearch->text();
+    }
+
     void
     SkillManagerMonitorWidgetController::refreshSkillsAndExecutions()
     {
@@ -245,6 +264,29 @@ namespace armarx
         }
     }
 
+    void
+    SkillManagerMonitorWidgetController::matchSkillUpdateToSearch(
+        std::map<skills::manager::dto::SkillID, skills::manager::dto::SkillDescription>& update)
+    {
+        if (this->currentSkillSearch.isEmpty())
+        {
+            return;
+        }
+
+        for (auto it = update.begin(); it != update.end();)
+        {
+            if (boost::algorithm::to_lower_copy(skills::SkillID::FromIce(it->first).skillName)
+                    .find(this->currentSkillSearch.toLower().toStdString()))
+            {
+                update.erase(it++);
+            }
+            else
+            {
+                ++it;
+            }
+        }
+    }
+
     void
     SkillManagerMonitorWidgetController::refreshSkills()
     {
@@ -261,6 +303,7 @@ namespace armarx
             std::scoped_lock l(updateMutex);
 
             auto managerSkills = memory->getSkillDescriptions();
+            this->matchSkillUpdateToSearch(managerSkills);
 
             // completely recreate internal skills map
             skills.clear();
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
index ce93db4e5..63c26f1a8 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
@@ -133,6 +133,8 @@ namespace armarx
         void prepareAndRunMenu(const QPoint& pos);
         void rerunSkillWithSimilarParams();
 
+        void searchSkills();
+
 
     private:
         aron::data::DictPtr getConfigAsAron() const;
@@ -143,6 +145,7 @@ namespace armarx
          */
         Ui::SkillManagerMonitorWidget widget;
         QPointer<SimpleConfigDialog> dialog;
+        QString currentSkillSearch;
 
         std::string observerName = "SkillManager";
         skills::dti::SkillMemoryInterfacePrx memory = nullptr;
@@ -172,6 +175,8 @@ namespace armarx
         } selectedSkill;
 
         void executeSkillWithParams(skills::SkillID skillId, aron::data::DictPtr params);
+        void matchSkillUpdateToSearch(std::map<skills::manager::dto::SkillID,
+                                               skills::manager::dto::SkillDescription>& update);
 
         // Helper to get the treeWidgetItem easily
         QTreeWidgetItem* skillsArgumentsTreeWidgetItem = nullptr;
-- 
GitLab