ObserverWidget.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package
19 * @author
20 * @date
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#include "ObserverWidget.h"
25
26#include <boost/regex.hpp>
27
28#include <QAction>
29#include <QItemSelectionModel>
30#include <QList>
31#include <QMenu>
32
37
38#include <ArmarXGui/gui-plugins/ObserverPropertiesPlugin/ui_FilterPropertiesDialog.h>
40
43
44namespace armarx
45{
47 {
48 this->controller = controller;
49 qRegisterMetaType<DatafieldFilterBasePtr>("DatafieldFilterBasePtr");
50 ui.setupUi(this);
51 ui.propertiesView->setLayout(new QVBoxLayout());
52 ui.observerTreeView->setSortingEnabled(true);
53 //ui.observerTreeView->setHideChildren(false);
54
55 propertiesWidget = 0;
56
57 updateTimer = new QTimer(this);
58
59 connect(ui.observerTreeView,
60 SIGNAL(customContextMenuRequested(const QPoint&)),
61 this,
62 SLOT(treeView_contextMenu(const QPoint&)));
63
64 QList<int> sizes;
65 sizes.append(400);
66 sizes.append(800);
67
68 ui.splitter->setSizes(sizes);
69
70 autoUpdateAction = new QAction("Auto update", ui.observerTreeView);
71
72 filterExpansionTimer.setSingleShot(true);
73 connect(&filterExpansionTimer, SIGNAL(timeout()), this, SLOT(delayedFilterExpansion()));
74 }
75
76 void
78 {
79 model = new ObserverItemModel(controller->getIceManager(), controller->getVariantInfo());
80 proxyModel = new InfixFilterModel(this);
81 proxyModel->setSourceModel(model);
82 ui.observerTreeView->setModel(proxyModel);
83 proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
84 connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateObservers()));
85 QItemSelectionModel* selectionModel = ui.observerTreeView->selectionModel();
86 connect(selectionModel,
87 SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
88 this,
89 SLOT(treeView_selected(const QItemSelection&, const QItemSelection&)));
90 // updateObservers();
91
92 connect(ui.lineEditSearch,
93 SIGNAL(textChanged(QString)),
94 proxyModel,
95 SLOT(setFilterFixedString(QString)));
96 connect(ui.lineEditSearch,
97 SIGNAL(textChanged(QString)),
98 this,
99 SLOT(expandFilterSelection(QString)),
100 Qt::QueuedConnection);
101 }
102
103 void
105 {
106 if (model)
107 {
108 model->updateObservers();
109 }
110
111 auto selection = ui.observerTreeView->selectionModel()->selectedIndexes();
112
113 if (selection.size() > 0)
114 {
115 if (propertiesWidget)
116 {
117 ui.propertiesView->layout()->removeWidget(propertiesWidget);
118 propertiesWidget->deleteLater();
119 propertiesWidget = NULL;
120 }
121 auto tempWidgetPtr = model->getPropertiesWidget(
122 proxyModel->mapToSource(selection.at(0)), ui.propertiesView);
123 if (tempWidgetPtr)
124 {
125 propertiesWidget = tempWidgetPtr;
126 ui.propertiesView->layout()->addWidget(propertiesWidget);
127 propertiesWidget->show();
128 }
129 }
130 }
131
132 void
133 ObserverWidget::treeView_selected(const QItemSelection& selected,
134 const QItemSelection& deselected)
135 {
136 if (selected.indexes().size() == 0)
137 {
138 return;
139 }
140
141 if (propertiesWidget)
142 {
143 ui.propertiesView->layout()->removeWidget(propertiesWidget);
144 propertiesWidget->deleteLater();
145 propertiesWidget = NULL;
146 }
147
148 QModelIndexList list = selected.indexes();
149 propertiesWidget =
150 model->getPropertiesWidget(proxyModel->mapToSource(list.at(0)), ui.propertiesView);
151 ui.propertiesView->layout()->addWidget(propertiesWidget);
152 propertiesWidget->show();
153 }
154
155 void
157 {
158 if (checked)
159 {
160 updateTimer->start(500);
161 }
162 else
163 {
164 updateTimer->stop();
165 }
166 }
167
168 void
170 {
171 QAction* action = qobject_cast<QAction*>(sender());
172 if (action)
173 {
174 // auto widget = qobject_cast<DataFieldPropertiesWidget*>(propertiesWidget);
175 DatafieldFilterBasePtr filter;
176 if (!action->data().isNull())
177 {
178 auto filterName = action->data().toString().toStdString();
179 auto valFac =
180 controller->getIceManager()->getCommunicator()->getValueFactoryManager()->find(
181 filterName);
182 if (!valFac)
183 {
184 ARMARX_WARNING << "Could not find obj factory of type " << filterName;
185 return;
186 }
187
188 filter = DatafieldFilterBasePtr::dynamicCast(valFac->create(filterName));
189 if (!filter)
190 {
191 ARMARX_WARNING << "Could not create filter of type " << valFac;
192 return;
193 }
194 }
195 else
196 {
197 ARMARX_ERROR << "Filter " << action->text().toStdString() << " is unknown";
198 return;
199 }
200 QDialog d;
201 Ui::FilterPropertiesDialog dSetup;
202 dSetup.setupUi(&d);
203 dSetup.tableWidget->setSortingEnabled(false);
204 StringFloatDictionary props = filter->getProperties();
205 ARMARX_INFO << VAROUT(props);
206 dSetup.tableWidget->setRowCount(props.size());
207 dSetup.tableWidget->setColumnCount(2);
208 int i = 0;
209 for (auto& p : props)
210 {
211 auto keyItem = new QTableWidgetItem(p.first.c_str());
212 keyItem->setFlags(Qt::ItemIsEnabled);
213 dSetup.tableWidget->setItem(i, 0, keyItem);
214 auto valueItem = new QTableWidgetItem(QString::number(p.second));
215 dSetup.tableWidget->setItem(i, 1, valueItem);
216 i++;
217 }
218 dSetup.groupBox->setTitle(action->text() + " properties");
219 if (d.exec() == QDialog::Accepted)
220 {
221 props.clear();
222 for (int i = 0; i < dSetup.tableWidget->rowCount(); ++i)
223 {
224 bool ok;
225 float value = dSetup.tableWidget->item(i, 1)->text().toFloat(&ok);
226 if (ok)
227 {
228 props[dSetup.tableWidget->item(i, 0)->text().toStdString()] = value;
229 }
230 }
231 ARMARX_INFO << VAROUT(props);
232 filter->setProperties(props);
233 emit createFilterClicked(selectedFilterId, filter);
234 }
235 }
236 selectedFilterId.clear();
237 }
238
239 void
241 {
242 if (propertiesWidget)
243 {
244 ui.propertiesView->layout()->removeWidget(propertiesWidget);
245 propertiesWidget->deleteLater();
246 propertiesWidget = NULL;
247 }
248 }
249
250 void
252 {
253 QPoint globalPos = ui.observerTreeView->viewport()->mapToGlobal(point);
254 QMenu treeViewMenu;
255
256 // update action
257 QAction* updateAction = new QAction("Update", ui.observerTreeView);
258
259 if (autoUpdateAction->isChecked())
260 {
261 updateAction->setEnabled(false);
262 }
263
264 connect(updateAction, SIGNAL(triggered()), this, SLOT(updateObservers()));
265 treeViewMenu.addAction(updateAction);
266
267 // // auto update action
268 // autoUpdateAction->setCheckable(true);
269 // connect(autoUpdateAction, SIGNAL(toggled(bool)), this, SLOT(toggleAutoUpdate(bool)));
270 // treeViewMenu.addAction(autoUpdateAction);
271
273 qobject_cast<DataFieldPropertiesWidget*>(propertiesWidget);
274 if (widget)
275 {
276 auto typeId = widget->getVariant()->getType();
277 selectedFilterId = widget->getDatafieldIdentifier()->getIdentifierStr();
278 QMenu* filters = treeViewMenu.addMenu("Filters");
279 std::map<std::string, bool> filterNames;
280 for (const FactoryCollectionBasePtr& facContainer :
282 {
283 if (!facContainer)
284 {
285 continue;
286 }
287 for (auto pair : facContainer->getFactories())
288 {
289
290 Ice::ValueFactoryPtr fac = pair.second;
291 if (!fac)
292 {
293 continue;
294 }
295 try
296 {
297 auto obj = fac->create(pair.first);
298 if (!obj)
299 {
300 continue;
301 }
302 // auto ids = obj->ice_ids();
303 // auto it = std::find(ids.begin(), ids.end(), "::armarx::DatafieldFilterBase");
304 DatafieldFilterBasePtr filter = DatafieldFilterBasePtr::dynamicCast(obj);
305 if (filter)
306 {
307 auto supportedTypes = filter->getSupportedTypes();
308 auto typeIt =
309 std::find(supportedTypes.begin(), supportedTypes.end(), typeId);
310 filterNames.insert(
311 std::make_pair(pair.first, typeIt != supportedTypes.end()));
312 }
313 }
314 catch (...)
315 {
316 }
317 }
318 }
319 for (auto filter : filterNames)
320 {
321 const boost::regex e("::armarx::([a-zA-Z0-9_]+)Base");
322 boost::match_results<std::string::const_iterator> what;
323 boost::regex_search(filter.first, what, e);
324 QAction* a;
325 if (what.size() < 2)
326 {
327 a = filters->addAction(filter.first.c_str(), this, SLOT(filterSelected()));
328 }
329 else
330 {
331 std::string filteredName = what[1];
332 a = filters->addAction(filteredName.c_str(), this, SLOT(filterSelected()));
333 }
334 a->setEnabled(filter.second);
335 if (!filter.second)
336 {
337 a->setToolTip("This filter does not support this type");
338 }
339 a->setData(filter.first.c_str());
340 }
341 }
342
343 // show menu
344 QAction* selectedItem = treeViewMenu.exec(globalPos);
345
346
347 if (selectedItem)
348 {
349 // something was chosen, do stuff
350 }
351 else
352 {
353 // nothing was chosen
354 }
355 }
356
357 void
358 ObserverWidget::expandFilterSelection(QString filterStr)
359 {
360 //ARMARX_INFO_S << VAROUT(filterStr);
361 if (filterStr.length() == 0)
362 {
363 ui.observerTreeView->collapseAll();
364 // ui.monitoredManagersTree->expandToDepth(1);
365 }
366 else
367 {
368 filterExpansionTimer.start(500);
369 }
370 }
371
372 void
373 ObserverWidget::delayedFilterExpansion()
374 {
375 InfixFilterModel::ExpandFilterResults(ui.observerTreeView);
376 }
377} // namespace armarx
#define VAROUT(x)
DataFieldIdentifierPtr getDatafieldIdentifier() const
static const std::vector< FactoryCollectionBasePtr > & GetPreregistratedFactories()
This proxy model reimplements the filterAcceptsRow function with a new behavior: All elements that fi...
static void ExpandFilterResults(QTreeView *treeView)
Expands the treeview that all items that match the filterstring are expanded and directly visible.
ObserverWidget(ObserverWidgetController *controller)
void createFilterClicked(const std::string &datafieldStr, DatafieldFilterBasePtr filter)
void treeView_selected(const QItemSelection &selected, const QItemSelection &deselected)
void toggleAutoUpdate(bool checked)
void treeView_contextMenu(const QPoint &point)
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< FactoryCollectionBase > FactoryCollectionBasePtr