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 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
47namespace 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
121 aron::data::visit(v, value);
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 {
144 aron::data::visit(v, value);
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<uint8_t>(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<uint16_t>(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<uint32_t>(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<int8_t>(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 {
281 quatWidget->setText((QuaternionWidget::QuaternionComponents)i, toString(i));
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
#define float
Definition 16_Level.h:22
aron::type::VariantPtr aronType
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)
This file offers overloads of toIce() and fromIce() functions for STL container types.
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)
constexpr auto n() noexcept
typename VisitorBase< const data::VariantPtr >::Input Input
Definition Visitor.h:66