From 801dcddafcb91ddf7aebc6c024312f6718a444c9 Mon Sep 17 00:00:00 2001
From: Peter Albrecht <usnlf@student.kit.edu>
Date: Wed, 25 Dec 2024 13:30:33 +0100
Subject: [PATCH] feat: parameters saving

---
 .../skill_details/SkillDetailsTreeWidget.cpp  | 64 +++++++++++++++----
 .../skill_details/SkillDetailsTreeWidget.h    |  9 ++-
 2 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/source/RobotAPI/libraries/skills_gui/skill_details/SkillDetailsTreeWidget.cpp b/source/RobotAPI/libraries/skills_gui/skill_details/SkillDetailsTreeWidget.cpp
index 10c521380..bff75ae4f 100644
--- a/source/RobotAPI/libraries/skills_gui/skill_details/SkillDetailsTreeWidget.cpp
+++ b/source/RobotAPI/libraries/skills_gui/skill_details/SkillDetailsTreeWidget.cpp
@@ -8,10 +8,15 @@
 #include <QResizeEvent>
 #include <QVBoxLayout>
 #include <qchar.h>
+#include <qcheckbox.h>
 #include <qmessagebox.h>
+#include <qpushbutton.h>
+#include <qtreewidget.h>
 
 #include <ArmarXCore/core/logging/Logging.h>
 
+#include "RobotAPI/libraries/skills/core/SkillID.h"
+#include "RobotAPI/libraries/skills_gui/aron_tree_widget/AronTreeWidgetController.h"
 #include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
 
 namespace armarx::skills::gui
@@ -76,7 +81,7 @@ namespace armarx::skills::gui
         resizeContents();
 
         // update the ShownSkill
-        shownSkill = {skillId, descr};
+        shownSkill = {skillId, descr, aronTreeWidgetController->convertToAron()};
     }
 
     void
@@ -112,12 +117,7 @@ namespace armarx::skills::gui
         // only triggers if the description does not match
         if (descr != shownSkill->descr)
         {
-            if (askUserToConfirmWidgetReset(
-                    "The currently shown skill in the details widget has not been found in the "
-                    "latest manager update. Did the skill provider die?"))
-            {
-                this->updateContents(sid, descr);
-            }
+            this->updateContents(sid, descr);
         }
     }
 
@@ -139,16 +139,49 @@ namespace armarx::skills::gui
     }
 
     bool
-    SkillDetailsTreeWidget::askUserToConfirmWidgetReset(std::string reason)
+    SkillDetailsTreeWidget::askUserToConfirmWidgetReset()
     {
-        std::string msg = "The skill details widget will be reset.\nReason: " + reason;
+        std::string msg = "The skill details widget will be reset. All changes will be lost, unless saved.";
         QMessageBox msgBox;
         msgBox.setText(QString::fromStdString(msg));
-        QPushButton* connectButton = msgBox.addButton(tr("Connect"), QMessageBox::ActionRole);
-        QPushButton* abortButton = msgBox.addButton(QMessageBox::Abort);
-        ARMARX_WARNING << "The skill details widget will be reset. Reason: " << reason;
+        QCheckBox* ignoreCheckbox = new QCheckBox("Do not ask again in this session.");
+        msgBox.setCheckBox(ignoreCheckbox);
+        QPushButton* copyParamsButton = msgBox.addButton(tr("Copy Parameters && Close"), QMessageBox::ActionRole);
+        QPushButton* copySkillIdButton = msgBox.addButton(tr("Copy SkillID && Close"), QMessageBox::ActionRole);
+        QPushButton* closeWithoutSavingButton = msgBox.addButton(tr("Close"), QMessageBox::ActionRole);
+
+        msgBox.setDefaultButton(closeWithoutSavingButton);
+        QObject::connect(ignoreCheckbox, &QCheckBox::stateChanged, [this](int state){
+        if (static_cast<Qt::CheckState>(state) == Qt::CheckState::Checked) {
+            this->showWidgetResetConfirmation_ = false;
+        }
+        });
+
+        connect(copyParamsButton, &QPushButton::pressed, this, &SkillDetailsTreeWidget::copyCurrentConfig);
+        msgBox.exec();
+
         return true;
     }
+    
+    bool SkillDetailsTreeWidget::checkIfParametersAreModified() 
+    {
+        if (not shownSkill.has_value())
+        {
+            return false;
+        }
+
+        auto defaults = shownSkill->originalParameters;
+
+        auto params = this->aronTreeWidgetController->convertToAron();
+        bool modified = *defaults.get() != *params.get();
+        if (modified)
+        {
+            ARMARX_INFO << "The parameters have been modified. Asking the user to save.";
+            ARMARX_INFO << "Defaults:\n" << defaults.get();
+            ARMARX_INFO << "Params:\n" << params.get();
+        }
+        return modified;
+    }
 
     /**
      * Problem: columns 0 and 1 have arbitrary size; so we want to limit their size, to make sure
@@ -240,6 +273,13 @@ namespace armarx::skills::gui
     void
     SkillDetailsTreeWidget::resetWidget()
     {
+        if (checkIfParametersAreModified())
+        {
+            if (showWidgetResetConfirmation_ && not askUserToConfirmWidgetReset())
+            {
+                return;
+            }
+        }
         this->clear();
         this->shownSkill = std::nullopt;
         aronTreeWidgetController = nullptr;
diff --git a/source/RobotAPI/libraries/skills_gui/skill_details/SkillDetailsTreeWidget.h b/source/RobotAPI/libraries/skills_gui/skill_details/SkillDetailsTreeWidget.h
index 5d8417ea4..cf954dceb 100644
--- a/source/RobotAPI/libraries/skills_gui/skill_details/SkillDetailsTreeWidget.h
+++ b/source/RobotAPI/libraries/skills_gui/skill_details/SkillDetailsTreeWidget.h
@@ -4,6 +4,7 @@
 #include <vector>
 #include <QTreeWidget>
 
+#include "RobotAPI/libraries/aron/core/data/variant/container/Dict.h"
 #include "RobotAPI/libraries/skills/core/SkillID.h"
 #include "RobotAPI/libraries/skills_gui/aron_tree_widget/AronTreeWidgetController.h"
 
@@ -22,13 +23,13 @@ namespace armarx::skills::gui
         void updateContents(skills::SkillID const& skillId, skills::SkillDescription const& descr);
 
         aron::data::DictPtr getConfigAsAron();
-        void copyCurrentConfig();
         void pasteCurrentConfig();
         void resetWidget();
 
     public slots:
         // this will reset the args to the profile defaults
         void resetCurrentConfig();
+        void copyCurrentConfig();
         void disconnectGui();
         void updateGui(SkillManagerWrapper::Snapshot update);
         void resizeContents();
@@ -38,6 +39,7 @@ namespace armarx::skills::gui
         {
             skills::SkillID skillId;
             skills::SkillDescription descr;
+            armarx::aron::data::DictPtr originalParameters;
         };
 
         std::optional<ShownSkill> shownSkill;
@@ -49,7 +51,10 @@ namespace armarx::skills::gui
         AronTreeWidgetControllerPtr aronTreeWidgetController = nullptr;
         void setupUi();
         void checkIfShownSkillIsAvailable(SkillManagerWrapper::Snapshot& update);
-        bool askUserToConfirmWidgetReset(std::string reason);
+        bool askUserToConfirmWidgetReset();
+        bool checkIfParametersAreModified();
+
+        bool showWidgetResetConfirmation_ = true;
     };
 } // namespace armarx::skills::gui
 
-- 
GitLab