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::skills::gui
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  void
91  {
93  // return if check failed
94  if (aronType->getDescriptor() != aron::type::Descriptor::DICT)
95  {
96  return;
97  }
98  // iterate through children; memorize keys
99  std::map<QString, std::vector<int>> found_keys;
100  auto numChildren = childCount();
101  for (int i = 0; i < numChildren; ++i)
102  {
103  auto* casted = AronTreeWidgetItem::DynamicCastAndCheck(child(i));
104  if (!casted)
105  {
106  // soft error here, we already report it above. - Definetly programming error
107  continue;
108  }
109  auto& vec = found_keys[casted->text(0)];
110  vec.push_back(i);
111  }
112  // highlight keys that conflict
113  // memorize children that are not ok
114  std::set<int> errorneous_indices;
115  for (auto [key, vals] : found_keys)
116  {
117  if (vals.size() > 1)
118  {
119  for (int i : vals)
120  {
121  auto* casted = AronTreeWidgetItem::DynamicCastAndCheck(child(i));
122  if (!casted)
123  {
124  // soft error here, we already report it above. - Definetly programming error
125  continue;
126  }
127  casted->setKeyErrorState(true);
128  errorneous_indices.emplace(i);
129  }
130  }
131  }
132  // clear potential error state of other elements
133  for (int i = 0; i < numChildren; ++i)
134  {
135  if (errorneous_indices.find(i) != errorneous_indices.end())
136  {
137  continue;
138  }
139  auto* casted = AronTreeWidgetItem::DynamicCastAndCheck(child(i));
140  if (!casted)
141  {
142  // soft error here, we already report it above. - Definetly programming error
143  continue;
144  }
145  casted->setKeyErrorState(false);
146  }
147  }
148 
149  void
151  {
152  QTreeWidgetItem* qParent = QTreeWidgetItem::parent();
153  ARMARX_CHECK(qParent);
154  AronTreeWidgetItem* aronParent = DynamicCast(qParent);
155  if (changedColumn == 0)
156  {
157  if (col0Editable)
158  {
159  // Topmost should always be an Object and col0 is not editable in the child then...
160  // -> aronParent should never be nullptr
161  ARMARX_CHECK(aronParent);
162  // check if the element is child of a dict. If so, validate uniqueness of keys
163  if (aronParent->aronType->getDescriptor() == aron::type::Descriptor::DICT)
164  {
165  aronParent->checkKeyValidityOfChildren();
166  }
167  }
168  else
169  {
170  // maybe while editing keys, we try to edit a key that should not change by tabbing.
171  // Catch that here and undo the edit
172  preventIllegalKeyChange();
173  }
174  }
175  }
176 
177  void
178  AronTreeWidgetItem::preventIllegalKeyChange()
179  {
180  if (!col0Editable)
181  {
182  setText(0, unchangeableKey);
183  }
184  }
185 
187  bool editVal,
188  QString key,
189  aron::type::VariantPtr type) :
190  aronType(type), col0Editable(editKey), col1Editable(editVal)
191  {
192  this->setText(0, key);
193  // add hook to check for edited keys for children of dictionaries
194  if (!editKey)
195  {
196  unchangeableKey = std::move(key);
197  }
198  }
199 
200 } // namespace armarx::skills::gui
armarx::aron::type::VariantPtr
std::shared_ptr< Variant > VariantPtr
Definition: forward_declarations.h:11
armarx::skills::gui::AronTreeWidgetItem::col0Editable
const bool col0Editable
Definition: AronTreeWidgetItem.h:32
armarx::skills::gui::AronTreeWidgetItem::checkKeyValidityOfChildren
void checkKeyValidityOfChildren()
Definition: AronTreeWidgetItem.cpp:90
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
armarx::skills::gui::AronTreeWidgetItem::setKeyErrorState
void setKeyErrorState(bool hasError)
Definition: AronTreeWidgetItem.cpp:64
armarx::skills::gui::CustomWidget::DynamicCast
static CustomWidget * DynamicCast(QWidget *)
Definition: CustomWidget.cpp:18
armarx::skills::gui::AronTreeWidgetItem::onUserChange
void onUserChange(int changedColumn)
Definition: AronTreeWidgetItem.cpp:150
All.h
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::skills::gui::AronTreeWidgetItem::setValueErrorState
void setValueErrorState(bool isErrorSource, bool isTransitiveError)
Definition: AronTreeWidgetItem.cpp:39
armarx::skills::gui::gui_color_palette::getIndirectErrorPalette
QPalette getIndirectErrorPalette()
Definition: ColorPalettes.cpp:24
armarx::skills::gui::AronTreeWidgetItem::resetError
void resetError()
Definition: AronTreeWidgetItem.cpp:76
armarx::skills::gui::AronTreeWidgetItem::aronType
aron::type::VariantPtr aronType
Definition: AronTreeWidgetItem.h:30
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::skills::gui::AronTreeWidgetItem::AronTreeWidgetItem
AronTreeWidgetItem(bool editKey, bool editVal, QString key, aron::type::VariantPtr type)
Definition: AronTreeWidgetItem.cpp:186
ColorPalettes.h
armarx::skills::gui::AronTreeWidgetItem::DynamicCast
static AronTreeWidgetItem * DynamicCast(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:15
armarx::skills::gui
Definition: PeriodicUpdateWidget.cpp:11
armarx::skills::gui::AronTreeWidgetItem::isValueErrorneous
bool isValueErrorneous()
Definition: AronTreeWidgetItem.cpp:33
armarx::aron::type::Descriptor::DICT
@ DICT
armarx::skills::gui::gui_color_palette::getErrorPalette
QPalette getErrorPalette()
Definition: ColorPalettes.cpp:6
armarx::skills::gui::AronTreeWidgetItem
Definition: AronTreeWidgetItem.h:19
AronTreeWidgetItem.h
armarx::skills::gui::AronTreeWidgetItem::DynamicCastAndCheck
static AronTreeWidgetItem * DynamicCastAndCheck(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:21
armarx::skills::gui::gui_color_palette::getNormalPalette
QPalette getNormalPalette()
Definition: ColorPalettes.cpp:14