QueryWidget.cpp
Go to the documentation of this file.
1#include "QueryWidget.h"
2
3#include <limits>
4#include <mutex>
5
6#include <QCheckBox>
7#include <QGroupBox>
8#include <QHBoxLayout>
9#include <QLabel>
10#include <QLineEdit>
11#include <QPushButton>
12#include <QScrollArea>
13#include <QSpinBox>
14#include <QTabWidget>
15#include <QVBoxLayout>
16#include <QSignalBlocker>
17
19
20namespace armarx::armem::gui
21{
22
24 {
25 auto* vlayout = new QVBoxLayout();
26 auto* hlayout = new QHBoxLayout();
27
28 {
29 _availableMemoriesGroupBox = new QGroupBox("Available memories");
30 auto vboxlayout = new QVBoxLayout();
31 vboxlayout->setMargin(1);
32 vboxlayout->setSizeConstraint(QLayout::SizeConstraint::SetMinAndMaxSize);
33 vboxlayout->setAlignment(Qt::AlignTop);
34 _de_selectMemoryServers = new QPushButton(_selectText);
35 _de_selectMemoryServers->setEnabled(false);
36 vboxlayout->addWidget(_de_selectMemoryServers);
37 _availableMemoriesGroupBox->setLayout(vboxlayout);
38
39 // make _availableMemoriesGroupBox scrollable
40 _availableMemoriesScrollArea = new QScrollArea();
41 _availableMemoriesScrollArea->setWidget(_availableMemoriesGroupBox);
42 _availableMemoriesScrollArea->setWidgetResizable(true);
43
44 hlayout->addWidget(_availableMemoriesScrollArea);
45 }
46
47 QFrame* vFrame = new QFrame;
48 vFrame->setFrameShape(QFrame::VLine);
49 hlayout->addWidget(vFrame);
50
51 {
52 _additionalSettingsGroupBox = new QGroupBox("Additional query settings");
53 auto vboxlayout = new QVBoxLayout();
54 vboxlayout->setMargin(1);
55 vboxlayout->setSizeConstraint(QLayout::SizeConstraint::SetMinAndMaxSize);
56 vboxlayout->setAlignment(Qt::AlignTop);
57 _additionalSettingsGroupBox->setLayout(vboxlayout);
58
59 _dataCheckBox = new QCheckBox("Get Data");
60 _dataCheckBox->setChecked(true);
61 vboxlayout->addWidget(_dataCheckBox);
62
63 _dropRemovedCheckBox = new QCheckBox("Drop disconnected memories");
64 _dropRemovedCheckBox->setChecked(true);
65 vboxlayout->addWidget(_dropRemovedCheckBox);
66
67 _dropDisabledCheckBox = new QCheckBox("Drop disabled memories");
68 _dropDisabledCheckBox->setChecked(false);
69 vboxlayout->addWidget(_dropDisabledCheckBox);
70
71 auto* recDepthHLayout = new QHBoxLayout();
72 _recursionDepthLabel = new QLabel("Link resolution depth:");
73 recDepthHLayout->addWidget(_recursionDepthLabel);
74 _recursionDepthLabel->setFixedWidth(200);
75
76 _recursionDepthSpinner = new QSpinBox(); // NOLINT
77 _recursionDepthSpinner->setRange(-1, std::numeric_limits<int>::max());
78 _recursionDepthSpinner->setValue(0);
79 _recursionDepthSpinner->setEnabled(_dataCheckBox->isChecked());
80 _recursionDepthSpinner->setSpecialValueText(QString("Unlimited"));
81 recDepthHLayout->addWidget(_recursionDepthSpinner);
82 recDepthHLayout->addStretch();
83 vboxlayout->addLayout(recDepthHLayout);
84
85 hlayout->addWidget(_additionalSettingsGroupBox);
86 }
87 vlayout->addLayout(hlayout);
88
89 // Private connections.
90 connect(
91 _dataCheckBox, &QCheckBox::stateChanged, this, &This::setRecursionDepthSpinnerEnabled);
92
93 connect(_de_selectMemoryServers, &QPushButton::pressed, this, &This::deSelectMemoryServers);
94
95 connect(_recursionDepthSpinner,
96 qOverload<int>(&QSpinBox::valueChanged),
97 this,
98 [this](int val) { emit recursionDepthChanged(val); });
99
100 connect(_dropRemovedCheckBox,
101 &QCheckBox::toggled,
102 this,
104
105 connect(_dropDisabledCheckBox,
106 &QCheckBox::toggled,
107 this,
109
110 connect(_dataCheckBox,
111 &QCheckBox::toggled,
112 this,
114
115 setLayout(vlayout);
116 }
117
118 void
119 QueryWidget::update(const std::vector<std::string>& activeMemoryNames)
120 {
121 {
122 std::scoped_lock l(enabledMemoriesMutex);
123 std::vector<std::string> alreadyPresentMemoryCheckboxes;
124
125 // get information about memories already present and activate inactive ones if necessary
126 int maxIndex = _availableMemoriesGroupBox->layout()
127 ->count(); //as the (de)select button is counted as well
128
129 for (int i = 1; i < maxIndex; ++i)
130 {
131 auto w = _availableMemoriesGroupBox->layout()->itemAt(i)->widget();
132 QCheckBox* box = static_cast<QCheckBox*>(w);
133 QSignalBlocker blocker(box);
134 std::string memoryName = box->text().toStdString();
135 if (box->isEnabled() &&
136 std::find(activeMemoryNames.begin(), activeMemoryNames.end(), memoryName) ==
137 activeMemoryNames.end())
138 {
139 // checkbox is enabled but memory is not available anymore
140 box->setVisible(false);
141 box->setChecked(false);
142 box->setEnabled(false);
143 }
144 if (not(box->isEnabled()) &&
145 std::find(activeMemoryNames.begin(), activeMemoryNames.end(), memoryName) !=
146 activeMemoryNames.end())
147 {
148 // checkbox is disabled but memory is available again
149 box->setVisible(true);
150 box->setChecked(false);
151 box->setEnabled(true);
152 }
153 alreadyPresentMemoryCheckboxes.push_back(memoryName);
154 }
155
156
157 // Add checkboxes for new memories
158 for (const auto& memoryName : activeMemoryNames)
159 {
160 if (std::find(alreadyPresentMemoryCheckboxes.begin(),
161 alreadyPresentMemoryCheckboxes.end(),
162 memoryName) == alreadyPresentMemoryCheckboxes.end())
163 {
164 // new memory available
165 auto box = new QCheckBox(QString::fromStdString(memoryName));
166 box->setChecked(
167 false); // we do not want all memories to be enabled on startup, to reduce communication overhead
168 box->setVisible(true);
169 box->setEnabled(true);
170 _availableMemoriesGroupBox->layout()->addWidget(box);
171
172 // necessary to select the correct select/deselect button
173 connect(box, &QCheckBox::stateChanged, this, &This::updateSelectAllButtonState);
174 connect(box, &QCheckBox::toggled, this, &This::activeMemoriesChanged);
175 }
176 }
177
178 // activate/deactivate button
179 _de_selectMemoryServers->setEnabled(!activeMemoryNames.empty());
180 }
181 // signals cannot be within the lock scope, otherwise potential deadlocks
183 }
184
187 {
188 return _dataCheckBox->isChecked() ? armem::query::DataMode::WithData
190 }
191
192 bool
194 {
195 return _dropRemovedCheckBox->isChecked();
196 }
197
198 bool
200 {
201 return _dropDisabledCheckBox->isChecked();
202 }
203
204 std::map<std::string, armem::gui::ActiveMemoryState>
206 {
207 std::scoped_lock l(enabledMemoriesMutex);
208
209 std::map<std::string, armem::gui::ActiveMemoryState> states;
210 int maxIndex = _availableMemoriesGroupBox->layout()->count();
211 for (int i = 1; i < maxIndex; ++i)
212 {
213 auto w = _availableMemoriesGroupBox->layout()->itemAt(i)->widget();
214 QCheckBox* box = static_cast<QCheckBox*>(w);
215 std::string memoryName = box->text().toStdString();
216 if (box->isEnabled() && box->isChecked())
217 {
219 }
220 else if (box->isEnabled() && !box->isChecked())
221 {
223 }
224 else
225 {
226 states[memoryName] = armem::gui::ActiveMemoryState::NotFound;
227 }
228 }
229 return states;
230 }
231
232 int
234 {
235 return _recursionDepthSpinner->value();
236 }
237
238 void
239 QueryWidget::setRecursionDepthSpinnerEnabled(int state)
240 {
241 switch (state)
242 {
243 case Qt::Checked:
244 _recursionDepthSpinner->setEnabled(true);
245 break;
246 case Qt::Unchecked:
247 default:
248 _recursionDepthSpinner->setEnabled(false);
249 break;
250 }
251 }
252
253 void
254 QueryWidget::deSelectMemoryServers()
255 {
256 if (!_allMemoryServersSelected)
257 {
258 //ARMARX_INFO << "Selecting all memory servers";
259 //not all servers are selected -> select all memory servers:
260 std::scoped_lock l(enabledMemoriesMutex);
261
262 // get information about memories already present and activate inactive ones if necessary
263 int maxIndex = _availableMemoriesGroupBox->layout()
264 ->count(); //as the (de)select button is counted as well
265 for (int i = 1; i < maxIndex; ++i)
266 {
267 auto w = _availableMemoriesGroupBox->layout()->itemAt(i)->widget();
268 QCheckBox* box = static_cast<QCheckBox*>(w);
269 QSignalBlocker blocker(box);
270 box->setChecked(true);
271 }
272 //set variables and text:
273 _allMemoryServersSelected = true;
274 _de_selectMemoryServers->setText(_deselectText);
275 }
276 else
277 {
278 //ARMARX_INFO << "Deselecting all memory servers";
279 //memories should be deselected:
280 std::scoped_lock l(enabledMemoriesMutex);
281
282 // get information about memories already present and activate inactive ones if necessary
283 int maxIndex = _availableMemoriesGroupBox->layout()
284 ->count(); //as the (de)select button is counted as well
285 for (int i = 1; i < maxIndex; ++i)
286 {
287 auto w = _availableMemoriesGroupBox->layout()->itemAt(i)->widget();
288 QCheckBox* box = static_cast<QCheckBox*>(w);
289 QSignalBlocker blocker(box);
290 box->setChecked(false);
291 }
292
293 _allMemoryServersSelected = false;
294 _de_selectMemoryServers->setText(_selectText);
295 }
296 // necessary after using QSignalBlocker
298 }
299
300 void
301 QueryWidget::updateSelectAllButtonState()
302{
303
304 int maxIndex = _availableMemoriesGroupBox->layout()->count();
305 bool allSelected = true;
306
307 for (int i = 1; i < maxIndex; ++i)
308 {
309 auto w = _availableMemoriesGroupBox->layout()->itemAt(i)->widget();
310 QCheckBox* box = static_cast<QCheckBox*>(w);
311
312 if (box->isEnabled() && !box->isChecked())
313 {
314 allSelected = false;
315 break;
316 }
317 }
318
319 _allMemoryServersSelected = allSelected;
320 _de_selectMemoryServers->setText(allSelected ? _deselectText : _selectText);
321}
322
323} // namespace armarx::armem::gui
void recursionDepthChanged(int value)
armem::query::DataMode dataMode() const
std::map< std::string, armem::gui::ActiveMemoryState > getAvailableMemoryStates() const
void update(const std::vector< std::string > &memoryNames)
@ WithData
Get structure and ARON data.
Definition DataMode.h:9
@ NoData
Just get the structure, but no ARON data.
Definition DataMode.h:8