From 51903cf6512860e84ed2197e0aae6ef9b1183e87 Mon Sep 17 00:00:00 2001
From: Peter Albrecht <albrecpe@gmail.com>
Date: Thu, 16 Nov 2023 15:32:05 +0100
Subject: [PATCH] Added stop all button, and implemented update widget

---
 .../PeriodicUpdateWidget.cpp                  |  2 +-
 .../SkillManagerMonitorWidget.ui              | 85 +++++++++++--------
 .../SkillManagerMonitorWidgetController.cpp   | 63 +++++++-------
 .../SkillManagerMonitorWidgetController.h     | 15 ++--
 4 files changed, 91 insertions(+), 74 deletions(-)

diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/PeriodicUpdateWidget.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/PeriodicUpdateWidget.cpp
index d039d0d54..e23920f1b 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/PeriodicUpdateWidget.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/PeriodicUpdateWidget.cpp
@@ -12,7 +12,7 @@ namespace armarx
 {
     PeriodicUpdateWidget::PeriodicUpdateWidget(double frequency, double maxFrequency)
     {
-        setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Fixed);
+        setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
 
         QLayout* vlayout = new QVBoxLayout();
         QLayout* hlayout = new QHBoxLayout();
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
index 5ff285285..abc07d96c 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
@@ -6,12 +6,12 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>1060</width>
-    <height>657</height>
+    <width>1126</width>
+    <height>729</height>
    </rect>
   </property>
   <property name="sizePolicy">
-   <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
     <horstretch>0</horstretch>
     <verstretch>0</verstretch>
    </sizepolicy>
@@ -19,41 +19,14 @@
   <property name="windowTitle">
    <string>SkillManagerMonitorWidget</string>
   </property>
-  <layout class="QGridLayout" name="gridLayout_3">
-   <item row="3" column="0">
-    <widget class="QCheckBox" name="checkBoxAutoUpdate">
-     <property name="text">
-      <string>Auto Update</string>
-     </property>
-    </widget>
-   </item>
-   <item row="3" column="3">
-    <widget class="QPushButton" name="pushButtonRefreshNow">
-     <property name="text">
-      <string>Refresh Now</string>
-     </property>
-    </widget>
-   </item>
-   <item row="3" column="2">
-    <widget class="QDoubleSpinBox" name="doubleSpinBoxUpdateFreq"/>
-   </item>
-   <item row="3" column="1">
-    <widget class="QLabel" name="label">
-     <property name="text">
-      <string>Update Frequency:</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="0" colspan="4">
+  <layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,0,0">
+   <item row="3" column="0" colspan="2">
     <widget class="QSplitter" name="splitter_2">
      <property name="enabled">
       <bool>true</bool>
      </property>
      <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
@@ -75,7 +48,7 @@
        <string>Executions</string>
       </property>
       <layout class="QGridLayout" name="gridLayout_4">
-       <item row="1" column="0" colspan="3">
+       <item row="0" column="0" colspan="3">
         <widget class="QTreeWidget" name="treeWidgetSkillExecutions">
          <property name="contextMenuPolicy">
           <enum>Qt::CustomContextMenu</enum>
@@ -249,6 +222,50 @@
      </widget>
     </widget>
    </item>
+   <item row="0" column="0" rowspan="3" colspan="2">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <property name="sizeConstraint">
+      <enum>QLayout::SetDefaultConstraint</enum>
+     </property>
+     <item>
+      <layout class="QHBoxLayout" name="updateWidgetLayout">
+       <item>
+        <spacer name="horizontalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Expanding</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="stopAllLayout">
+       <item>
+        <spacer name="horizontalSpacer">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
   </layout>
  </widget>
  <resources/>
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
index 83bfd04d2..fb8a1ba37 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
@@ -35,9 +35,6 @@
 
 // modals
 
-#include "aronTreeWidget/modal/text/AronTreeWidgetTextInputModalController.h"
-
-// debug
 #include <QAction>
 #include <QClipboard>
 #include <QDoubleSpinBox>
@@ -47,6 +44,7 @@
 #include <RobotAPI/libraries/skills/core/SkillExecutionRequest.h>
 
 #include "aronTreeWidget/Data.h"
+#include "aronTreeWidget/modal/text/AronTreeWidgetTextInputModalController.h"
 
 //configSk
 namespace armarx
@@ -142,30 +140,25 @@ namespace armarx
     SkillManagerMonitorWidgetController::SkillManagerMonitorWidgetController()
     {
         widget.setupUi(getWidget());
+        this->updateWidget = new PeriodicUpdateWidget(2.0, 60);
+        widget.updateWidgetLayout->insertWidget(0, updateWidget);
 
-        double default_hz = 2;
-        widget.doubleSpinBoxUpdateFreq->setValue(default_hz);
-        widget.doubleSpinBoxUpdateFreq->setMinimum(0.5);
-        widget.doubleSpinBoxUpdateFreq->setMaximum(20);
-        widget.doubleSpinBoxUpdateFreq->setSingleStep(0.5);
-        widget.doubleSpinBoxUpdateFreq->setSuffix(" Hz");
-        this->currentSkillSearch = QString("");
+        this->stopAllButton = new QPushButton("Stop all executions");
+        widget.stopAllLayout->addWidget(stopAllButton);
 
-        refreshSkillsResultTimer = new QTimer(this);
-        updateTimerFrequency();
-        refreshSkillsResultTimer->start();
+        this->currentSkillSearch = QString("");
 
+        connect(this->stopAllButton,
+                &QPushButton::clicked,
+                this,
+                &SkillManagerMonitorWidgetController::stopAllExecutions);
         connect(widget.treeWidgetSkillExecutions,
                 &QTreeWidget::customContextMenuRequested,
                 this,
                 &SkillManagerMonitorWidgetController::prepareAndRunMenu);
 
-        connect(widget.doubleSpinBoxUpdateFreq,
-                &QDoubleSpinBox::editingFinished,
-                this,
-                &SkillManagerMonitorWidgetController::updateTimerFrequency);
-        connect(refreshSkillsResultTimer,
-                &QTimer::timeout,
+        connect(updateWidget,
+                &armarx::PeriodicUpdateWidget::update,
                 this,
                 &SkillManagerMonitorWidgetController::refreshSkillsAndExecutions);
 
@@ -193,10 +186,10 @@ namespace armarx
                 this,
                 &SkillManagerMonitorWidgetController::skillExecutionSelectionChanged);
 
-        connect(widget.pushButtonRefreshNow,
+        /*connect(widget.pushButtonRefreshNow,
                 &QPushButton::clicked,
                 this,
-                &SkillManagerMonitorWidgetController::refreshSkills);
+                &SkillManagerMonitorWidgetController::refreshSkills);*/
         connect(widget.pushButtonSearch,
                 &QPushButton::clicked,
                 this,
@@ -227,6 +220,7 @@ namespace armarx
         widget.treeWidgetSkillDetails->setColumnHidden(3, true);
 
         getProxy(memory, observerName, 1000);
+        this->updateWidget->startTimerIfEnabled();
         connected = true;
     }
 
@@ -243,13 +237,7 @@ namespace armarx
         skillsArgumentsTreeWidgetItem = nullptr;
         selectedSkill.skillId.providerId->providerName = "";
         selectedSkill.skillId.skillName = "";
-    }
-
-    void
-    SkillManagerMonitorWidgetController::updateTimerFrequency()
-    {
-        int f = static_cast<int>(std::round(1000 / widget.doubleSpinBoxUpdateFreq->value()));
-        refreshSkillsResultTimer->setInterval(f);
+        this->updateWidget->stopTimer();
     }
 
     void
@@ -261,11 +249,8 @@ namespace armarx
     void
     SkillManagerMonitorWidgetController::refreshSkillsAndExecutions()
     {
-        if (widget.checkBoxAutoUpdate->isChecked())
-        {
-            refreshSkills();
-            refreshExecutions();
-        }
+        refreshSkills();
+        refreshExecutions();
     }
 
     void
@@ -575,6 +560,18 @@ namespace armarx
         memory->begin_executeSkill(req.toManagerIce());
     }
 
+    void
+    SkillManagerMonitorWidgetController::stopAllExecutions()
+    {
+        auto tree = widget.treeWidgetSkillExecutions;
+        for (ssize_t i = 0; i < tree->topLevelItemCount(); ++i)
+        {
+            auto item = static_cast<SkillExecutionInfoTreeWidgetItem*>(
+                widget.treeWidgetSkillExecutions->topLevelItem(i));
+            memory->abortSkill(item->executionId.toManagerIce());
+        }
+    }
+
     void
     SkillManagerMonitorWidgetController::stopSkill()
     {
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
index 0480e13c6..df6f5b1ef 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
@@ -33,6 +33,7 @@
 #include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h>
 #include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h>
 
+#include "RobotAPI/gui-plugins/SkillManagerPlugin/PeriodicUpdateWidget.h"
 #include <RobotAPI/gui-plugins/SkillManagerPlugin/ui_SkillManagerMonitorWidget.h>
 #include <RobotAPI/interface/skills/SkillMemoryInterface.h>
 #include <RobotAPI/libraries/aron/core/data/variant/All.h>
@@ -112,16 +113,16 @@ namespace armarx
 
         void onInitComponent() override;
         void onConnectComponent() override;
-        void onDisconnectComponent() override;
+        void onDisconnectComponent();
 
     private slots:
         void skillSelectionChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous);
         void skillExecutionSelectionChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous);
 
-        void stopSkill();
+        void stopAllExecutions();
+        void stopSkill(); // TODO: rename
         void executeSelectedSkill();
 
-        void updateTimerFrequency();
         void refreshSkills();
         void refreshExecutions();
         void refreshSkillsAndExecutions();
@@ -179,13 +180,15 @@ namespace armarx
         void matchSkillUpdateToSearch(std::map<skills::manager::dto::SkillID,
                                                skills::manager::dto::SkillDescription>& update);
 
+
+        PeriodicUpdateWidget* updateWidget =
+            nullptr; // TODO: this should not be held by the controller!
+        QPushButton* stopAllButton = nullptr; // also this. Oh well...
+
         // Helper to get the treeWidgetItem easily
         QTreeWidgetItem* skillsArgumentsTreeWidgetItem = nullptr;
         AronTreeWidgetControllerPtr aronTreeWidgetController = nullptr;
 
-        // others
-        QTimer* refreshSkillsResultTimer;
-
         // connected flag
         std::atomic_bool connected = false;
     };
-- 
GitLab