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 
39  std::stringstream ss;
40  const char* locale = "C";
41  ss.imbue(std::locale(locale));
42  ss << std::fixed << std::setprecision(precision) << number;
43 
44  return ss.str();
45 }
46 
47 //visitors
48 namespace armarx::skills::gui
49 {
50  bool
51  AronTreeWidgetSetterVisitor::checkTreeWidgetItemForSimilarName(const std::string& name) const
52  {
53  QTreeWidgetItem* el = parentItem->child(index);
54 
55  // do not check attribute name, if the element is part of a list or map
56  auto* castedThis = AronTreeWidgetItem::DynamicCast(el->parent());
57  if (castedThis)
58  {
59  auto descr = castedThis->aronType->getDescriptor();
61  {
62  return true;
63  }
64  }
65  std::string n = el->text(0).toStdString();
66  if (name != n)
67  {
68  ARMARX_WARNING_S << "Could not set a tree widget value for the element with key '"
69  << name << "' because it is different from the expected name '" << n
70  << "'.";
71  return false;
72  }
73  return true;
74  }
75 
76  void
77  AronTreeWidgetSetterVisitor::adjustNumberOfChildren(AronTreeWidgetItem* parent,
78  size_t numChildren)
79  {
80  if (((size_t)parent->childCount()) < numChildren)
81  {
82  // The type to create must be the only child of the current aron type
83  ARMARX_CHECK_EQUAL(parent->aronType->childrenSize(), 1);
84  size_t childrenToAdd = numChildren - parent->childCount();
85  for (size_t j = 0; j < childrenToAdd; ++j)
86  {
87  AronTreeWidgetCreatorVisitor childCreator(parent);
88  aron::type::visit(childCreator, parent->aronType->getChildren()[0]);
89  ARMARX_CHECK_NOT_NULL(childCreator.createdQWidgetItem);
90  }
91  }
92  else if ((size_t)parent->childCount() > numChildren)
93  {
94  size_t numChilds = (size_t)parent->childCount() - numChildren;
95  // pop the last child
96  for (size_t j = 0; j < numChilds; ++j)
97  {
98  parent->removeChild(parent->child(parent->childCount() - 1));
99  }
100  }
101  }
102 
103  void
105  {
106 
107  // either it is the root or it has a name
108  if (i->getPath().size() == 0 ||
109  checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
110  {
112  auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el);
113  // allocate enough child items
114  adjustNumberOfChildren(aronTreeWidget, i->childrenSize());
115 
116  // write child values
117  unsigned int x = 0;
118  for (const auto& [key, value] : i->getElements())
119  {
120  el->child(x)->setText(0, {key.c_str()});
121 
124  }
125 
126  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
127  {
128  el->setCheckState(2, Qt::CheckState::Checked);
129  }
130  }
131  }
132 
133  void
135  {
136 
137  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
138  {
140  auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el);
141  adjustNumberOfChildren(aronTreeWidget, i->childrenSize());
142 
143  unsigned int x = 0;
144  for (const auto& value : i->getElements())
145  {
148  auto* currChild = el->child(x);
149  std::string listNum = usString(x);
150  currChild->setText(0, listNum.c_str());
151 
152  ++x;
153  }
154  // This displays the number of children also when the list is collapsed
155  QString numElemsText = misc::generateNumElementsText(i->getElements().size());
156  aronTreeWidget->setText(1, numElemsText);
157  // set italic
158  auto currFont = aronTreeWidget->font(1);
159  currFont.setItalic(true);
160  aronTreeWidget->setFont(1, currFont);
161 
162  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
163  {
164  el->setCheckState(2, Qt::CheckState::Checked);
165  }
166  }
167  }
168 
169  void
171  const std::shared_ptr<armarx::aron::type::Matrix>& matrixType,
172  const aron::data::NDArrayPtr& arr)
173  {
174 
175  auto elemType = matrixType->getElementType();
176  auto* rawData = arr->getData();
177  // string can convert any item
178  auto toString = [elemType, rawData](size_t elementNr) -> std::string
179  {
180  switch (elemType)
181  {
182  case aron::type::matrix::ElementType::FLOAT32:
183  {
184  static_assert(sizeof(float) == 4);
185  float* interpreted = reinterpret_cast<float*>(rawData);
186  float laundered = std::launder(interpreted)[elementNr];
187  return usString<float>(laundered);
188  }
189  case aron::type::matrix::ElementType::FLOAT64:
190  {
191  static_assert(sizeof(double) == 8);
192  double* interpreted = reinterpret_cast<double*>(rawData);
193  float laundered = std::launder(interpreted)[elementNr];
194  return usString<double>(laundered);
195  }
196  case aron::type::matrix::ElementType::UINT8:
197  {
198  auto* interpreted = reinterpret_cast<uint8_t*>(rawData);
199  auto laudered = std::launder(interpreted)[elementNr];
200  return usString<>(laudered);
201  }
202  case aron::type::matrix::ElementType::UINT16:
203  {
204  auto* interpreted = reinterpret_cast<uint16_t*>(rawData);
205  auto laudered = std::launder(interpreted)[elementNr];
206  return usString<>(laudered);
207  }
208  case aron::type::matrix::ElementType::UINT32:
209  {
210  auto* interpreted = reinterpret_cast<uint32_t*>(rawData);
211  auto laudered = std::launder(interpreted)[elementNr];
212  return usString<>(laudered);
213  }
214  case aron::type::matrix::ElementType::INT8:
215  {
216  auto* interpreted = reinterpret_cast<int8_t*>(rawData);
217  auto laudered = std::launder(interpreted)[elementNr];
218  return usString<>(laudered);
219  }
220  case aron::type::matrix::ElementType::INT16:
221  {
222  int16_t* interpreted = reinterpret_cast<int16_t*>(rawData);
223  int16_t laudered = std::launder(interpreted)[elementNr];
224  return usString<int16_t>(laudered);
225  }
226  case aron::type::matrix::ElementType::INT32:
227  {
228  int32_t* interpreted = reinterpret_cast<int32_t*>(rawData);
229  int32_t laudered = std::launder(interpreted)[elementNr];
230  return usString<int32_t>(laudered);
231  }
232  case aron::type::matrix::ElementType::INT64:
233  {
234  int64_t* interpreted = reinterpret_cast<int64_t*>(rawData);
235  int64_t laudered = std::launder(interpreted)[elementNr];
236  return usString<int64_t>(laudered);
237  }
238  }
239  return "Error!";
240  };
241 
242 
243  for (size_t row = 0; (int)row < matrixType->getRows(); ++row)
244  {
245  for (size_t col = 0; (int)col < matrixType->getCols(); ++col)
246  {
247  matrixWidget->setText(row, col, toString(col * matrixType->getRows() + row));
248  }
249  }
250  }
251 
252  void
254  std::shared_ptr<armarx::aron::type::Quaternion>& quatType,
255  const aron::data::NDArrayPtr& arr)
256  {
257 
258  auto elemType = quatType->getElementType();
259  auto rawData = arr->getData();
260  auto shape = arr->getShape();
261  // string can convert any item
262  auto toString = [elemType, rawData](size_t elementNr) -> std::string
263  {
264  switch (elemType)
265  {
266  case aron::type::quaternion::ElementType::FLOAT32:
267  {
268  static_assert(sizeof(float) == 4);
269  float* interpreted = reinterpret_cast<float*>(rawData);
270  float laundered = std::launder(interpreted)[elementNr];
271  return usString<float>(laundered);
272  }
273  case aron::type::quaternion::ElementType::FLOAT64:
274  {
275  static_assert(sizeof(double) == 8);
276  double* interpreted = reinterpret_cast<double*>(rawData);
277 
278  float laundered = std::launder(interpreted)[elementNr];
279  return usString<double>(laundered);
280  }
281  }
282  return "Error!";
283  };
284  for (size_t i = 0; i < 4; ++i)
285  {
287  }
288  }
289 
290  void
292  {
293 
294  // Matrices are handled as NDArray. Raw ndarrays cannot be created currently
296  ARMARX_CHECK(el);
297 
298  auto matrixCast = aron::type::Matrix::DynamicCast(el->aronType);
299  auto quaternionCast = aron::type::Quaternion::DynamicCast(el->aronType);
300 
301  auto* rootWidget = el->treeWidget();
302  ARMARX_CHECK(rootWidget);
303  auto* matrixWidget = EditMatrixWidget::DynamicCast(rootWidget->itemWidget(el, 1));
304  auto* quaternionWidget = QuaternionWidget::DynamicCast(rootWidget->itemWidget(el, 1));
305 
306  if (matrixCast && matrixWidget)
307  {
308  visitMatrix(matrixWidget, matrixCast, arr);
309  }
310  else if (quaternionCast && quaternionWidget)
311  {
312  visitQuaternion(quaternionWidget, quaternionCast, arr);
313  }
314  else
315  {
317  << "we do not support raw NDArrays. Ask Fabian Peller for more information.";
318  }
319 
320  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
321  {
322  el->setCheckState(2, Qt::CheckState::Checked);
323  }
324  }
325 
326  void
328  {
329 
330  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
331  {
333  auto* enumWidget = IntEnumWidget::DynamicCast(el->treeWidget()->itemWidget(el, 1));
334  auto newText = QString::fromStdString(usString<int>(i->getValue()));
335  if (enumWidget)
336  {
337  // Its an IntEnum! -> Ask the custom widget
338  enumWidget->setText(newText);
339  }
340  else
341  {
342  // Its just an int. -> do the QTreeWidgetItem call
343  el->setText(1, newText);
344  }
345 
346  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
347  {
348  el->setCheckState(2, Qt::CheckState::Checked);
349  }
350  }
351  }
352 
353  void
355  {
356 
357  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
358  {
360  el->setText(1, QString::fromStdString(usString<long>(i->getValue())));
361 
362  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
363  {
364  el->setCheckState(2, Qt::CheckState::Checked);
365  }
366  }
367  }
368 
369  void
371  {
372  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
373  {
375  std::string repr = usString<float>(i->getValue());
376  QString qstr = QString::fromStdString(repr);
377  el->setText(1, qstr);
378  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
379  {
380  el->setCheckState(2, Qt::CheckState::Checked);
381  }
382  }
383  }
384 
385  void
387  {
388 
389  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
390  {
392  el->setText(1, QString::fromStdString(usString<double>(i->getValue())));
393 
394  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
395  {
396  el->setCheckState(2, Qt::CheckState::Checked);
397  }
398  }
399  }
400 
401  void
403  {
404 
405  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
406  {
408  el->setText(1, QString::fromStdString(usString<bool>(i->getValue())));
409 
410  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
411  {
412  el->setCheckState(2, Qt::CheckState::Checked);
413  }
414  }
415  }
416 
417  void
419  {
420 
421  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
422  {
424  el->setText(1, QString::fromStdString(i->getValue()));
425 
426  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
427  {
428  el->setCheckState(2, Qt::CheckState::Checked);
429  }
430  }
431  }
432 
433  void
435  {
436  ARMARX_WARNING_S << "Received an unknown type when trying to set a skill argument type "
437  "from an aron data object.";
438  }
439 } // 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:170
AronTreeWidgetSetter.h
armarx::skills::gui::QuaternionWidget::setText
void setText(QuaternionComponents col, const std::string &str)
Definition: QuaternionWidget.cpp:34
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
qstr
QString qstr(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:50
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:39
armarx::skills::gui::EditMatrixWidget
Definition: EditMatrixWidget.h:21
armarx::skills::gui::AronTreeWidgetSetterVisitor::index
int index
Definition: AronTreeWidgetSetter.h:41
armarx::skills::gui::QuaternionWidget::DynamicCast
static QuaternionWidget * DynamicCast(QWidget *)
Definition: QuaternionWidget.cpp:16
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:253
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:855
armarx::aron::type::detail::SpecializedVariantBase< type::dto::Matrix, Matrix >::DynamicCast
static Matrix & DynamicCast(Variant &n)
Definition: SpecializedVariant.h:101
armarx::skills::gui
Definition: PeriodicUpdateWidget.cpp:11
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::skills::gui::AronTreeWidgetSetterVisitor::visitAronVariant
virtual void visitAronVariant(const aron::data::DictPtr &) final
Definition: AronTreeWidgetSetter.cpp:104
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
armarx::skills::gui::QuaternionWidget
Definition: QuaternionWidget.h:21
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:30
armarx::aron::similarity::FloatSimilarity::NONE
@ NONE
Definition: FloatSimilarity.h:14
armarx::skills::gui::AronTreeWidgetSetterVisitor::visitUnknown
void visitUnknown(Input &) final
Definition: AronTreeWidgetSetter.cpp:434
armarx::viz::toString
const char * toString(InteractionFeedbackType type)
Definition: Interaction.h:28
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:136
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:39
T
float T
Definition: UnscentedKalmanFilterTest.cpp:38
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