AronTreeWidgetItem.cpp
Go to the documentation of this file.
2
3#include <QAction>
4#include <QMenu>
5
7
8#include "ColorPalettes.h"
11
12namespace armarx::skills::gui
13{
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 }
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
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,
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::skills::gui
constexpr T c
AronTreeWidgetItem(bool editKey, bool editVal, QString key, aron::type::VariantPtr type)
void setValueErrorState(bool isErrorSource, bool isTransitiveError)
static AronTreeWidgetItem * DynamicCast(QTreeWidgetItem *)
static AronTreeWidgetItem * DynamicCastAndCheck(QTreeWidgetItem *)
static CustomWidget * DynamicCast(QWidget *)
#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...
std::shared_ptr< Variant > VariantPtr