ObserverItemModel.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package ArmarX::Gui
17* @author Kai Welke (welke@kit.edu)
18* @copyright 2012 Humanoids Group, IAIM, IFA
19* @license http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
23
24#include "ObserverItemModel.h"
25
30#include <ArmarXCore/interface/observers/ConditionHandlerInterface.h>
32
36
37namespace armarx
38{
40 QStandardItemModel(0, 1), iceManager(iceManager), info(info)
41
42 {
43
45 }
46
47 void
48 ObserverItemModel::updateModel(const std::string& observerName,
49 const ChannelRegistry& channels,
50 const StringConditionCheckMap& checks)
51 {
52 // update data
53 channelRegistry[observerName] = channels;
54 availableChecks[observerName] = checks;
55 // activeConditions[observerName] = conditions;
56
57 // mark all elements for deletion
58 markAllForDelete(invisibleRootItem());
59
60 // insert observer
61 QStandardItem* observerItem = updateObserver(observerName);
62
63 // update channels
64 updateChannels(getChildByName(observerItem, "channels"), channels);
65
66 // update checks
67 updateChecks(getChildByName(observerItem, "checks"), checks);
68
69 // update conditions
70 // updateConditions(observerItem->child(2), conditions);
71
72 // delete not updated items
73 deleteUnusedItems(observerItem);
74 }
75
76 QWidget*
77 ObserverItemModel::getPropertiesWidget(const QModelIndex& index, QWidget* parent)
78 {
79 QStandardItem* item = itemFromIndex(index);
80 if (!item)
81 {
82 ARMARX_WARNING << "Could not find widget at column " << index.column() << " and row "
83 << index.row();
84 return NULL;
85 }
86 QVariant id = item->data(OBSERVER_ITEM_ID);
87
88 QWidget* widget;
89
90 switch (item->data(OBSERVER_ITEM_TYPE).toInt())
91 {
92 // properties for channel
93 case eChannelItem:
94 {
95 // retrieve registry entry
96 QString channelName = id.toString();
97 QString observerName = item->parent()->parent()->data(OBSERVER_ITEM_ID).toString();
98 ChannelRegistryEntry& entry =
99 channelRegistry[observerName.toLatin1().data()][channelName.toLatin1().data()];
100
101 // create widget
102 widget = new ChannelPropertiesWidget(channelName.toLatin1().data(),
103 observerName.toLatin1().data(),
104 entry.description,
105 parent);
106 break;
107 }
108
109 // properties for datafields
110 case eDataFieldItem:
111 {
112 // retrieve registry entry
113 const DataFieldIdentifier dataFieldIdentifier(id.toString().toLatin1().data());
114
116 channelRegistry.count(dataFieldIdentifier.getObserverName()))
117 << "No channel registry for name '" << dataFieldIdentifier.getObserverName()
118 << "' "
119 << "Available names:\n"
120 << getMapKeys(channelRegistry);
121 ChannelRegistry& chanReg =
122 channelRegistry.at(dataFieldIdentifier.getObserverName());
123
124 ARMARX_CHECK_EXPRESSION(chanReg.count(dataFieldIdentifier.getChannelName()))
125 << "Channel registry '" << dataFieldIdentifier.getObserverName()
126 << "' has no channel '" << dataFieldIdentifier.getChannelName() << "' "
127 << "Available channels:\n"
128 << getMapKeys(chanReg);
129 ChannelRegistryEntry& chanRegEntry =
130 chanReg.at(dataFieldIdentifier.getChannelName());
131
133 chanRegEntry.dataFields.count(dataFieldIdentifier.getDataFieldName()))
134 << "Channel '" << dataFieldIdentifier.getObserverName() << "."
135 << dataFieldIdentifier.getChannelName() << "' has no datafield '"
136 << dataFieldIdentifier.getDataFieldName() << "'. Available datafields:\n"
137 << getMapKeys(chanRegEntry.dataFields);
138 DataFieldRegistryEntry& entry =
139 chanRegEntry.dataFields.at(dataFieldIdentifier.getDataFieldName());
140
141 // create widget
142 DatafieldRefPtr ref = DatafieldRefPtr::dynamicCast(entry.identifier);
143 if (info &&
144 (!entry.value->data || entry.value->data->ice_id() == "::armarx::VariantData"))
145 {
146 ARMARX_INFO << "Variant Factory for " << entry.typeName
147 << " is missing - trying to load lib now";
148 auto lib = info->loadLibraryOfVariant(entry.typeName);
149 if (!lib)
150 {
151 widget = new QWidget(parent);
152 break;
153 }
155 iceManager->getCommunicator());
156 entry.value = ref->getDataField();
157 }
158 widget = new DataFieldPropertiesWidget(entry.description,
159 ref,
160 VariantPtr::dynamicCast(entry.value),
161 iceManager,
162 parent);
163 break;
164 }
165
166 case eCheckItem:
167 {
168 // retrieve check
169 QString checkName = id.toString();
170 QString observerName = item->parent()->parent()->data(OBSERVER_ITEM_ID).toString();
171 ConditionCheckBasePtr check =
172 availableChecks[observerName.toLatin1().data()][checkName.toLatin1().data()];
173
174 // create widget
176 check, checkName.toLatin1().data(), true, false, false, parent);
177
178 break;
179 }
180
181 /* case eConditionItem:
182 {
183 // retrieve check
184 int conditionIndex = id.toInt();
185 QString observerName = item->parent()->parent()->data(OBSERVER_ITEM_ID).toString();
186 ConditionCheckBasePtr condition = activeConditions[observerName.toLatin1().data()][conditionIndex];
187
188 // create widget
189 widget = new ConditionPropertiesWidget(condition, parent);
190
191 break;
192 }
193
194 case eElementaryConditionItem:
195 {
196 // retrieve check
197 int elementId = id.toInt();
198 int conditionIndex = item->parent()->data(OBSERVER_ITEM_ID).toInt();
199 QString observerName = item->parent()->parent()->parent()->data(OBSERVER_ITEM_ID).toString();
200 ConditionCheckBasePtr check = activeConditions[observerName.toLatin1().data()][conditionIndex];
201 ElementaryConditionCheckBasePtr element = check->elementaryChecks[elementId];
202
203 // create widget
204 widget = new ElementaryCheckPropertiesWidget(element, element->condition->checkName, false, true, true, parent);
205
206 break;
207 }*/
208
209 default:
210 widget = new QWidget(parent);
211 break;
212 }
213
214 return widget;
215 }
216
219 {
220 ObserverList list;
221
222 if (!iceManager)
223 {
224 return list;
225 }
226
227 try
228 {
229 ConditionHandlerInterfacePrx handler =
230 iceManager->getProxy<ConditionHandlerInterfacePrx>("ConditionHandler");
231
232 if (handler)
233 {
234 ObserverList registeredObs = handler->getObserverNames();
235 list = registeredObs;
236 }
237 }
238 catch (...)
239 {
240 }
241
242
243 ObserverList globalList =
244 iceManager->getIceGridSession()->getRegisteredObjectNames<ObserverInterfacePrx>(
245 "*Observer");
246 list.insert(list.end(), globalList.begin(), globalList.end());
247 std::sort(list.begin(), list.end());
248 ObserverList::iterator it = std::unique(list.begin(), list.end());
249 list.resize(std::distance(list.begin(), it));
250 return list;
251 }
252
253 void
255 {
256 if (!iceManager)
257 {
258 ARMARX_WARNING_S << "No IceManager set";
259 return;
260 }
261
262 ObserverList observerList = getObservers();
263 ObserverList::iterator iter = observerList.begin();
264
265 while (iter != observerList.end())
266 {
267 ObserverInterfacePrx proxy;
268 try
269 {
270 proxy = iceManager->getProxy<ObserverInterfacePrx>(*iter);
272 *iter,
273 proxy->getAvailableChannels(true),
274 proxy->getAvailableChecks()); //, component->getActiveConditionChecks(*iter));
275 }
276 catch (...)
277 {
278 if (proxy)
279 {
280 iceManager->removeProxyFromCache(proxy);
281 }
282 }
283
284 iter++;
285 }
286 }
287
288 QStandardItem*
289 ObserverItemModel::updateObserver(std::string observerName)
290 {
291 // create observer item
292 QStandardItem* observerItem = new QStandardItem(QString(observerName.c_str()));
293 observerItem->setData(QVariant(eObserverItem), OBSERVER_ITEM_TYPE);
294 observerItem->setData(QVariant(observerName.c_str()), OBSERVER_ITEM_ID);
295 observerItem = updateOrInsertItem(invisibleRootItem(), observerItem);
296
297 // add channels
298 QStandardItem* channelsItem = new QStandardItem(QString("channels"));
299 channelsItem->setData(QVariant(eChannelsItem), OBSERVER_ITEM_TYPE);
300 channelsItem->setData(QVariant("channels"), OBSERVER_ITEM_ID);
301 updateOrInsertItem(observerItem, channelsItem);
302
303 // add checks
304 QStandardItem* checksItem = new QStandardItem(QString("checks"));
305 checksItem->setData(QVariant(eChecksItem), OBSERVER_ITEM_TYPE);
306 checksItem->setData(QVariant("checks"), OBSERVER_ITEM_ID);
307 updateOrInsertItem(observerItem, checksItem);
308
309 // add conditions
310 /* QStandardItem *conditionsItem = new QStandardItem( QString("conditions") );
311 conditionsItem->setData(QVariant(eConditionsItem), OBSERVER_ITEM_TYPE);
312 conditionsItem->setData(QVariant("conditions"), OBSERVER_ITEM_ID);
313 updateOrInsertItem(observerItem, conditionsItem);*/
314
315 return observerItem;
316 }
317
318 void
319 ObserverItemModel::updateChannels(QStandardItem* channelsItem, const ChannelRegistry& channels)
320 {
321 if (!channelsItem)
322 {
323 return;
324 }
325
326 // loop through channelsobser
327 ChannelRegistry::const_iterator iterChannels = channels.begin();
328
329 while (iterChannels != channels.end())
330 {
331 // create item for channels
332 QStandardItem* channelItem =
333 new QStandardItem(QString(iterChannels->second.name.c_str()));
334
335 channelItem->setData(QVariant(eChannelItem), OBSERVER_ITEM_TYPE);
336 channelItem->setData(QVariant(iterChannels->second.name.c_str()), OBSERVER_ITEM_ID);
337
338 // insert channel's item
339 channelItem = updateOrInsertItem(channelsItem, channelItem);
340
341 // loop through datafields
342 DataFieldRegistry::const_iterator iterDataFields =
343 iterChannels->second.dataFields.begin();
344
345 while (iterDataFields != iterChannels->second.dataFields.end())
346 {
347 // create new datafield item
348 std::string datafieldName =
349 iterDataFields->second.identifier->channelRef->observerName + "." +
350 iterDataFields->second.identifier->channelRef->channelName + "." +
351 iterDataFields->second.identifier->datafieldName;
352 QStandardItem* dataFieldItem = new QStandardItem(
353 QString(iterDataFields->second.identifier->datafieldName.c_str()));
354 dataFieldItem->setData(QVariant(eDataFieldItem), OBSERVER_ITEM_TYPE);
355 dataFieldItem->setData(QVariant(datafieldName.c_str()), OBSERVER_ITEM_ID);
356
357 // insert item
358 updateOrInsertItem(channelItem, dataFieldItem);
359 iterDataFields++;
360 }
361
362 iterChannels++;
363 }
364 }
365
366 void
367 ObserverItemModel::updateChecks(QStandardItem* checksItem,
368 const StringConditionCheckMap& checks)
369 {
370 if (!checksItem)
371 {
372 return;
373 }
374
375 StringConditionCheckMap::const_iterator iterChecks = checks.begin();
376
377 while (iterChecks != checks.end())
378 {
379 QStandardItem* checkItem = new QStandardItem(QString(iterChecks->first.c_str()));
380 checkItem->setData(QVariant(eCheckItem), OBSERVER_ITEM_TYPE);
381 checkItem->setData(QVariant(iterChecks->first.c_str()), OBSERVER_ITEM_ID);
382
383 updateOrInsertItem(checksItem, checkItem);
384
385 iterChecks++;
386 }
387 }
388
389 /*
390 void ObserverItemModel::updateConditions(QStandardItem* conditionsItem, const ConditionCheckMap& conditions)
391 {
392 ConditionCheckMap::const_iterator iterConditions = conditions.begin();
393 while(iterConditions != conditions.end())
394 {
395 // update condition
396 QString name = QString("%1").arg(iterConditions->second->info.identifier.uniqueId);
397
398 QStandardItem* conditionItem = new QStandardItem( name );
399 conditionItem->setData(QVariant(eConditionItem), OBSERVER_ITEM_TYPE);
400 conditionItem->setData(QVariant(name), OBSERVER_ITEM_ID);
401
402 conditionItem = updateOrInsertItem(conditionsItem, conditionItem);
403
404 // loop through elementary conditions
405 IntElementaryConditionCheckMap::iterator iterElements = iterConditions->second->elementaryChecks.begin();
406
407 while (iterElements != iterConditions->second->elementaryChecks.end())
408 {
409 // update elementary condition
410 QStandardItem* elementItem = new QStandardItem(iterElements->second->condition->checkName.c_str());
411 elementItem->setData(QVariant(eElementaryConditionItem), OBSERVER_ITEM_TYPE);
412 elementItem->setData(QVariant(iterElements->first), OBSERVER_ITEM_ID);
413
414 updateOrInsertItem(conditionItem, elementItem);
415
416 iterElements++;
417 }
418
419 iterConditions++;
420 }
421 }
422 */
423 QStandardItem*
424 ObserverItemModel::updateOrInsertItem(QStandardItem* parent, QStandardItem* insert)
425 {
426 // loop through childs and compare data
427 for (int r = 0; r < parent->rowCount(); r++)
428 {
429 QStandardItem* item = parent->child(r);
430
431 if (item->data(OBSERVER_ITEM_ID) == insert->data(OBSERVER_ITEM_ID))
432 {
433 delete insert;
434 item->setData(QVariant(false), OBSERVER_ITEM_DELETE);
435 return item;
436 }
437 }
438
439 parent->appendRow(insert);
440
441 insert->setData(QVariant(false), OBSERVER_ITEM_DELETE);
442 return insert;
443 }
444
445 QStandardItem*
446 ObserverItemModel::getChildByName(QStandardItem* item, const QString& name)
447 {
448 for (int r = 0; r < item->rowCount(); r++)
449 {
450 if (item->child(r)->data(OBSERVER_ITEM_ID).toString() == name)
451 {
452 return item->child(r);
453 }
454 }
455
456 return 0;
457 }
458
459 // mark all elements for deletion
460 void
461 ObserverItemModel::markAllForDelete(QStandardItem* observerItem)
462 {
463 int nCount = 0;
464 std::list<QStandardItem*> markList;
465 markList.push_back(observerItem);
466
467 while (markList.size() > 0)
468 {
469 QStandardItem* current = markList.front();
470 markList.pop_front();
471 current->setData(QVariant(true), OBSERVER_ITEM_DELETE);
472 nCount++;
473
474 if (current->hasChildren())
475 {
476 for (int r = 0; r < current->rowCount(); r++)
477 {
478 markList.push_back(current->child(r));
479 }
480 }
481 }
482 }
483
484 void
485 ObserverItemModel::deleteUnusedItems(QStandardItem* observerItem)
486 {
487 std::list<QStandardItem*> searchList;
488 std::vector<int> removeRows;
489
490 searchList.push_back(observerItem);
491
492 while (searchList.size() > 0)
493 {
494 QStandardItem* current = searchList.back();
495 searchList.pop_back();
496
497 if (!current)
498 {
499 continue;
500 }
501
502 // ARMARX_INFO_S << "CurrentItem: " << current->data(OBSERVER_ITEM_ID).toString().toStdString() << " num: " << current->rowCount();
503 if (current->hasChildren())
504 {
505 removeRows.clear();
506
507 for (int r = 0; r < current->rowCount(); r++)
508 {
509 if (current->child(r)->data(OBSERVER_ITEM_DELETE).toBool())
510 {
511 // ARMARX_INFO_S << "Removing row: " << current->child(r)->data(OBSERVER_ITEM_ID).toString().toStdString();
512 removeRows.push_back(r);
513 }
514 else
515 {
516 // ARMARX_INFO_S << "Insert row: " << current->child(r)->data(OBSERVER_ITEM_ID).toString().toStdString();
517 searchList.push_back(current->child(r));
518 }
519 }
520
521 // remove unused rows
522 std::vector<int>::reverse_iterator iter = removeRows.rbegin();
523
524 while (iter != removeRows.rend())
525 {
526 current->removeRow(*iter);
527 iter++;
528 }
529 }
530 }
531 }
532} // namespace armarx
uint8_t index
#define OBSERVER_ITEM_DELETE
#define OBSERVER_ITEM_ID
#define OBSERVER_ITEM_TYPE
static void RegisterKnownObjectFactoriesWithIce(const Ice::CommunicatorPtr &ic)
Registers all object factories that are known with Ice.
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
std::string getObserverName() const
Retrieve observer name.
std::string getChannelName() const
Retrieve channel name.
std::string getDataFieldName() const
Retrieve datafield name.
void updateModel(const std::string &observerName, const ChannelRegistry &channels, const StringConditionCheckMap &checks)
QWidget * getPropertiesWidget(const QModelIndex &index, QWidget *parent)
ObserverItemModel(IceManagerPtr iceManager, VariantInfoPtr info=NULL)
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
bool insert(mongocxx::collection &coll, const nlohmann::json &value)
Definition mongodb.cpp:44
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::vector< std::string > ObserverList
IceInternal::Handle< DatafieldRef > DatafieldRefPtr
Definition Observer.h:43
std::shared_ptr< VariantInfo > VariantInfoPtr
Definition VariantInfo.h:39
void getMapKeys(const MapType &map, OutputIteratorType it)
Definition algorithm.h:173
IceUtil::Handle< IceManager > IceManagerPtr
IceManager smart pointer.
Definition ArmarXFwd.h:39