From de3f32b8a9a710aa9defb64361489280c08e53a3 Mon Sep 17 00:00:00 2001
From: Peter Albrecht <albrecpe@gmail.com>
Date: Thu, 14 Dec 2023 17:06:05 +0100
Subject: [PATCH] Implemented skill search

---
 .../skills_gui/memory/SkillManagerWrapper.cpp | 33 +++++++++++++++++++
 .../skills_gui/memory/SkillManagerWrapper.h   | 14 ++++++++
 .../skills_gui/skills/SkillGroupBox.cpp       | 23 +++++++++++++
 .../skills_gui/skills/SkillGroupBox.h         |  3 ++
 4 files changed, 73 insertions(+)

diff --git a/source/RobotAPI/libraries/skills_gui/memory/SkillManagerWrapper.cpp b/source/RobotAPI/libraries/skills_gui/memory/SkillManagerWrapper.cpp
index 66b8a2b62..9165c9a53 100644
--- a/source/RobotAPI/libraries/skills_gui/memory/SkillManagerWrapper.cpp
+++ b/source/RobotAPI/libraries/skills_gui/memory/SkillManagerWrapper.cpp
@@ -19,6 +19,33 @@ namespace armarx::skills::gui
         ARMARX_ERROR << "Function not implemented!";
     }
 
+    void
+    SkillManagerWrapper::filterSkillUpdate(
+        std::map<skills::manager::dto::SkillID, skills::manager::dto::SkillDescription>& update)
+    {
+        // empty search => do not filter
+        if (this->currentSkillSearch.empty())
+        {
+            return;
+        }
+
+        // TODO: whitespace to wildcard
+
+        std::string key = simox::alg::to_lower(this->currentSkillSearch);
+
+        for (auto it = update.begin(); it != update.end();)
+        {
+            if (simox::alg::to_lower(skills::SkillID::FromIce(it->first).skillName).find(key))
+            {
+                it = update.erase(it);
+            }
+            else
+            {
+                ++it;
+            }
+        }
+    }
+
     void
     SkillManagerWrapper::fetchSkills()
     {
@@ -87,6 +114,12 @@ namespace armarx::skills::gui
         }
     }
 
+    void
+    SkillManagerWrapper::acceptSearchRequest(std::string search)
+    {
+        this->currentSkillSearch = search;
+    }
+
     const SkillManagerWrapper::Snapshot
     SkillManagerWrapper::getLatestUpdate()
     {
diff --git a/source/RobotAPI/libraries/skills_gui/memory/SkillManagerWrapper.h b/source/RobotAPI/libraries/skills_gui/memory/SkillManagerWrapper.h
index e86c5c16b..7b1a2cb92 100644
--- a/source/RobotAPI/libraries/skills_gui/memory/SkillManagerWrapper.h
+++ b/source/RobotAPI/libraries/skills_gui/memory/SkillManagerWrapper.h
@@ -82,12 +82,19 @@ namespace armarx::skills::gui
          */
         void disconnect();
 
+        /**
+         * @brief Applies the search word to the update filter.
+         * @param search The search word.
+         */
+        void acceptSearchRequest(std::string search);
+
     private:
         mutable std::mutex mutex_memory;
         mutable std::mutex mutex_snapshot;
 
         armarx::skills::manager::dti::SkillManagerInterfacePrx memory;
         Snapshot snapshot;
+        std::string currentSkillSearch = "";
 
         /**
          * @brief Updates the skills map in the snapshot.
@@ -98,5 +105,12 @@ namespace armarx::skills::gui
          * @brief Updates the executions map in the snapshot.
          */
         void fetchExecutions();
+
+        /**
+         * @brief Modifies the given map to match the search.
+         * @param update The map to modify.
+         */
+        void filterSkillUpdate(std::map<skills::manager::dto::SkillID,
+                                        skills::manager::dto::SkillDescription>& update);
     };
 } // namespace armarx::skills::gui
diff --git a/source/RobotAPI/libraries/skills_gui/skills/SkillGroupBox.cpp b/source/RobotAPI/libraries/skills_gui/skills/SkillGroupBox.cpp
index 5d079e983..97a201547 100644
--- a/source/RobotAPI/libraries/skills_gui/skills/SkillGroupBox.cpp
+++ b/source/RobotAPI/libraries/skills_gui/skills/SkillGroupBox.cpp
@@ -5,6 +5,13 @@
 
 namespace armarx::skills::gui
 {
+    void
+    SkillGroupBox::handleSearch()
+    {
+        std::string search = this->searchBar->text().toStdString();
+        emit searchRequest(search);
+    }
+
     void
     SkillGroupBox::setupUi()
     {
@@ -24,5 +31,21 @@ namespace armarx::skills::gui
         searchLayout->addWidget(this->acceptSearchButton);
 
         // text
+        this->searchBar->setPlaceholderText(QString::fromStdString("Search ..."));
+        this->acceptSearchButton->setText(QString::fromStdString("Search"));
+
+        connectSignals();
+    }
+
+    void
+    SkillGroupBox::connectSignals()
+    {
+        connect(
+            this->acceptSearchButton, &QPushButton::clicked, this, &SkillGroupBox::handleSearch);
+        connect(this->searchBar, &QLineEdit::editingFinished, this, &SkillGroupBox::handleSearch);
+        connect(this,
+                &SkillGroupBox::searchRequest,
+                this->memory.get(),
+                &SkillManagerWrapper::acceptSearchRequest);
     }
 } // namespace armarx::skills::gui
diff --git a/source/RobotAPI/libraries/skills_gui/skills/SkillGroupBox.h b/source/RobotAPI/libraries/skills_gui/skills/SkillGroupBox.h
index cd9293287..60bd45e3b 100644
--- a/source/RobotAPI/libraries/skills_gui/skills/SkillGroupBox.h
+++ b/source/RobotAPI/libraries/skills_gui/skills/SkillGroupBox.h
@@ -12,10 +12,12 @@ namespace armarx::skills::gui
 {
     class SkillGroupBox : public QGroupBox, public MemoryCommunicatorBase
     {
+        Q_OBJECT
     public:
         SkillGroupBox(std::shared_ptr<SkillManagerWrapper> _memory, QWidget* parent = nullptr) :
             QGroupBox(parent), MemoryCommunicatorBase(_memory)
         {
+            setupUi();
         }
 
     signals:
@@ -31,6 +33,7 @@ namespace armarx::skills::gui
 
     private:
         void setupUi();
+        void connectSignals();
         QLineEdit* searchBar;
         QPushButton* acceptSearchButton = nullptr;
         SkillTreeWidget* skillTreeWidget = nullptr;
-- 
GitLab