TypedDataTreeBuilder.cpp
Go to the documentation of this file.
2
3#include <QTreeWidgetItem>
4
5#include <RobotAPI/libraries/armem/aron/MemoryID.aron.generated.h>
15
17{
18
22
23 void
24 TypedDataTreeBuilder::updateTree(QTreeWidgetItem* parent,
25 const aron::type::Dict& type,
27 {
28 auto childType = type.getAcceptedType();
29 DictBuilder builder = getDictBuilder();
30 builder.setUpdateItemFn(
31 [this, &childType, &data](const std::string& key, QTreeWidgetItem* item)
32 {
33 auto childData = data.getElement(key);
34 if (childData)
35 {
36 this->updateDispatch(item, key, childType, childData);
37 }
38 return true;
39 });
40
41 builder.updateTreeWithContainer(parent, data.getAllKeys());
42 }
43
44 void
45 TypedDataTreeBuilder::updateTree(QTreeWidgetItem* parent,
46 const aron::type::AnyObject& type,
48 {
49 DictBuilder builder = getDictBuilder();
50 builder.setUpdateItemFn(
51 [this, &data](const std::string& key, QTreeWidgetItem* item)
52 {
53 auto childData = data.getElement(key);
54 if (childData)
55 {
56 this->updateDispatch(item, key, nullptr, childData);
57 }
58 return true;
59 });
60
61 builder.updateTreeWithContainer(parent, data.getAllKeys());
62 }
63
64 void
65 TypedDataTreeBuilder::updateTree(QTreeWidgetItem* parent,
66 const aron::type::Object& type,
68 {
69 DictBuilder builder = getDictBuilder();
70 builder.setMakeItemFn(
71 [this, &type](const std::string& key) -> QTreeWidgetItem*
72 {
73 if (type.hasMemberType(key) &&
74 type.getMemberType(key)->getFullName() == instance::rawMemoryIDTypeName)
75 {
77 new MemoryIDTreeWidgetItem({QString::fromStdString(key)});
78 item->addKeyChildren();
79 return item;
80 }
81 else
82 {
83 return this->makeItem(key);
84 }
85 });
86 builder.setUpdateItemFn(
87 [this, &type, &data](const std::string& key, QTreeWidgetItem* item)
88 {
89 auto childData = data.getElement(key);
90
91 // We need this check here because getMemberType(key) throws
92 // instead of returning nullptr if the type doesn't have the key.
93 if (type.hasMemberType(key))
94 {
95 this->updateDispatch(item, key, type.getMemberType(key), childData);
96 }
97 else
98 {
99 this->updateDispatch(item, key, nullptr, childData);
100 }
101 return true;
102 });
103
104 builder.updateTreeWithContainer(parent, data.getAllKeys());
105 }
106
107 void
108 TypedDataTreeBuilder::updateTree(QTreeWidgetItem* parent,
109 const aron::type::List& type,
110 const aron::data::List& data)
111 {
112 auto childType = type.getAcceptedType();
113 auto children = data.getChildren();
114
115 ListBuilder builder = getListBuilder();
116 builder.setUpdateItemFn(
117 [this, &children, &childType](size_t key, QTreeWidgetItem* item)
118 {
119 if (auto childData = children.at(key))
120 {
121 this->updateDispatch(item, std::to_string(key), childType, childData);
122 }
123 return true;
124 });
125
126 builder.updateTreeWithContainer(parent, getIndex(children.size()));
127 }
128
129 void
130 TypedDataTreeBuilder::updateTree(QTreeWidgetItem* parent,
131 const aron::type::Pair& type,
132 const aron::data::List& data)
133 {
134 ARMARX_CHECK_EQUAL(data.childrenSize(), 2);
135 auto childTypes = type.getAcceptedTypes();
136
137 ListBuilder builder = getListBuilder();
138 builder.setUpdateItemFn(
139 [this, &data, &childTypes](size_t i, QTreeWidgetItem* item)
140 {
141 auto childType = i == 0 ? childTypes.first : childTypes.second;
142 auto childData = data.getElement(static_cast<unsigned int>(i));
143
144 this->updateDispatch(item, std::to_string(i), childType, childData);
145 return true;
146 });
147
148 builder.updateTreeWithContainer(parent, getIndex(data.childrenSize()));
149 }
150
151 void
152 TypedDataTreeBuilder::updateTree(QTreeWidgetItem* parent,
153 const aron::type::Tuple& type,
154 const aron::data::List& data)
155 {
156 // Allows tuples where the data list is longer than the type tuple -
157 // is that desired behavior?
158
159 auto childTypes = type.getAcceptedTypes();
160
161 ListBuilder builder = getListBuilder();
162 builder.setUpdateItemFn(
163 [this, &data, &childTypes](size_t i, QTreeWidgetItem* item)
164 {
165 auto childType = (i < childTypes.size()) ? childTypes.at(i) : nullptr;
166 auto childData = data.getElement(static_cast<unsigned int>(i));
167
168 this->updateDispatch(item, std::to_string(i), childType, childData);
169 return true;
170 });
171
172 builder.updateTreeWithContainer(parent, getIndex(data.childrenSize()));
173 }
174
175 /*! Used so that elements in the data that don't appear in the type
176 * can still be shown in the GUI if type information is enabled
177 * (otherwise, they would be hidden).
178 */
179 void
181 const std::string& key,
182 const aron::type::VariantPtr& type,
184 {
185 if (type)
186 {
187 this->update(item, key, type, data);
188 }
189 else
190 {
191 this->update(item, key, data);
192 }
193 }
194
195 void
196 TypedDataTreeBuilder::update(QTreeWidgetItem* item,
197 const std::string& key,
198 const aron::type::VariantPtr& type,
200 {
201 using namespace aron;
202
203 const std::string value =
205
206 std::string typeName;
207 if (type::IntEnumPtr enumType = type::IntEnum::DynamicCast(type))
208 {
209 typeName = enumType->getEnumName();
210 }
211 else
212 {
213 typeName = type->getFullName();
214 }
215 typeName = instance::sanitizeTypeName(typeName);
216 switch (type->getMaybe())
217 {
218 case aron::type::Maybe::OPTIONAL:
219 typeName = "Optional[" + typeName + "]";
220 break;
221 default:
222 break;
223 }
224
225 setRowTexts(item, key, value, typeName);
226
227 item->setData(columnKey,
228 Qt::UserRole,
229 data ? instance::serializePath(data->getPath()) : QStringList());
230 item->setData(columnType, Qt::UserRole, static_cast<int>(type->getDescriptor()));
231
232 if (typeName == sanitizedMemoryIDTypeName)
233 {
234 MemoryIDTreeWidgetItem* memoryIDItem = dynamic_cast<MemoryIDTreeWidgetItem*>(item);
235 const auto dictData = aron::data::Dict::DynamicCastAndCheck(data);
236 if (memoryIDItem && dictData)
237 {
238 arondto::MemoryID dto;
239 // Because fromAron does not take refs -.-
240 dto.fromAron(dictData);
241
243 memoryIDItem->setInstanceID(id);
244 return; // Done, no recursion.
245 }
246 }
247
248 // We pass empty containers if data is null so that subitems of the data are deleted.
249 auto emptyDict = aron::data::Dict(type->getPath());
250 auto emptyList = aron::data::List(type->getPath());
251 if (const auto d = aron::data::Dict::DynamicCast(data);
252 const auto t = type::Object::DynamicCast(type))
253 {
254 _updateTree(item, *t, d ? *d : emptyDict);
255 }
256 else if (const auto d = aron::data::Dict::DynamicCast(data);
257 const auto t = type::Dict::DynamicCast(type))
258 {
259 _updateTree(item, *t, d ? *d : emptyDict);
260 }
261 else if (const auto d = aron::data::List::DynamicCast(data);
262 const auto t = type::List::DynamicCast(type))
263 {
264 _updateTree(item, *t, d ? *d : emptyList);
265 }
266 else if (const auto d = aron::data::List::DynamicCast(data);
267 const auto t = type::Pair::DynamicCast(type))
268 {
269 _updateTree(item, *t, d ? *d : emptyList);
270 }
271 else if (const auto d = aron::data::List::DynamicCast(data);
272 const auto t = type::Tuple::DynamicCast(type))
273 {
274 _updateTree(item, *t, d ? *d : emptyList);
275 }
276 else if (const auto d = aron::data::Dict::DynamicCast(data);
277 const auto t = type::AnyObject::DynamicCast(type))
278 {
279 _updateTree(item, *t, d ? *d : emptyDict);
280 }
281 }
282
283 void
284 TypedDataTreeBuilder::update(QTreeWidgetItem* item,
285 const std::string& key,
287 {
288 if (data)
289 {
290 this->setRowTexts(item, key, data);
291
292 item->setData(columnKey,
293 Qt::UserRole,
294 data ? instance::serializePath(data->getPath()) : QStringList());
295
296 if (auto cast = aron::data::Dict::DynamicCast(data))
297 {
298 DataTreeBuilder builder;
299 builder.updateTree(item, cast);
300 }
301 else if (auto cast = aron::data::List::DynamicCast(data))
302 {
303 DataTreeBuilder builder;
304 builder.updateTree(item, cast);
305 }
306 }
307 else
308 {
309 this->setRowTexts(item, key, "(none)");
310 }
311 }
312
313 template <class DataT, class TypeT>
314 void
315 TypedDataTreeBuilder::_updateTree(QTreeWidgetItem* item, TypeT& type, DataT& data)
316 {
317 updateTree(item, type, data);
318 }
319
320} // namespace armarx::armem::gui::instance
std::vector< size_t > getIndex(size_t size) const
armarx::TreeWidgetBuilder< std::string > DictBuilder
armarx::TreeWidgetBuilder< size_t > ListBuilder
void setRowTexts(QTreeWidgetItem *item, const std::string &key, const std::string &value, const std::string &typeName="") const
QTreeWidgetItem * makeItem(const std::string &key) const
void updateTree(QTreeWidgetItem *parent, const aron::data::DictPtr &data)
void setInstanceID(const MemoryID &id, int valueColumn=1)
void updateTree(QTreeWidgetItem *parent, const aron::type::Dict &type, const aron::data::Dict &data)
void updateDispatch(QTreeWidgetItem *item, const std::string &key, const aron::type::VariantPtr &type, const aron::data::VariantPtr &data)
void update(QTreeWidgetItem *item, const std::string &key, const aron::type::VariantPtr &type, const aron::data::VariantPtr &data)
void _updateTree(QTreeWidgetItem *item, TypeT &type, DataT &data)
static std::string getValue(const type::VariantPtr &type, const data::VariantPtr &data)
The AnyObject class.
Definition AnyObject.h:38
The Dict class.
Definition Dict.h:40
VariantPtr getAcceptedType() const
Definition Dict.cpp:42
The List class.
Definition List.h:40
VariantPtr getAcceptedType() const
Definition List.cpp:43
The Object class.
Definition Object.h:43
VariantPtr getMemberType(const std::string &) const
Definition Object.cpp:128
bool hasMemberType(const std::string &) const
Definition Object.cpp:180
The Pair class.
Definition Pair.h:39
std::pair< VariantPtr, VariantPtr > getAcceptedTypes() const
Definition Pair.cpp:44
The Tuple class.
Definition Tuple.h:39
std::vector< VariantPtr > getAcceptedTypes() const
Definition Tuple.cpp:59
#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...
std::string sanitizeTypeName(const std::string &typeName)
QStringList serializePath(const aron::Path &path)
const std::string sanitizedMemoryIDTypeName
std::shared_ptr< Variant > VariantPtr
std::shared_ptr< Variant > VariantPtr
void fromAron(const T &dto, T &bo)
void setUpdateItemFn(UpdateItemFn updateItemFn)
void setMakeItemFn(MakeItemFn makeItemFn)
void updateTreeWithContainer(ParentT *parent, const ContainerT &elements)
Update the tree with the iterable container.