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
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 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,
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
constexpr T c
AronTreeWidgetItem(bool editKey, bool editVal, QString key, aron::type::VariantPtr type)
aron::type::VariantPtr aronType
void setValueErrorState(bool isErrorSource, bool isTransitiveError)
void onUserChange(int changedColumn)
void setKeyErrorState(bool hasError)
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
This file offers overloads of toIce() and fromIce() functions for STL container types.