28 #include <QGridLayout>
29 #include <QSortFilterProxyModel>
40 connect(
ui->pushButtonLoadLib, SIGNAL(released()),
this, SLOT(loadLibClicked()));
41 connect(
ui->comboBoxPackage,
42 SIGNAL(currentIndexChanged(QString)),
44 SLOT(packageEditChanged()));
45 connect(
ui->comboBoxPackage,
46 SIGNAL(editTextChanged(QString)),
48 SLOT(packageEditChanged()));
49 ui->comboBoxPackage->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
50 ui->comboBoxPackage->setFixedWidth(300);
54 using namespace std::filesystem;
55 std::string homeDir = QDir::homePath().toStdString();
56 path p = path{homeDir} /
".cmake" /
"packages";
59 for (
const path& entry : directory_iterator(p))
61 const std::string pkg = entry.filename().string();
64 ui->comboBoxPackage->addItem(QString::fromStdString(pkg));
68 QSortFilterProxyModel* proxy =
new QSortFilterProxyModel(
ui->comboBoxPackage);
69 proxy->setSourceModel(
ui->comboBoxPackage->model());
72 ui->comboBoxPackage->model()->setParent(proxy);
73 ui->comboBoxPackage->setModel(proxy);
74 ui->comboBoxPackage->model()->sort(0);
78 ui->comboBoxPackage->setEditText(
"");
81 ui->treeWidget->setColumnCount(2);
83 QTreeWidgetItem* head =
ui->treeWidget->headerItem();
84 head->setText(0,
"Class");
86 head->setToolTip(0,
"Controller class name");
87 ui->treeWidget->header()->setResizeMode(0, QHeaderView::Fixed);
88 ui->treeWidget->header()->setResizeMode(1, QHeaderView::Fixed);
100 std::unique_lock<std::recursive_timed_mutex> guard{
mutex};
107 auto data = ru->getNJointControllerClassDescription(name);
109 nJointControllerClassDescriptions[
data.className] = std::move(
data);
112 QMetaObject::invokeMethod(
this,
"updateContent", Qt::QueuedConnection);
121 if (oldName == createdName || force)
123 ++defaultControllerName;
125 for (
auto& pair : entries)
127 pair.second->updateDefaultName(oldName, newName);
135 return QString::number(defaultControllerName);
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());
151 settings->setValue(
"classLoadLineEditLib",
ui->lineEditLibrary->text());
152 settings->setValue(
"classLoadComboBoxPkg",
ui->comboBoxPackage->currentText());
153 settings->setValue(
"classLoadComboBoxLib",
ui->comboBoxLibrary->currentText());
160 nJointControllerClassDescriptions.clear();
166 for (
const auto& pair : nJointControllerClassDescriptions)
170 nJointControllerClassDescriptions.clear();
176 auto temp =
robotUnit->getNJointControllerClassDescriptions();
178 std::unique_lock<std::recursive_timed_mutex> guard{
mutex};
179 for (NJointControllerClassDescription& ds : temp)
181 nJointControllerClassDescriptions[ds.className] = std::move(ds);
189 if (nJointControllerClassDescriptions.empty())
193 add(nJointControllerClassDescriptions.begin()->second);
194 nJointControllerClassDescriptions.erase(nJointControllerClassDescriptions.begin());
199 NJointControllerClassesWidget::filterUpdated()
201 for (
auto& entry : entries)
204 if (!filterNameActive->isChecked() && !filterRemoteCreationActive->isChecked())
209 const bool combineOr = (filterCombination->currentText() ==
"Or");
210 bool showName = !combineOr;
211 bool showRemote = !combineOr;
213 if (filterNameActive->isChecked())
215 showName = (item->
matchName(filterName->text()) != filterNameInverted->isChecked());
217 if (filterRemoteCreationActive->isChecked())
221 showRemote = (filterRemoteCreation->currentText() !=
"Without");
225 showRemote = (filterRemoteCreation->currentText() !=
"With");
240 NJointControllerClassesWidget::add(
const NJointControllerClassDescription& desc)
242 std::unique_lock<std::recursive_timed_mutex> guard{
mutex};
243 if (entries.count(desc.className))
247 entries[desc.className] =
248 new NJointControllerClassesWidgetEntry(*
this, *(
ui->treeWidget), desc,
robotUnit);
252 NJointControllerClassesWidget::addFilter()
254 QTreeWidgetItem* filterHeader =
new QTreeWidgetItem;
255 ui->treeWidget->addTopLevelItem(filterHeader);
256 filterHeader->setText(0,
"Filter");
258 QTreeWidgetItem* filter =
new QTreeWidgetItem;
259 filterHeader->addChild(filter);
260 filter->setFirstColumnSpanned(
true);
261 QWidget* w =
new QWidget;
262 QGridLayout* l =
new QGridLayout;
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);
272 filterNameActive =
new QCheckBox;
273 filterNameActive->setText(
"Filter by name");
274 l->addWidget(filterNameActive, 1, 0, 1, 1);
276 filterName =
new QLineEdit;
277 l->addWidget(filterName, 1, 1, 1, 1);
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)));
284 filterNameActive, SIGNAL(toggled(
bool)), filterNameInverted, SLOT(setEnabled(
bool)));
285 filterName->setEnabled(
false);
286 filterNameInverted->setEnabled(
false);
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);
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()));
309 filterRemoteCreation, SIGNAL(currentIndexChanged(
int)),
this, SLOT(filterUpdated()));
311 filterNameActive->setChecked(
false);
312 filterRemoteCreationActive->setChecked(
false);
314 ui->treeWidget->setItemWidget(filter, 0, w);
319 QTreeWidget& treeWidget,
320 const NJointControllerClassDescription& desc,
323 className{desc.className},
324 classNameQStr{QString::fromStdString(className)},
325 robotUnit{robotUnit},
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)
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");
348 &QPushButton::clicked,
350 &NJointControllerClassesWidgetEntry::createCtrl);
352 &QLineEdit::returnPressed,
354 &NJointControllerClassesWidgetEntry::createCtrl);
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);
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);
375 QLineEdit* dummy =
new QLineEdit;
376 dummy->setFixedWidth(0);
377 dummy->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
378 headerW->layout()->addWidget(dummy);
380 headerW->layout()->addWidget(
new QLabel{
"No remote creation allowed."});
382 treeWidget.setItemWidget(header, 1, headerW);
399 const QString& newName)
414 NJointControllerClassesWidgetEntry::createCtrl()
416 const auto instanceName =
nameEdit->text().toStdString();
418 if (variants.empty())
421 <<
" with no parameters\n";
425 std::stringstream ss;
426 ss <<
"creating " << instanceName <<
" of class " <<
className <<
" with parameters:\n";
427 for (
const auto& pair : variants)
432 if (pair.second->data)
434 ss <<
" '" << pair.first <<
"' of type " << pair.second->data->ice_id()
439 ss <<
" '" << pair.first <<
"' nullptr data \n";
444 ss <<
" '" << pair.first <<
"' nullptr\n";
449 robotUnit->createNJointControllerFromVariantConfig(
className, instanceName, variants);
454 NJointControllerClassesWidget::packageEditChanged()
456 auto package = ui->comboBoxPackage->currentText();
457 if (package.isEmpty())
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(
"");
468 libShortNameToFileName.clear();
469 ui->comboBoxLibrary->clear();
471 selectLibMode = SelectLibsMode::ComboBox;
472 ui->lineEditLibrary->setVisible(
false);
473 ui->comboBoxLibrary->setVisible(
true);
474 CMakePackageFinder pFinder(package.toStdString());
475 if (pFinder.packageFound())
477 ui->pushButtonLoadLib->setEnabled(
true);
478 ui->labelPackageFound->setPixmap(QPixmap(
":/icons/user-online.svg").scaled(16, 16));
479 ui->labelPackageFound->setToolTip(
"Found Package");
481 for (
const std::string& lib :
Split(pFinder.getLibs(),
",; ",
true))
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));
495 (lib.find(
"Controller") != lib.npos || lib.find(
"controller") != lib.npos))
497 libidx = libShortNameToFileName.size() - 1;
499 ui->comboBoxLibrary->setCurrentIndex(libidx);
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");
513 NJointControllerClassesWidget::loadLibClicked()
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.";