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
24
25#include <string>
26
27#include "../ListDictHelper.h"
33
34template <typename T>
35std::string
36usString(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
48namespace 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
123 aron::data::visit(v, value);
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 {
147 aron::data::visit(v, value);
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(row * matrixType->getCols() + col));
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 {
286 quatWidget->setText((QuaternionWidget::QuaternionComponents)i, toString(i));
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
#define float
Definition 16_Level.h:22
QString qstr(const T &t)
static AronTreeWidgetItem * DynamicCast(QTreeWidgetItem *)
static AronTreeWidgetItem * DynamicCastAndCheck(QTreeWidgetItem *)
virtual void visitAronVariant(const aron::data::DictPtr &) final
static EditMatrixWidget * DynamicCast(QWidget *)
void setText(long row, long col, const std::string &str)
static IntEnumWidget * DynamicCast(QWidget *)
static QuaternionWidget * DynamicCast(QWidget *)
void setText(QuaternionComponents col, const std::string &str)
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#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...
#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...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
std::string usString(T number, size_t precision=3)
std::shared_ptr< Dict > DictPtr
Definition Dict.h:42
std::shared_ptr< List > ListPtr
Definition List.h:41
std::shared_ptr< Bool > BoolPtr
std::shared_ptr< Float > FloatPtr
std::shared_ptr< NDArray > NDArrayPtr
Definition NDArray.h:46
std::shared_ptr< Long > LongPtr
std::shared_ptr< Int > IntPtr
void visit(VisitorImplementation &v, typename VisitorImplementation::Input &o)
Definition Visitor.h:136
std::shared_ptr< Double > DoublePtr
std::shared_ptr< String > StringPtr
void visit(VisitorImplementation &v, typename VisitorImplementation::Input &t)
The visit function.
Definition Visitor.h:39
QString generateNumElementsText(int num)
void visitQuaternion(QuaternionWidget *quatWidget, std::shared_ptr< armarx::aron::type::Quaternion > &quatType, const aron::data::NDArrayPtr &arr)
void visitMatrix(EditMatrixWidget *matrixWidget, const std::shared_ptr< armarx::aron::type::Matrix > &matrixType, const aron::data::NDArrayPtr &arr)
This file offers overloads of toIce() and fromIce() functions for STL container types.
constexpr auto n() noexcept
typename VisitorBase< const data::VariantPtr >::Input Input
Definition Visitor.h:66