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
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::INT16:
193  {
194  int16_t* interpreted = reinterpret_cast<int16_t*>(rawData);
195  int16_t laudered = std::launder(interpreted)[elementNr];
196  return usString<int16_t>(laudered);
197  }
198  case aron::type::matrix::ElementType::INT32:
199  {
200  int32_t* interpreted = reinterpret_cast<int32_t*>(rawData);
201  int32_t laudered = std::launder(interpreted)[elementNr];
202  return usString<int32_t>(laudered);
203  }
204  case aron::type::matrix::ElementType::INT64:
205  {
206  int64_t* interpreted = reinterpret_cast<int64_t*>(rawData);
207  int64_t laudered = std::launder(interpreted)[elementNr];
208  return usString<int64_t>(laudered);
209  }
210  }
211  return "Error!";
212  };
213 
214 
215  for (size_t row = 0; (int)row < matrixType->getRows(); ++row)
216  {
217  for (size_t col = 0; (int)col < matrixType->getCols(); ++col)
218  {
219  matrixWidget->setText(row, col, toString(col * matrixType->getRows() + row));
220  }
221  }
222  }
223 
224  void
226  std::shared_ptr<armarx::aron::type::Quaternion>& quatType,
227  const aron::data::NDArrayPtr& arr)
228  {
229  auto elemType = quatType->getElementType();
230  auto rawData = arr->getData();
231  auto shape = arr->getShape();
232  // string can convert any item
233  auto toString = [elemType, rawData](size_t elementNr) -> std::string
234  {
235  switch (elemType)
236  {
237  case aron::type::quaternion::ElementType::FLOAT32:
238  {
239  static_assert(sizeof(float) == 4);
240  float* interpreted = reinterpret_cast<float*>(rawData);
241  float laundered = std::launder(interpreted)[elementNr];
242  return usString<float>(laundered);
243  }
244  case aron::type::quaternion::ElementType::FLOAT64:
245  {
246  static_assert(sizeof(double) == 8);
247  double* interpreted = reinterpret_cast<double*>(rawData);
248 
249  float laundered = std::launder(interpreted)[elementNr];
250  return usString<double>(laundered);
251  }
252  }
253  return "Error!";
254  };
255  for (size_t i = 0; i < 4; ++i)
256  {
258  }
259  }
260 
261  void
263  {
264  // Matrices are handled as NDArray. Raw ndarrays cannot be created currently
266  ARMARX_CHECK(el);
267 
268  auto matrixCast = aron::type::Matrix::DynamicCast(el->aronType);
269  auto quaternionCast = aron::type::Quaternion::DynamicCast(el->aronType);
270 
271  auto* rootWidget = el->treeWidget();
272  ARMARX_CHECK(rootWidget);
273  auto* matrixWidget = EditMatrixWidget::DynamicCast(rootWidget->itemWidget(el, 1));
274  auto* quaternionWidget = QuaternionWidget::DynamicCast(rootWidget->itemWidget(el, 1));
275 
276  if (matrixCast && matrixWidget)
277  {
278  visitMatrix(matrixWidget, matrixCast, arr);
279  }
280  else if (quaternionCast && quaternionWidget)
281  {
282  visitQuaternion(quaternionWidget, quaternionCast, arr);
283  }
284  else
285  {
287  << "we do not support raw NDArrays. Ask Fabian Peller for more information.";
288  }
289 
290  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
291  {
292  el->setCheckState(1, Qt::CheckState::Checked);
293  }
294  }
295 
296  void
298  {
299  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
300  {
302  auto* enumWidget = IntEnumWidget::DynamicCast(el->treeWidget()->itemWidget(el, 1));
303  auto newText = QString::fromStdString(usString<int>(i->getValue()));
304  if (enumWidget)
305  {
306  // Its an IntEnum! -> Ask the custom widget
307  enumWidget->setText(newText);
308  }
309  else
310  {
311  // Its just an int. -> do the QTreeWidgetItem call
312  el->setText(1, newText);
313  }
314 
315  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
316  {
317  el->setCheckState(1, Qt::CheckState::Checked);
318  }
319  }
320  }
321 
322  void
324  {
325  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
326  {
328  el->setText(1, QString::fromStdString(usString<long>(i->getValue())));
329 
330  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
331  {
332  el->setCheckState(1, Qt::CheckState::Checked);
333  }
334  }
335  }
336 
337  void
339  {
340  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
341  {
343  el->setText(1, QString::fromStdString(usString<float>(i->getValue())));
344 
345  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
346  {
347  el->setCheckState(1, Qt::CheckState::Checked);
348  }
349  }
350  }
351 
352  void
354  {
355  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
356  {
358  el->setText(1, QString::fromStdString(usString<double>(i->getValue())));
359 
360  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
361  {
362  el->setCheckState(1, Qt::CheckState::Checked);
363  }
364  }
365  }
366 
367  void
369  {
370  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
371  {
373  el->setText(1, QString::fromStdString(usString<bool>(i->getValue())));
374 
375  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
376  {
377  el->setCheckState(1, Qt::CheckState::Checked);
378  }
379  }
380  }
381 
382  void
384  {
385  if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
386  {
388  el->setText(1, QString::fromStdString(i->getValue()));
389 
390  if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
391  {
392  el->setCheckState(1, Qt::CheckState::Checked);
393  }
394  }
395  }
396 
397  void
399  {
400  ARMARX_WARNING_S << "Received an unknown type when trying to set a skill argument type "
401  "from an aron data object.";
402  }
403 } // namespace armarx
armarx::QuaternionWidget
Definition: QuaternionWidget.h:17
armarx::EditMatrixWidget::setText
void setText(long row, long col, const std::string &str)
Definition: EditMatrixWidget.cpp:104
armarx::AronTreeWidgetItem
Definition: AronTreeWidgetItem.h:19
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::AronTreeWidgetSetterVisitor::parentItem
QTreeWidgetItem * parentItem
Definition: AronTreeWidgetSetter.h:40
armarx::aron::data::LongPtr
std::shared_ptr< Long > LongPtr
Definition: forward_declarations.h:26
AronTreeWidgetContextMenu.h
armarx::aron::type::Descriptor::LIST
@ LIST
armarx::visitQuaternion
void visitQuaternion(QuaternionWidget *quatWidget, std::shared_ptr< armarx::aron::type::Quaternion > &quatType, const aron::data::NDArrayPtr &arr)
Definition: AronTreeWidgetSetter.cpp:225
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::QuaternionWidget::DynamicCast
static QuaternionWidget * DynamicCast(QWidget *)
Definition: QuaternionWidget.cpp:13
armarx::misc::generateNumElementsText
QString generateNumElementsText(int num)
Definition: ListDictHelper.cpp:6
armarx::AronTreeWidgetSetterVisitor::visitUnknown
void visitUnknown(Input &) final
Definition: AronTreeWidgetSetter.cpp:398
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::EditMatrixWidget::DynamicCast
static EditMatrixWidget * DynamicCast(QWidget *)
Definition: EditMatrixWidget.cpp:86
armarx::AronTreeWidgetSetterVisitor::visitAronVariant
virtual void visitAronVariant(const aron::data::DictPtr &) final
Definition: AronTreeWidgetSetter.cpp:103
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::visitMatrix
void visitMatrix(EditMatrixWidget *matrixWidget, const std::shared_ptr< armarx::aron::type::Matrix > &matrixType, const aron::data::NDArrayPtr &arr)
Definition: AronTreeWidgetSetter.cpp:167
armarx::IntEnumWidget::DynamicCast
static IntEnumWidget * DynamicCast(QWidget *)
Definition: IntEnumWidget.cpp:38
armarx::QuaternionWidget::setText
void setText(QuaternionComponents col, const std::string &str)
Definition: QuaternionWidget.cpp:31
armarx::AronTreeWidgetItem::DynamicCastAndCheck
static AronTreeWidgetItem * DynamicCastAndCheck(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:21
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::QuaternionWidget::QuaternionComponents
QuaternionComponents
Definition: QuaternionWidget.h:26
armarx::AronTreeWidgetSetterVisitor::index
int index
Definition: AronTreeWidgetSetter.h:41
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
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::aron::similarity::FloatSimilarity::NONE
@ NONE
Definition: FloatSimilarity.h:11
armarx::AronTreeWidgetItem::DynamicCast
static AronTreeWidgetItem * DynamicCast(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:15
armarx::viz::toString
const char * toString(InteractionFeedbackType type)
Definition: Interaction.h:27
armarx::AronTreeWidgetSetterVisitor
Definition: AronTreeWidgetSetter.h:37
armarx::EditMatrixWidget
Definition: EditMatrixWidget.h:19
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::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
AronTreeWidgetCreator.h
armarx::aron::data::ListPtr
std::shared_ptr< List > ListPtr
Definition: List.h:40
armarx::aron::data::VisitorBase< const data::VariantPtr >::Input
const data::VariantPtr Input
Definition: Visitor.h:41
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::AronTreeWidgetItem::aronType
aron::type::VariantPtr aronType
Definition: AronTreeWidgetItem.h:30
armarx::aron::data::BoolPtr
std::shared_ptr< Bool > BoolPtr
Definition: forward_declarations.h:38
AronTreeWidgetSetter.h