NJointControllerClassesWidget.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 RobotAPI::gui-plugins::RobotUnitPlugin
17  * \author Raphael Grimm ( raphael dot grimm at kit dot edu )
18  * \date 2017
19  * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
24 
25 #include <filesystem>
26 
27 #include <QDir>
28 #include <QGridLayout>
29 #include <QSortFilterProxyModel>
30 
34 
35 namespace armarx
36 {
38  RobotUnitWidgetTemplateBase("NJointControllerClassesWidget", parent)
39  {
40  connect(ui->pushButtonLoadLib, SIGNAL(released()), this, SLOT(loadLibClicked()));
41  connect(ui->comboBoxPackage,
42  SIGNAL(currentIndexChanged(QString)),
43  this,
44  SLOT(packageEditChanged()));
45  connect(ui->comboBoxPackage,
46  SIGNAL(editTextChanged(QString)),
47  this,
48  SLOT(packageEditChanged()));
49  ui->comboBoxPackage->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
50  ui->comboBoxPackage->setFixedWidth(300);
51 
52  //get package hints
53  {
54  using namespace std::filesystem;
55  std::string homeDir = QDir::homePath().toStdString();
56  path p = path{homeDir} / ".cmake" / "packages";
57  if (is_directory(p))
58  {
59  for (const path& entry : directory_iterator(p))
60  {
61  const std::string pkg = entry.filename().string();
62  if (CMakePackageFinder{pkg, "", true}.packageFound())
63  {
64  ui->comboBoxPackage->addItem(QString::fromStdString(pkg));
65  }
66  }
67  // for sorting you need the following 4 lines
68  QSortFilterProxyModel* proxy = new QSortFilterProxyModel(ui->comboBoxPackage);
69  proxy->setSourceModel(ui->comboBoxPackage->model());
70  // combo's current model must be reparented,
71  // otherwise QComboBox::setModel() will delete it
72  ui->comboBoxPackage->model()->setParent(proxy);
73  ui->comboBoxPackage->setModel(proxy);
74  ui->comboBoxPackage->model()->sort(0);
75  }
76  }
77 
78  ui->comboBoxPackage->setEditText("");
79  packageEditChanged();
80 
81  ui->treeWidget->setColumnCount(2);
82 
83  QTreeWidgetItem* head = ui->treeWidget->headerItem();
84  head->setText(0, "Class");
85  head->setText(1, "");
86  head->setToolTip(0, "Controller class name");
87  ui->treeWidget->header()->setResizeMode(0, QHeaderView::Fixed);
88  ui->treeWidget->header()->setResizeMode(1, QHeaderView::Fixed);
89  }
90 
92  {
93  delete ui;
94  }
95 
96  void
98  {
100  std::unique_lock<std::recursive_timed_mutex> guard{mutex};
101  if (!robotUnit)
102  {
103  return;
104  }
105  ru = robotUnit;
106  guard.unlock();
107  auto data = ru->getNJointControllerClassDescription(name);
108  guard.lock();
109  nJointControllerClassDescriptions[data.className] = std::move(data);
110  if (doMetaCall)
111  {
112  QMetaObject::invokeMethod(this, "updateContent", Qt::QueuedConnection);
113  }
114  }
115 
116  void
118  bool force)
119  {
120  const auto oldName = getDefaultName();
121  if (oldName == createdName || force)
122  {
123  ++defaultControllerName;
124  const auto newName = getDefaultName();
125  for (auto& pair : entries)
126  {
127  pair.second->updateDefaultName(oldName, newName);
128  }
129  }
130  }
131 
132  QString
134  {
135  return QString::number(defaultControllerName);
136  }
137 
138  void
140  {
141  ui->lineEditLibrary->setText(settings->value("classLoadLineEditLib", "").toString());
142  ui->comboBoxPackage->lineEdit()->setText(
143  settings->value("classLoadComboBoxPkg", "").toString());
144  ui->comboBoxLibrary->lineEdit()->setText(
145  settings->value("classLoadComboBoxLib", "").toString());
146  }
147 
148  void
150  {
151  settings->setValue("classLoadLineEditLib", ui->lineEditLibrary->text());
152  settings->setValue("classLoadComboBoxPkg", ui->comboBoxPackage->currentText());
153  settings->setValue("classLoadComboBoxLib", ui->comboBoxLibrary->currentText());
154  }
155 
156  void
158  {
159  entries.clear();
160  nJointControllerClassDescriptions.clear();
161  }
162 
163  void
165  {
166  for (const auto& pair : nJointControllerClassDescriptions)
167  {
168  add(pair.second);
169  }
170  nJointControllerClassDescriptions.clear();
171  }
172 
173  void
175  {
176  auto temp = robotUnit->getNJointControllerClassDescriptions();
177  {
178  std::unique_lock<std::recursive_timed_mutex> guard{mutex};
179  for (NJointControllerClassDescription& ds : temp)
180  {
181  nJointControllerClassDescriptions[ds.className] = std::move(ds);
182  }
183  }
184  }
185 
186  bool
188  {
189  if (nJointControllerClassDescriptions.empty())
190  {
191  return true;
192  }
193  add(nJointControllerClassDescriptions.begin()->second);
194  nJointControllerClassDescriptions.erase(nJointControllerClassDescriptions.begin());
195  return false;
196  }
197 
198  void
199  NJointControllerClassesWidget::filterUpdated()
200  {
201  for (auto& entry : entries)
202  {
203  NJointControllerClassesWidgetEntry* item = entry.second;
204  if (!filterNameActive->isChecked() && !filterRemoteCreationActive->isChecked())
205  {
206  item->setVisible(true);
207  return;
208  }
209  const bool combineOr = (filterCombination->currentText() == "Or");
210  bool showName = !combineOr; //init to neutral element
211  bool showRemote = !combineOr; //init to neutral element
212 
213  if (filterNameActive->isChecked())
214  {
215  showName = (item->matchName(filterName->text()) != filterNameInverted->isChecked());
216  }
217  if (filterRemoteCreationActive->isChecked())
218  {
219  if (item->hasRemoteCreation())
220  {
221  showRemote = (filterRemoteCreation->currentText() != "Without");
222  }
223  else
224  {
225  showRemote = (filterRemoteCreation->currentText() != "With");
226  }
227  }
228  if (combineOr)
229  {
230  item->setVisible(showName || showRemote);
231  }
232  else
233  {
234  item->setVisible(showName && showRemote);
235  }
236  }
237  }
238 
239  void
240  NJointControllerClassesWidget::add(const NJointControllerClassDescription& desc)
241  {
242  std::unique_lock<std::recursive_timed_mutex> guard{mutex};
243  if (entries.count(desc.className))
244  {
245  return;
246  }
247  entries[desc.className] =
248  new NJointControllerClassesWidgetEntry(*this, *(ui->treeWidget), desc, robotUnit);
249  }
250 
251  void
252  NJointControllerClassesWidget::addFilter()
253  {
254  QTreeWidgetItem* filterHeader = new QTreeWidgetItem;
255  ui->treeWidget->addTopLevelItem(filterHeader);
256  filterHeader->setText(0, "Filter");
257 
258  QTreeWidgetItem* filter = new QTreeWidgetItem;
259  filterHeader->addChild(filter);
260  filter->setFirstColumnSpanned(true);
261  QWidget* w = new QWidget;
262  QGridLayout* l = new QGridLayout;
263  w->setLayout(l);
264  l->setContentsMargins(0, 0, 0, 0);
265  l->addItem(new QSpacerItem{0, 0, QSizePolicy::MinimumExpanding}, 0, 3);
266  l->addWidget(new QLabel{"Combine filters with"}, 0, 0, 1, 1);
267  filterCombination = new QComboBox;
268  filterCombination->addItem("Or");
269  filterCombination->addItem("And");
270  l->addWidget(filterCombination, 0, 1, 1, 1);
271 
272  filterNameActive = new QCheckBox;
273  filterNameActive->setText("Filter by name");
274  l->addWidget(filterNameActive, 1, 0, 1, 1);
275 
276  filterName = new QLineEdit;
277  l->addWidget(filterName, 1, 1, 1, 1);
278 
279  filterNameInverted = new QCheckBox;
280  filterNameInverted->setText("Invert filter");
281  l->addWidget(filterNameInverted, 1, 2, 1, 1);
282  connect(filterNameActive, SIGNAL(toggled(bool)), filterName, SLOT(setEnabled(bool)));
283  connect(
284  filterNameActive, SIGNAL(toggled(bool)), filterNameInverted, SLOT(setEnabled(bool)));
285  filterName->setEnabled(false);
286  filterNameInverted->setEnabled(false);
287 
288  filterRemoteCreationActive = new QCheckBox;
289  filterRemoteCreationActive->setText("Filter by remote creation capabilities");
290  l->addWidget(filterRemoteCreationActive, 2, 0, 1, 1);
291  filterRemoteCreation = new QComboBox;
292  filterRemoteCreation->addItem("Both");
293  filterRemoteCreation->addItem("With");
294  filterRemoteCreation->addItem("Without");
295  l->addWidget(filterRemoteCreation, 2, 1, 1, 1);
296  connect(filterRemoteCreationActive,
297  SIGNAL(toggled(bool)),
298  filterRemoteCreation,
299  SLOT(setEnabled(bool)));
300  filterRemoteCreationActive->setEnabled(false);
301 
302  connect(
303  filterCombination, SIGNAL(currentIndexChanged(QString)), this, SLOT(filterUpdated()));
304  connect(filterNameActive, SIGNAL(clicked(bool)), this, SLOT(filterUpdated()));
305  connect(filterRemoteCreationActive, SIGNAL(clicked(bool)), this, SLOT(filterUpdated()));
306  connect(filterNameInverted, SIGNAL(clicked(bool)), this, SLOT(filterUpdated()));
307  connect(filterName, SIGNAL(textChanged(QString)), this, SLOT(filterUpdated()));
308  connect(
309  filterRemoteCreation, SIGNAL(currentIndexChanged(int)), this, SLOT(filterUpdated()));
310 
311  filterNameActive->setChecked(false);
312  filterRemoteCreationActive->setChecked(false);
313 
314  ui->treeWidget->setItemWidget(filter, 0, w);
315  }
316 
319  QTreeWidget& treeWidget,
320  const NJointControllerClassDescription& desc,
322  QObject{&parent},
323  className{desc.className},
324  classNameQStr{QString::fromStdString(className)},
325  robotUnit{robotUnit},
326  parent{&parent}
327  {
328  header = new QTreeWidgetItem{{QString::fromStdString(desc.className)}};
329  treeWidget.addTopLevelItem(header);
330  treeWidget.resizeColumnToContents(0);
331  QWidget* headerW = new QWidget;
332  headerW->setLayout(new QHBoxLayout);
333  headerW->layout()->setContentsMargins(0, 0, 0, 0);
334  headerW->layout()->addItem(new QSpacerItem{0, 0, QSizePolicy::MinimumExpanding});
335  if (desc.configDescription)
336  {
337  //add textfiel + button
338  {
339  nameEdit = new QLineEdit;
340  nameEdit->setText(parent.getDefaultName());
341  nameEdit->setToolTip("The instance name for the created controller instance");
342  headerW->layout()->addWidget(new QLabel{"Controller name"});
343  headerW->layout()->addWidget(nameEdit);
344  QPushButton* button = new QPushButton{"Create"};
345  headerW->layout()->addWidget(button);
346  button->setToolTip("Create a new controller instance of this class");
347  connect(button,
348  &QPushButton::clicked,
349  this,
350  &NJointControllerClassesWidgetEntry::createCtrl);
351  connect(nameEdit,
352  &QLineEdit::returnPressed,
353  this,
354  &NJointControllerClassesWidgetEntry::createCtrl);
355  }
356  //descr
357  {
358  QTreeWidgetItem* child = new QTreeWidgetItem;
359  header->addChild(child);
360  child->setFirstColumnSpanned(true);
361  QWidget* compressWid = new QWidget;
362  QHBoxLayout* compressLay = new QHBoxLayout;
363  compressWid->setLayout(compressLay);
364  compressLay->setContentsMargins(0, 0, 0, 0);
365  creator = WidgetDescription::makeDescribedWidget(desc.configDescription);
366  creator->layout()->setContentsMargins(0, 0, 0, 0);
367  compressLay->addWidget(creator);
368  compressLay->addItem(new QSpacerItem{0, 0, QSizePolicy::MinimumExpanding});
369  treeWidget.setItemWidget(child, 0, compressWid);
370  }
371  }
372  else
373  {
374  //dummy to force the same height for all lines
375  QLineEdit* dummy = new QLineEdit;
376  dummy->setFixedWidth(0);
377  dummy->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
378  headerW->layout()->addWidget(dummy);
379 
380  headerW->layout()->addWidget(new QLabel{"No remote creation allowed."});
381  }
382  treeWidget.setItemWidget(header, 1, headerW);
383  }
384 
385  bool
387  {
388  return classNameQStr.contains(name, Qt::CaseInsensitive);
389  }
390 
391  bool
393  {
394  return creator;
395  }
396 
397  void
399  const QString& newName)
400  {
401  if (nameEdit && nameEdit->text() == oldName)
402  {
403  nameEdit->setText(newName);
404  }
405  }
406 
407  void
409  {
410  header->setHidden(!vis);
411  }
412 
413  void
414  NJointControllerClassesWidgetEntry::createCtrl()
415  {
416  const auto instanceName = nameEdit->text().toStdString();
417  const auto variants = creator->getVariants();
418  if (variants.empty())
419  {
420  ARMARX_INFO << "creating " << instanceName << " of class " << className
421  << " with no parameters\n";
422  }
423  else
424  {
425  std::stringstream ss;
426  ss << "creating " << instanceName << " of class " << className << " with parameters:\n";
427  for (const auto& pair : variants)
428  {
429  if (pair.second)
430  {
431 
432  if (pair.second->data)
433  {
434  ss << " '" << pair.first << "' of type " << pair.second->data->ice_id()
435  << "\n";
436  }
437  else
438  {
439  ss << " '" << pair.first << "' nullptr data \n";
440  }
441  }
442  else
443  {
444  ss << " '" << pair.first << "' nullptr\n";
445  }
446  }
447  ARMARX_INFO << ss.str();
448  }
449  robotUnit->createNJointControllerFromVariantConfig(className, instanceName, variants);
451  }
452 
453  void
454  NJointControllerClassesWidget::packageEditChanged()
455  {
456  auto package = ui->comboBoxPackage->currentText();
457  if (package.isEmpty())
458  {
459  selectLibMode = SelectLibsMode::LineEdit;
460  ui->lineEditLibrary->setVisible(true);
461  ui->comboBoxLibrary->setVisible(false);
462  ui->pushButtonLoadLib->setEnabled(true);
463  ui->labelPackageFound->setPixmap(QPixmap(":/icons/Blank.svg").scaled(16, 16));
464  ui->labelPackageFound->setToolTip("");
465  }
466  else
467  {
468  libShortNameToFileName.clear();
469  ui->comboBoxLibrary->clear();
470 
471  selectLibMode = SelectLibsMode::ComboBox;
472  ui->lineEditLibrary->setVisible(false);
473  ui->comboBoxLibrary->setVisible(true);
474  CMakePackageFinder pFinder(package.toStdString());
475  if (pFinder.packageFound())
476  {
477  ui->pushButtonLoadLib->setEnabled(true);
478  ui->labelPackageFound->setPixmap(QPixmap(":/icons/user-online.svg").scaled(16, 16));
479  ui->labelPackageFound->setToolTip("Found Package");
480  int libidx = -1;
481  for (const std::string& lib : Split(pFinder.getLibs(), ",; ", true))
482  {
483  if (lib.empty())
484  {
485  return;
486  }
487  const auto libPrefix = lib.find("lib");
488  const auto libSubstrStart = libPrefix == lib.npos ? 0 : libPrefix + 3;
489  const auto libSuffix = lib.find(".");
490  const auto libSubstrEnd = libSuffix - libSubstrStart;
491  std::string shortName = lib.substr(libSubstrStart, libSubstrEnd);
492  libShortNameToFileName[shortName] = lib;
493  ui->comboBoxLibrary->addItem(QString::fromStdString(shortName));
494  if (libidx == -1 &&
495  (lib.find("Controller") != lib.npos || lib.find("controller") != lib.npos))
496  {
497  libidx = libShortNameToFileName.size() - 1;
498  }
499  ui->comboBoxLibrary->setCurrentIndex(libidx);
500  }
501  }
502  else
503  {
504  ui->pushButtonLoadLib->setEnabled(false);
505  ui->labelPackageFound->setPixmap(
506  QPixmap(":/icons/dialog-cancel-5.svg").scaled(16, 16));
507  ui->labelPackageFound->setToolTip("Cannot find Package");
508  }
509  }
510  }
511 
512  void
513  NJointControllerClassesWidget::loadLibClicked()
514  {
515  ARMARX_WARNING << "The functionality of dynamically loading libraries during runtime is no "
516  "longer supported. Use"
517  "the component properties to load additional libraries.";
518  return;
519  // if (!robotUnit)
520  // {
521  // return;
522  // }
523 
524  // switch (selectLibMode)
525  // {
526  // case SelectLibsMode::LineEdit:
527  // {
528  // auto lib = ui->lineEditLibrary->text().toStdString();
529  // if (lib.empty())
530  // {
531  // return;
532  // }
533  //// ARMARX_INFO << "requesting to load lib " << lib
534  //// << " -> " << robotUnit->loadLibFromPath(lib);
535  // }
536  // break;
537  //
538  // case SelectLibsMode::ComboBox:
539  // {
540  // auto package = ui->comboBoxPackage->currentText().toStdString();
541  // auto lib = ui->comboBoxLibrary->currentText().toStdString();
542  // if (lib.empty())
543  // {
544  // return;
545  // }
546  // if (libShortNameToFileName.count(lib))
547  // {
548  // lib = libShortNameToFileName.at(lib);
549  // }
550  //// ARMARX_INFO << "requesting to load lib " << lib << " from package " << package
551  //// << " -> " << robotUnit->loadLibFromPackage(package, lib);
552  // }
553  // break;
554  // default:
555  // ARMARX_WARNING << "Load lib for given SelectLibsMode nyi";
556  // break;
557  // }
558  }
559 
560 } // namespace armarx
armarx::NJointControllerClassesWidget::clearAll
void clearAll() override
Definition: NJointControllerClassesWidget.cpp:157
armarx::NJointControllerClassesWidgetEntry::creator
WidgetDescription::DescribedWidgetBase * creator
Definition: NJointControllerClassesWidget.h:135
armarx::NJointControllerClassesWidgetEntry::nameEdit
QLineEdit * nameEdit
Definition: NJointControllerClassesWidget.h:134
armarx::NJointControllerClassesWidget::nJointControllerClassAdded
virtual void nJointControllerClassAdded(std::string name)
Definition: NJointControllerClassesWidget.cpp:97
armarx::CMakePackageFinder::packageFound
bool packageFound() const
Returns whether or not this package was found with cmake.
Definition: CMakePackageFinder.cpp:511
armarx::NJointControllerClassesWidget::loadSettings
void loadSettings(QSettings *settings) override
Definition: NJointControllerClassesWidget.cpp:139
armarx::NJointControllerClassesWidgetEntry
Definition: NJointControllerClassesWidget.h:109
armarx::NJointControllerClassesWidget::doContentUpdate
void doContentUpdate() override
Definition: NJointControllerClassesWidget.cpp:164
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:36
armarx::CMakePackageFinder
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Definition: CMakePackageFinder.h:52
armarx::NJointControllerClassesWidget::saveSettings
void saveSettings(QSettings *settings) override
Definition: NJointControllerClassesWidget.cpp:149
armarx::NJointControllerClassesWidget::addOneFromResetData
bool addOneFromResetData() override
Definition: NJointControllerClassesWidget.cpp:187
armarx::RobotUnitWidgetTemplateBase< Ui::NJointControllerClassesWidget >::ui
Ui::NJointControllerClassesWidget * ui
Definition: RobotUnitWidgetBase.h:134
StringHelpers.h
armarx::RobotUnitWidgetBase::doMetaCall
std::atomic_bool doMetaCall
Definition: RobotUnitWidgetBase.h:99
armarx::NJointControllerClassesWidgetEntry::parent
NJointControllerClassesWidget * parent
Definition: NJointControllerClassesWidget.h:136
armarx::RobotUnitWidgetBase::robotUnit
RobotUnitInterfacePrx robotUnit
Definition: RobotUnitWidgetBase.h:93
armarx::NJointControllerClassesWidget::getResetData
void getResetData() override
Definition: NJointControllerClassesWidget.cpp:174
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::NJointControllerClassesWidget::getDefaultName
QString getDefaultName() const
Definition: NJointControllerClassesWidget.cpp:133
armarx::NJointControllerClassesWidgetEntry::robotUnit
RobotUnitInterfacePrx robotUnit
Definition: NJointControllerClassesWidget.h:132
armarx::NJointControllerClassesWidgetEntry::hasRemoteCreation
bool hasRemoteCreation()
Definition: NJointControllerClassesWidget.cpp:392
armarx::RobotUnitWidgetBase::mutex
std::recursive_timed_mutex mutex
Definition: RobotUnitWidgetBase.h:94
armarx::RobotUnitWidgetTemplateBase
Definition: RobotUnitWidgetBase.h:106
armarx::NJointControllerClassesWidget::~NJointControllerClassesWidget
~NJointControllerClassesWidget() override
Definition: NJointControllerClassesWidget.cpp:91
armarx::NJointControllerClassesWidgetEntry::classNameQStr
QString classNameQStr
Definition: NJointControllerClassesWidget.h:131
armarx::WidgetDescription::makeDescribedWidget
DescribedWidgetBase * makeDescribedWidget(const WidgetPtr &p, ValueChangedListenerInterface *listener)
Definition: WidgetDescription.cpp:892
armarx::NJointControllerClassesWidgetEntry::NJointControllerClassesWidgetEntry
NJointControllerClassesWidgetEntry(NJointControllerClassesWidget &parent, QTreeWidget &treeWidget, const NJointControllerClassDescription &desc, RobotUnitInterfacePrx robotUnit)
Definition: NJointControllerClassesWidget.cpp:317
CMakePackageFinder.h
armarx::NJointControllerClassesWidgetEntry::updateDefaultName
void updateDefaultName(const QString &oldName, const QString &newName)
Definition: NJointControllerClassesWidget.cpp:398
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::NJointControllerClassesWidget::NJointControllerClassesWidget
NJointControllerClassesWidget(QWidget *parent=0)
Definition: NJointControllerClassesWidget.cpp:37
armarx::NJointControllerClassesWidget
Definition: NJointControllerClassesWidget.h:52
IceInternal::ProxyHandle<::IceProxy::armarx::RobotUnitInterface >
armarx::WidgetDescription::DescribedWidgetBase::getVariants
virtual std::map< std::string, VariantBasePtr > getVariants()
Definition: WidgetDescription.h:57
armarx::NJointControllerClassesWidgetEntry::matchName
bool matchName(const QString &name)
Definition: NJointControllerClassesWidget.cpp:386
NJointControllerClassesWidget.h
Logging.h
armarx::NJointControllerClassesWidget::updateDefaultNameOnControllerCreated
virtual void updateDefaultNameOnControllerCreated(QString createdName, bool force=false)
Definition: NJointControllerClassesWidget.cpp:117
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::NJointControllerClassesWidgetEntry::className
std::string className
Definition: NJointControllerClassesWidget.h:130
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::NJointControllerClassesWidgetEntry::header
QTreeWidgetItem * header
Definition: NJointControllerClassesWidget.h:133
armarx::NJointControllerClassesWidgetEntry::setVisible
void setVisible(bool vis)
Definition: NJointControllerClassesWidget.cpp:408