TypedDataTreeBuilder.cpp
Go to the documentation of this file.
1 #include "TypedDataTreeBuilder.h"
2 
3 #include <QTreeWidgetItem>
4 
5 #include <RobotAPI/libraries/armem/aron/MemoryID.aron.generated.h>
15 
17 {
18 
20  {
21  }
22 
23  void
24  TypedDataTreeBuilder::updateTree(QTreeWidgetItem* parent,
25  const aron::type::Dict& type,
26  const aron::data::Dict& data)
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,
47  const aron::data::Dict& data)
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,
67  const aron::data::Dict& data)
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  {
76  MemoryIDTreeWidgetItem* item =
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
180  TypedDataTreeBuilder::updateDispatch(QTreeWidgetItem* item,
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 
242  MemoryID id = aron::fromAron<MemoryID>(dto);
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 
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
sanitize_typename.h
armarx::aron::type::AnyObject
The AnyObject class.
Definition: AnyObject.h:37
armarx::aron::type::Pair::getAcceptedTypes
std::pair< VariantPtr, VariantPtr > getAcceptedTypes() const
Definition: Pair.cpp:44
armarx::aron::type::VariantPtr
std::shared_ptr< Variant > VariantPtr
Definition: forward_declarations.h:11
armarx::aron::type::Object::getMemberType
VariantPtr getMemberType(const std::string &) const
Definition: Object.cpp:128
TypedDataTreeBuilder.h
armarx::VariantType::List
const VariantContainerType List
Definition: SingleTypeVariantList.h:191
armarx::armem::gui::instance::sanitizeTypeName
std::string sanitizeTypeName(const std::string &typeName)
Definition: sanitize_typename.cpp:29
armarx::aron::TypedDataDisplayVisitor::getValue
static std::string getValue(const type::VariantPtr &type, const data::VariantPtr &data)
Definition: TypedDataDisplayVisitor.cpp:20
armarx::conversions::cast
CvT cast(const auto &pt)
Definition: opencv.h:32
armarx::armem::gui::instance::TypedDataTreeBuilder::updateTree
void updateTree(QTreeWidgetItem *parent, const aron::type::Dict &type, const aron::data::Dict &data)
Definition: TypedDataTreeBuilder.cpp:24
MemoryID.h
armarx::armem::gui::instance::TypedDataTreeBuilder::TypedDataTreeBuilder
TypedDataTreeBuilder()
Definition: TypedDataTreeBuilder.cpp:19
armarx::aron::type::List
The List class.
Definition: List.h:39
armarx::aron::type::Object
The Object class.
Definition: Object.h:42
armarx::aron::data::List
Definition: List.h:43
armarx::aron::data::detail::SpecializedVariantBase< data::dto::Dict, Dict >::DynamicCastAndCheck
static PointerType DynamicCastAndCheck(const VariantPtr &n)
Definition: SpecializedVariant.h:135
TreeWidgetBuilder.h
armarx::aron::type::Tuple
The Tuple class.
Definition: Tuple.h:39
armarx::aron::data::detail::SpecializedVariantBase< data::dto::Dict, Dict >::DynamicCast
static PointerType DynamicCast(const VariantPtr &n)
Definition: SpecializedVariant.h:117
armarx::aron::data::VariantPtr
std::shared_ptr< Variant > VariantPtr
Definition: forward_declarations.h:11
DataTreeBuilder.h
armarx::TreeWidgetBuilder::updateTreeWithContainer
void updateTreeWithContainer(ParentT *parent, const ContainerT &elements)
Update the tree with the iterable container.
Definition: TreeWidgetBuilder.h:312
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::armem::MemoryID
A memory ID.
Definition: MemoryID.h:47
armarx::armem::gui::instance
Definition: AronDataView.cpp:2
armarx::aron::type::Dict
The Dict class.
Definition: Dict.h:40
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::aron::type::Tuple::getAcceptedTypes
std::vector< VariantPtr > getAcceptedTypes() const
Definition: Tuple.cpp:59
armarx::aron::type::Object::hasMemberType
bool hasMemberType(const std::string &) const
Definition: Object.cpp:180
armarx::TreeWidgetBuilder
A class to efficiently build and maintain sorted items of QTreeWidget or QTreeWidgetItem based on a s...
Definition: DataTreeBuilderBase.h:10
armarx::TreeWidgetBuilder::setUpdateItemFn
void setUpdateItemFn(UpdateItemFn updateItemFn)
Definition: TreeWidgetBuilder.h:57
armarx::aron::type::Pair
The Pair class.
Definition: Pair.h:39
armarx::aron::type::List::getAcceptedType
VariantPtr getAcceptedType() const
Definition: List.cpp:43
armarx::TreeWidgetBuilder::setMakeItemFn
void setMakeItemFn(MakeItemFn makeItemFn)
Definition: TreeWidgetBuilder.h:53
armarx::armem::gui::instance::DataTreeBuilderBase::getDictBuilder
DictBuilder getDictBuilder() const
Definition: DataTreeBuilderBase.cpp:65
armarx::armem::gui::instance::MemoryIDTreeWidgetItem::setInstanceID
void setInstanceID(const MemoryID &id, int valueColumn=1)
Definition: MemoryIDTreeWidgetItem.cpp:22
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::armem::server::ltm::util::mongodb::detail::update
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
Definition: mongodb.cpp:67
aron_conversions.h
armarx::armem::gui::instance::TypedDataTreeBuilder::updateDispatch
void updateDispatch(QTreeWidgetItem *item, const std::string &key, const aron::type::VariantPtr &type, const aron::data::VariantPtr &data)
Definition: TypedDataTreeBuilder.cpp:180
armarx::armem::gui::instance::rawMemoryIDTypeName
const std::string rawMemoryIDTypeName
Definition: sanitize_typename.cpp:10
aron_conversions.h
armarx::armem::gui::instance::serializePath
QStringList serializePath(const aron::Path &path)
Definition: serialize_path.cpp:13
armarx::armem::gui::instance::MemoryIDTreeWidgetItem
Definition: MemoryIDTreeWidgetItem.h:14
TypedDataDisplayVisitor.h
armarx::armem::gui::instance::sanitizedMemoryIDTypeName
const std::string sanitizedMemoryIDTypeName
Definition: sanitize_typename.cpp:11
armarx::armem::gui::instance::DataTreeBuilder::updateTree
void updateTree(QTreeWidgetItem *parent, const aron::data::DictPtr &data)
Definition: DataTreeBuilder.cpp:15
armarx::aron::type::Dict::getAcceptedType
VariantPtr getAcceptedType() const
Definition: Dict.cpp:42
armarx::armem::gui::instance::DataTreeBuilder
Definition: DataTreeBuilder.h:14
armarx::aron::type::IntEnumPtr
std::shared_ptr< IntEnum > IntEnumPtr
Definition: IntEnum.h:36
armarx::armem::gui::instance::DataTreeBuilderBase::makeItem
QTreeWidgetItem * makeItem(const std::string &key) const
Definition: DataTreeBuilderBase.cpp:34
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
MemoryIDTreeWidgetItem.h
serialize_path.h
armarx::aron::data::Dict
Definition: Dict.h:44
armarx::human::MemoryID
const armem::MemoryID MemoryID
Definition: memory_ids.cpp:29