AronTreeWidgetSetter.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * \package RobotAPI::gui-plugins::SkillManagerMonitorWidgetController
17  * \author Raphael Grimm ( raphael dot grimm at kit dot edu )
18  * \date 2020
19  * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "AronTreeWidgetSetter.h"
24 
25 #include <string>
26 
27 #include "../ListDictHelper.h"
28 #include "../widgets/EditMatrixWidget.h"
29 #include "../widgets/IntEnumWidget.h"
30 #include "../widgets/QuaternionWidget.h"
32 #include "AronTreeWidgetCreator.h"
33 
34 template <typename T>
35 std::string
36 usString(T number, size_t precision = 3)
37 {
38  std::stringstream ss;
39  const char* locale = "C";
40  ss.imbue(std::locale(locale));
41 
42  ss << std::fixed << std::setprecision(precision) << number;
43  return ss.str();
44 }
45 
46 //visitors
47 namespace armarx::skills::gui
48 {
49  bool
50  AronTreeWidgetSetterVisitor::checkTreeWidgetItemForSimilarName(const std::string& name) const
51  {
52  QTreeWidgetItem* el = parentItem->child(index);
53 
54  // do not check attribute name, if the element is part of a list or map
55  auto* castedThis = AronTreeWidgetItem::DynamicCast(el->parent());
56  if (castedThis)
57  {
58  auto descr = castedThis->aronType->getDescriptor();
60  {
61  return true;
62  }
63  }
64  std::string n = el->text(0).toStdString();
65  if (name != n)
66  {
67  ARMARX_WARNING_S << "Could not set a tree widget value for the element with key '"
68  << name << "' because it is different from the expected name '" << n
69  << "'.";
70  return false;
71  }
72  return true;
73  }
74 
75  void
76  AronTreeWidgetSetterVisitor::adjustNumberOfChildren(AronTreeWidgetItem* parent,
77  size_t numChildren)
78  {
79  if (((size_t)parent->childCount()) < numChildren)
80  {
81  // The type to create must be the only child of the current aron type
82  ARMARX_CHECK_EQUAL(parent->aronType->childrenSize(), 1);
83  size_t childrenToAdd = numChildren - parent->childCount();
84  for (size_t j = 0; j < childrenToAdd; ++j)
85  {
86  AronTreeWidgetCreatorVisitor childCreator(parent);
87  aron::type::visit(childCreator, parent->aronType->getChildren()[0]);
88  ARMARX_CHECK_NOT_NULL(childCreator.createdQWidgetItem);
89  }
90  }
91  else if ((size_t)parent->childCount() > numChildren)
92  {
93  size_t numChilds = (size_t)parent->childCount() - numChildren;
94  // pop the last child
95  for (size_t j = 0; j < numChilds; ++j)
96  {
97  parent->removeChild(parent->child(parent->childCount() - 1));
98  }
99  }
100  }
101 
102  void
104  {
105  // either it is the root or it has a name
106  if (i->getPath().size() == 0 ||
107  checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
108  {
110  auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el);
111  // allocate enough child items
112  adjustNumberOfChildren(aronTreeWidget, i->childrenSize());
113 
114  // write child values
115  unsigned int x = 0;
116  for (const auto& [key, value] : i->getElements())
117  {
118  el->child(x)->setText(0, {key.c_str()});
119 
122  }
123 
124  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
125  {
126  el->setCheckState(1, Qt::CheckState::Checked);
127  }
128  }
129  }
130 
131  void
133  {
134  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
135  {
137  auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el);
138  adjustNumberOfChildren(aronTreeWidget, i->childrenSize());
139 
140  unsigned int x = 0;
141  for (const auto& value : i->getElements())
142  {
145  auto* currChild = el->child(x);
146  std::string listNum = usString(x);
147  currChild->setText(0, listNum.c_str());
148 
149  ++x;
150  }
151  // This displays the number of children also when the list is collapsed
152  QString numElemsText = misc::generateNumElementsText(i->getElements().size());
153  aronTreeWidget->setText(1, numElemsText);
154  // set italic
155  auto currFont = aronTreeWidget->font(1);
156  currFont.setItalic(true);
157  aronTreeWidget->setFont(1, currFont);
158 
159  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
160  {
161  el->setCheckState(1, Qt::CheckState::Checked);
162  }
163  }
164  }
165 
166  void
168  const std::shared_ptr<armarx::aron::type::Matrix>& matrixType,
169  const aron::data::NDArrayPtr& arr)
170  {
171  auto elemType = matrixType->getElementType();
172  auto* rawData = arr->getData();
173  // string can convert any item
174  auto toString = [elemType, rawData](size_t elementNr) -> std::string
175  {
176  switch (elemType)
177  {
178  case aron::type::matrix::ElementType::FLOAT32:
179  {
180  static_assert(sizeof(float) == 4);
181  float* interpreted = reinterpret_cast<float*>(rawData);
182  float laundered = std::launder(interpreted)[elementNr];
183  return usString<float>(laundered);
184  }
185  case aron::type::matrix::ElementType::FLOAT64:
186  {
187  static_assert(sizeof(double) == 8);
188  double* interpreted = reinterpret_cast<double*>(rawData);
189  float laundered = std::launder(interpreted)[elementNr];
190  return usString<double>(laundered);
191  }
192  case aron::type::matrix::ElementType::UINT8:
193  {
194  auto* interpreted = reinterpret_cast<uint8_t*>(rawData);
195  auto laudered = std::launder(interpreted)[elementNr];
196  return usString<>(laudered);
197  }
198  case aron::type::matrix::ElementType::UINT16:
199  {
200  auto* interpreted = reinterpret_cast<uint16_t*>(rawData);
201  auto laudered = std::launder(interpreted)[elementNr];
202  return usString<>(laudered);
203  }
204  case aron::type::matrix::ElementType::UINT32:
205  {
206  auto* interpreted = reinterpret_cast<uint32_t*>(rawData);
207  auto laudered = std::launder(interpreted)[elementNr];
208  return usString<>(laudered);
209  }
210  case aron::type::matrix::ElementType::INT8:
211  {
212  auto* interpreted = reinterpret_cast<int8_t*>(rawData);
213  auto laudered = std::launder(interpreted)[elementNr];
214  return usString<>(laudered);
215  }
216  case aron::type::matrix::ElementType::INT16:
217  {
218  int16_t* interpreted = reinterpret_cast<int16_t*>(rawData);
219  int16_t laudered = std::launder(interpreted)[elementNr];
220  return usString<int16_t>(laudered);
221  }
222  case aron::type::matrix::ElementType::INT32:
223  {
224  int32_t* interpreted = reinterpret_cast<int32_t*>(rawData);
225  int32_t laudered = std::launder(interpreted)[elementNr];
226  return usString<int32_t>(laudered);
227  }
228  case aron::type::matrix::ElementType::INT64:
229  {
230  int64_t* interpreted = reinterpret_cast<int64_t*>(rawData);
231  int64_t laudered = std::launder(interpreted)[elementNr];
232  return usString<int64_t>(laudered);
233  }
234  }
235  return "Error!";
236  };
237 
238 
239  for (size_t row = 0; (int)row < matrixType->getRows(); ++row)
240  {
241  for (size_t col = 0; (int)col < matrixType->getCols(); ++col)
242  {
243  matrixWidget->setText(row, col, toString(col * matrixType->getRows() + row));
244  }
245  }
246  }
247 
248  void
250  std::shared_ptr<armarx::aron::type::Quaternion>& quatType,
251  const aron::data::NDArrayPtr& arr)
252  {
253  auto elemType = quatType->getElementType();
254  auto rawData = arr->getData();
255  auto shape = arr->getShape();
256  // string can convert any item
257  auto toString = [elemType, rawData](size_t elementNr) -> std::string
258  {
259  switch (elemType)
260  {
261  case aron::type::quaternion::ElementType::FLOAT32:
262  {
263  static_assert(sizeof(float) == 4);
264  float* interpreted = reinterpret_cast<float*>(rawData);
265  float laundered = std::launder(interpreted)[elementNr];
266  return usString<float>(laundered);
267  }
268  case aron::type::quaternion::ElementType::FLOAT64:
269  {
270  static_assert(sizeof(double) == 8);
271  double* interpreted = reinterpret_cast<double*>(rawData);
272 
273  float laundered = std::launder(interpreted)[elementNr];
274  return usString<double>(laundered);
275  }
276  }
277  return "Error!";
278  };
279  for (size_t i = 0; i < 4; ++i)
280  {
282  }
283  }
284 
285  void
287  {
288  // Matrices are handled as NDArray. Raw ndarrays cannot be created currently
290  ARMARX_CHECK(el);
291 
292  auto matrixCast = aron::type::Matrix::DynamicCast(el->aronType);
293  auto quaternionCast = aron::type::Quaternion::DynamicCast(el->aronType);
294 
295  auto* rootWidget = el->treeWidget();
296  ARMARX_CHECK(rootWidget);
297  auto* matrixWidget = EditMatrixWidget::DynamicCast(rootWidget->itemWidget(el, 1));
298  auto* quaternionWidget = QuaternionWidget::DynamicCast(rootWidget->itemWidget(el, 1));
299 
300  if (matrixCast && matrixWidget)
301  {
302  visitMatrix(matrixWidget, matrixCast, arr);
303  }
304  else if (quaternionCast && quaternionWidget)
305  {
306  visitQuaternion(quaternionWidget, quaternionCast, arr);
307  }
308  else
309  {
311  << "we do not support raw NDArrays. Ask Fabian Peller for more information.";
312  }
313 
314  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
315  {
316  el->setCheckState(1, Qt::CheckState::Checked);
317  }
318  }
319 
320  void
322  {
323  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
324  {
326  auto* enumWidget = IntEnumWidget::DynamicCast(el->treeWidget()->itemWidget(el, 1));
327  auto newText = QString::fromStdString(usString<int>(i->getValue()));
328  if (enumWidget)
329  {
330  // Its an IntEnum! -> Ask the custom widget
331  enumWidget->setText(newText);
332  }
333  else
334  {
335  // Its just an int. -> do the QTreeWidgetItem call
336  el->setText(1, newText);
337  }
338 
339  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
340  {
341  el->setCheckState(1, Qt::CheckState::Checked);
342  }
343  }
344  }
345 
346  void
348  {
349  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
350  {
352  el->setText(1, QString::fromStdString(usString<long>(i->getValue())));
353 
354  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
355  {
356  el->setCheckState(1, Qt::CheckState::Checked);
357  }
358  }
359  }
360 
361  void
363  {
364  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
365  {
367  el->setText(1, QString::fromStdString(usString<float>(i->getValue())));
368 
369  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
370  {
371  el->setCheckState(1, Qt::CheckState::Checked);
372  }
373  }
374  }
375 
376  void
378  {
379  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
380  {
382  el->setText(1, QString::fromStdString(usString<double>(i->getValue())));
383 
384  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
385  {
386  el->setCheckState(1, Qt::CheckState::Checked);
387  }
388  }
389  }
390 
391  void
393  {
394  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
395  {
397  el->setText(1, QString::fromStdString(usString<bool>(i->getValue())));
398 
399  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
400  {
401  el->setCheckState(1, Qt::CheckState::Checked);
402  }
403  }
404  }
405 
406  void
408  {
409  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
410  {
412  el->setText(1, QString::fromStdString(i->getValue()));
413 
414  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
415  {
416  el->setCheckState(1, Qt::CheckState::Checked);
417  }
418  }
419  }
420 
421  void
423  {
424  ARMARX_WARNING_S << "Received an unknown type when trying to set a skill argument type "
425  "from an aron data object.";
426  }
427 } // namespace armarx::skills::gui
armarx::skills::gui::EditMatrixWidget::setText
void setText(long row, long col, const std::string &str)
Definition: EditMatrixWidget.cpp:104
AronTreeWidgetContextMenu.h
armarx::skills::gui::AronTreeWidgetSetterVisitor
Definition: AronTreeWidgetSetter.h:37
armarx::skills::gui::visitMatrix
void visitMatrix(EditMatrixWidget *matrixWidget, const std::shared_ptr< armarx::aron::type::Matrix > &matrixType, const aron::data::NDArrayPtr &arr)
Definition: AronTreeWidgetSetter.cpp:167
AronTreeWidgetSetter.h
armarx::skills::gui::QuaternionWidget::setText
void setText(QuaternionComponents col, const std::string &str)
Definition: QuaternionWidget.cpp:32
armarx::skills::gui::misc::generateNumElementsText
QString generateNumElementsText(int num)
Definition: ListDictHelper.cpp:6
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
armarx::aron::data::LongPtr
std::shared_ptr< Long > LongPtr
Definition: forward_declarations.h:26
armarx::aron::type::Descriptor::LIST
@ LIST
armarx::aron::data::NDArrayPtr
std::shared_ptr< NDArray > NDArrayPtr
Definition: NDArray.h:46
armarx::aron::data::DoublePtr
std::shared_ptr< Double > DoublePtr
Definition: forward_declarations.h:32
armarx::skills::gui::IntEnumWidget::DynamicCast
static IntEnumWidget * DynamicCast(QWidget *)
Definition: IntEnumWidget.cpp:38
armarx::skills::gui::EditMatrixWidget
Definition: EditMatrixWidget.h:19
armarx::skills::gui::AronTreeWidgetSetterVisitor::index
int index
Definition: AronTreeWidgetSetter.h:41
armarx::skills::gui::QuaternionWidget::DynamicCast
static QuaternionWidget * DynamicCast(QWidget *)
Definition: QuaternionWidget.cpp:14
AronTreeWidgetCreator.h
armarx::skills::gui::AronTreeWidgetItem::aronType
aron::type::VariantPtr aronType
Definition: AronTreeWidgetItem.h:30
armarx::skills::gui::AronTreeWidgetSetterVisitor::parentItem
QTreeWidgetItem * parentItem
Definition: AronTreeWidgetSetter.h:40
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::skills::gui::visitQuaternion
void visitQuaternion(QuaternionWidget *quatWidget, std::shared_ptr< armarx::aron::type::Quaternion > &quatType, const aron::data::NDArrayPtr &arr)
Definition: AronTreeWidgetSetter.cpp:249
armarx::skills::gui::AronTreeWidgetItem::DynamicCast
static AronTreeWidgetItem * DynamicCast(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:15
usString
std::string usString(T number, size_t precision=3)
Definition: AronTreeWidgetSetter.cpp:36
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::aron::type::detail::SpecializedVariantBase< type::dto::Matrix, Matrix >::DynamicCast
static Matrix & DynamicCast(Variant &n)
Definition: SpecializedVariant.h:106
armarx::skills::gui
Definition: PeriodicUpdateWidget.cpp:11
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::skills::gui::AronTreeWidgetSetterVisitor::visitAronVariant
virtual void visitAronVariant(const aron::data::DictPtr &) final
Definition: AronTreeWidgetSetter.cpp:103
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::skills::gui::QuaternionWidget
Definition: QuaternionWidget.h:16
armarx::aron::data::DictPtr
std::shared_ptr< Dict > DictPtr
Definition: Dict.h:41
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
armarx::skills::gui::QuaternionWidget::QuaternionComponents
QuaternionComponents
Definition: QuaternionWidget.h:25
armarx::aron::similarity::FloatSimilarity::NONE
@ NONE
Definition: FloatSimilarity.h:11
armarx::skills::gui::AronTreeWidgetSetterVisitor::visitUnknown
void visitUnknown(Input &) final
Definition: AronTreeWidgetSetter.cpp:422
armarx::viz::toString
const char * toString(InteractionFeedbackType type)
Definition: Interaction.h:27
armarx::aron::type::Descriptor::DICT
@ DICT
armarx::aron::data::visit
requires isVisitor< VisitorImplementation, typename VisitorImplementation::Input > void visit(VisitorImplementation &v, typename VisitorImplementation::Input &o)
Definition: Visitor.h:124
armarx::aron::data::FloatPtr
std::shared_ptr< Float > FloatPtr
Definition: forward_declarations.h:29
armarx::aron::data::StringPtr
std::shared_ptr< String > StringPtr
Definition: forward_declarations.h:35
armarx::aron::type::visit
void visit(VisitorImplementation &v, typename VisitorImplementation::Input &t)
The visit function.
Definition: Visitor.h:42
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
armarx::skills::gui::AronTreeWidgetItem
Definition: AronTreeWidgetItem.h:19
armarx::aron::data::IntPtr
std::shared_ptr< Int > IntPtr
Definition: forward_declarations.h:23
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx::skills::gui::AronTreeWidgetItem::DynamicCastAndCheck
static AronTreeWidgetItem * DynamicCastAndCheck(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:21
armarx::aron::data::ListPtr
std::shared_ptr< List > ListPtr
Definition: List.h:40
armarx::skills::gui::EditMatrixWidget::DynamicCast
static EditMatrixWidget * DynamicCast(QWidget *)
Definition: EditMatrixWidget.cpp:86
armarx::aron::data::VisitorBase< const data::VariantPtr >::Input
const data::VariantPtr Input
Definition: Visitor.h:41
armarx::aron::data::BoolPtr
std::shared_ptr< Bool > BoolPtr
Definition: forward_declarations.h:38