AronTreeWidgetItem.cpp
Go to the documentation of this file.
1 #include "AronTreeWidgetItem.h"
2 
3 #include <QAction>
4 #include <QMenu>
5 
7 
8 #include "../ColorPalettes.h"
9 #include "visitors/AronTreeWidgetConverter.h"
10 #include "widgets/CustomWidget.h"
11 
12 namespace armarx
13 {
14  AronTreeWidgetItem*
15  AronTreeWidgetItem::DynamicCast(QTreeWidgetItem* i)
16  {
17  return dynamic_cast<AronTreeWidgetItem*>(i);
18  }
19 
22  {
23  if (!i)
24  {
25  return nullptr;
26  }
27  auto c = DynamicCast(i);
29  return c;
30  }
31 
32  bool
34  {
35  return itemValueError;
36  }
37 
38  void
39  AronTreeWidgetItem::setValueErrorState(bool isErrorSource, bool isTransitiveError)
40  {
41  itemValueError |= isErrorSource;
42  transitiveValueError |= isTransitiveError;
43 
44 
45  if (CustomWidget::DynamicCast(treeWidget()->itemWidget(this, 1)))
46  {
47  // The widgets handle errors themselves
48  return;
49  }
50  auto palette = gui_color_palette::getNormalPalette();
51  if (itemValueError)
52  {
54  }
55  else if (transitiveValueError)
56  {
58  }
59 
60  QTreeWidgetItem::setBackground(1, QBrush(palette.color(QPalette::Base)));
61  }
62 
63  void
65  {
66  ARMARX_CHECK(col0Editable); //only editable keys should call this function!
67  auto palette =
69 
70  keyValueError = hasError;
71 
72  QTreeWidgetItem::setBackground(1, QBrush(palette.color(QPalette::Base)));
73  }
74 
75  void
77  {
78  keyValueError = false;
79  itemValueError = false;
80  transitiveValueError = false;
81  // also reset children
82  for (int i = 0; i < childCount(); ++i)
83  {
84  auto* arChild = AronTreeWidgetItem::DynamicCastAndCheck(QTreeWidgetItem::child(i));
85  arChild->resetError();
86  }
87  }
88 
89 
90  void
92  {
94  // return if check failed
95  if (aronType->getDescriptor() != aron::type::Descriptor::DICT)
96  {
97  return;
98  }
99  // iterate through children; memorize keys
100  std::map<QString, std::vector<int>> found_keys;
101  auto numChildren = childCount();
102  for (int i = 0; i < numChildren; ++i)
103  {
104  auto* casted = AronTreeWidgetItem::DynamicCastAndCheck(child(i));
105  if (!casted)
106  {
107  // soft error here, we already report it above. - Definetly programming error
108  continue;
109  }
110  auto& vec = found_keys[casted->text(0)];
111  vec.push_back(i);
112  }
113  // highlight keys that conflict
114  // memorize children that are not ok
115  std::set<int> errorneous_indices;
116  for (auto [key, vals] : found_keys)
117  {
118  if (vals.size() > 1)
119  {
120  for (int i : vals)
121  {
122  auto* casted = AronTreeWidgetItem::DynamicCastAndCheck(child(i));
123  if (!casted)
124  {
125  // soft error here, we already report it above. - Definetly programming error
126  continue;
127  }
128  casted->setKeyErrorState(true);
129  errorneous_indices.emplace(i);
130  }
131  }
132  }
133  // clear potential error state of other elements
134  for (int i = 0; i < numChildren; ++i)
135  {
136  if (errorneous_indices.find(i) != errorneous_indices.end())
137  {
138  continue;
139  }
140  auto* casted = AronTreeWidgetItem::DynamicCastAndCheck(child(i));
141  if (!casted)
142  {
143  // soft error here, we already report it above. - Definetly programming error
144  continue;
145  }
146  casted->setKeyErrorState(false);
147  }
148  }
149 
150  void
152  {
153  QTreeWidgetItem* qParent = QTreeWidgetItem::parent();
154  ARMARX_CHECK(qParent);
155  AronTreeWidgetItem* aronParent = DynamicCast(qParent);
156  if (changedColumn == 0)
157  {
158  if (col0Editable)
159  {
160  // Topmost should always be an Object and col0 is not editable in the child then...
161  // -> aronParent should never be nullptr
162  ARMARX_CHECK(aronParent);
163  // check if the element is child of a dict. If so, validate uniqueness of keys
164  if (aronParent->aronType->getDescriptor() == aron::type::Descriptor::DICT)
165  {
166  aronParent->checkKeyValidityOfChildren();
167  }
168  }
169  else
170  {
171  // maybe while editing keys, we try to edit a key that should not change by tabbing.
172  // Catch that here and undo the edit
173  preventIllegalKeyChange();
174  }
175  }
176  }
177 
178  void
179  AronTreeWidgetItem::preventIllegalKeyChange()
180  {
181  if (!col0Editable)
182  {
183  setText(0, unchangeableKey);
184  }
185  }
186 
188  bool editVal,
189  QString key,
190  aron::type::VariantPtr type) :
191  aronType(type), col0Editable(editKey), col1Editable(editVal)
192  {
193  this->setText(0, key);
194  // add hook to check for edited keys for children of dictionaries
195  if (!editKey)
196  {
197  unchangeableKey = std::move(key);
198  }
199  }
200 
201 } // namespace armarx
armarx::AronTreeWidgetItem::checkKeyValidityOfChildren
void checkKeyValidityOfChildren()
Definition: AronTreeWidgetItem.cpp:91
armarx::aron::type::VariantPtr
std::shared_ptr< Variant > VariantPtr
Definition: forward_declarations.h:11
armarx::AronTreeWidgetItem::resetError
void resetError()
Definition: AronTreeWidgetItem.cpp:76
AronTreeWidgetItem.h
armarx::gui_color_palette::getErrorPalette
QPalette getErrorPalette()
Definition: ColorPalettes.cpp:6
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
All.h
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::gui_color_palette::getIndirectErrorPalette
QPalette getIndirectErrorPalette()
Definition: ColorPalettes.cpp:23
armarx::AronTreeWidgetItem::setKeyErrorState
void setKeyErrorState(bool hasError)
Definition: AronTreeWidgetItem.cpp:64
armarx::AronTreeWidgetItem::DynamicCastAndCheck
static AronTreeWidgetItem * DynamicCastAndCheck(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:21
armarx::AronTreeWidgetItem::col0Editable
const bool col0Editable
Definition: AronTreeWidgetItem.h:32
armarx::AronTreeWidgetItem::setValueErrorState
void setValueErrorState(bool isErrorSource, bool isTransitiveError)
Definition: AronTreeWidgetItem.cpp:39
armarx::AronTreeWidgetItem::DynamicCast
static AronTreeWidgetItem * DynamicCast(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:15
armarx::aron::type::Descriptor::DICT
@ DICT
armarx::AronTreeWidgetItem::isValueErrorneous
bool isValueErrorneous()
Definition: AronTreeWidgetItem.cpp:33
armarx::AronTreeWidgetItem::onUserChange
void onUserChange(int changedColumn)
Definition: AronTreeWidgetItem.cpp:151
armarx::gui_color_palette::getNormalPalette
QPalette getNormalPalette()
Definition: ColorPalettes.cpp:13
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::AronTreeWidgetItem::AronTreeWidgetItem
AronTreeWidgetItem(bool editKey, bool editVal, QString key, aron::type::VariantPtr type)
Definition: AronTreeWidgetItem.cpp:187
armarx::CustomWidget::DynamicCast
static CustomWidget * DynamicCast(QWidget *)
Definition: CustomWidget.cpp:18