25 #include <QGridLayout> 
   27 #include <QScrollArea> 
   28 #include <QSpacerItem> 
   29 #include <QStyledItemDelegate> 
   42         while ((item = layout->takeAt(0)))
 
   47                 delete item->layout();
 
   51                 delete item->widget();
 
   60         const char* 
const REMOTE_TAB_ID = 
"remote.tab_id";
 
   61         const char* 
const REMOTE_WIDGET_NAME = 
"remote.widget_name";
 
   63         struct InternalUpdateGuard
 
   70             ~InternalUpdateGuard()
 
   82         widget.remoteTabWidget->clear();
 
   84         widget.comboBoxTabGroups->setVisible(
false);
 
   85         widget.comboBoxTabGroups->addItem(groupAll);
 
   86         widget.comboBoxTabGroups->addItem(groupUngrouped);
 
   88         connect(widget.sendRemoteValuesButton,
 
   89                 &QPushButton::clicked,
 
   92         connect(widget.checkBoxGroupTabs,
 
   96         connect(widget.comboBoxTabGroups,
 
   97                 QOverload<const QString&>::of(&QComboBox::currentIndexChanged),
 
  105                 Qt::QueuedConnection);
 
  110                 Qt::QueuedConnection);
 
  115                 Qt::QueuedConnection);
 
  120                 Qt::QueuedConnection);
 
  122         widget.comboBoxTabGroups->setCurrentIndex(0);
 
  135             dialog->addProxyFinder<RemoteGuiInterfacePrx>({
"RemoteGuiProvider", 
"", 
"RemoteGui*"});
 
  137         return qobject_cast<SimpleConfigDialog*>(dialog);
 
  143         remoteGuiProviderName = dialog->getProxyName(
"RemoteGuiProvider");
 
  149         remoteGuiProviderName =
 
  150             settings->value(
"remoteGuiProviderName", 
"RemoteGuiProvider").toString().toStdString();
 
  156         settings->setValue(
"remoteGuiProviderName", QString::fromStdString(remoteGuiProviderName));
 
  168         remoteGuiProvider = getProxy<RemoteGuiInterfacePrx>(remoteGuiProviderName);
 
  172             std::unique_lock<std::mutex> lock(stateMutex);
 
  173             tabs = remoteGuiProvider->getTabs();
 
  174             tabWidgetStates = remoteGuiProvider->getTabStates();
 
  175             tabValueMap = remoteGuiProvider->getValuesForAllTabs();
 
  182         usingTopic(remoteGuiProvider->getTopicName());
 
  189             std::unique_lock<std::mutex> lock(stateMutex);
 
  190             tabs = remoteGuiProvider->getTabs();
 
  191             tabWidgetStates = remoteGuiProvider->getTabStates();
 
  192             tabValueMap = remoteGuiProvider->getValuesForAllTabs();
 
  194         QString qTabId = QString::fromStdString(tab);
 
  203             std::unique_lock<std::mutex> lock(stateMutex);
 
  204             tabs = remoteGuiProvider->getTabs();
 
  205             tabWidgetStates = remoteGuiProvider->getTabStates();
 
  206             tabValueMap = remoteGuiProvider->getValuesForAllTabs();
 
  213                                                    const RemoteGui::WidgetStateMap& widgetState,
 
  217             std::unique_lock<std::mutex> lock(stateMutex);
 
  218             tabWidgetStates[tab] = widgetState;
 
  220         QString qTabId = QString::fromStdString(tab);
 
  230             std::unique_lock<std::mutex> lock(stateMutex);
 
  231             for (
const auto& pair : delta)
 
  233                 tabValueMap[tab][pair.first] = pair.second;
 
  234                 tabDirtyMap[tab][pair.first] = pair.second;
 
  237         QString qTabId = QString::fromStdString(tab);
 
  247         std::unique_lock<std::mutex> lock(stateMutex);
 
  252         removeObsoleteTabs();
 
  258         std::unique_lock<std::mutex> lock(stateMutex);
 
  261         for (
auto& tabWidget : tabs)
 
  263             QString qid = QString::fromStdString(tabWidget.first);
 
  269         removeObsoleteTabs();
 
  278         std::unique_lock<std::mutex> lock(stateMutex);
 
  299         QWidget* widget = qobject_cast<QWidget*>(sender());
 
  302             ARMARX_WARNING << 
"Expected a widget as sender of onGuiStateChanged()";
 
  306         std::string 
id = widget->property(REMOTE_TAB_ID).toString().toStdString();
 
  307         std::string name = widget->property(REMOTE_WIDGET_NAME).toString().toStdString();
 
  309         std::unique_lock<std::mutex> lock(stateMutex);
 
  324         RemoteGui::ValueVariant& currentValue = tabValueMap.at(
id).at(name);
 
  328         RemoteGui::ValueVariant newValue = widgetHandler.
handleGuiChange(*desc, widget);
 
  330         if (newValue != currentValue)
 
  332             currentValue = newValue;
 
  340         const int index = widget.remoteTabWidget->currentIndex();
 
  341         QString currentTabText = widget.remoteTabWidget->tabText(
index);
 
  344         remoteGuiProvider->setValues(tabId, tabValueMap[tabId]);
 
  348     RemoteGuiWidgetController::createTab(std::string 
const& tabId)
 
  353         ARMARX_INFO << 
"Updating GUI for tab '" << tabId << 
"'";
 
  356         QString qTabId = QString::fromStdString(tabId);
 
  357         QWidget* tabHolder = 
nullptr;
 
  358         for (
const auto& pair : qtTabs)
 
  360             TabData 
const& 
data = pair.second;
 
  361             if (
data.fullName() == tabId)
 
  367         QGridLayout* layout = 
nullptr;
 
  371             QScrollArea* scrollArea = qobject_cast<QScrollArea*>(tabHolder);
 
  372             if (scrollArea && scrollArea->widget())
 
  374                 layout = qobject_cast<QGridLayout*>(scrollArea->widget()->layout());
 
  384                 QScrollArea* scrollArea = 
new QScrollArea(widget.remoteTabWidget);
 
  385                 scrollArea->setObjectName(qTabId);
 
  386                 scrollArea->setWidgetResizable(
true);
 
  387                 layout = 
new QGridLayout(scrollArea);
 
  388                 layout->setContentsMargins(0, 0, 0, 0);
 
  389                 QWidget* scrollAreaWidgetContents = 
new QWidget;
 
  390                 scrollArea->setWidget(scrollAreaWidgetContents);
 
  391                 scrollAreaWidgetContents->setLayout(layout);
 
  392                 tabHolder = scrollArea;
 
  395             auto& 
data = qtTabs[tabId];
 
  399                 const auto fname = 
data.fullName();
 
  400                 std::size_t idx = fname.find(
'_');
 
  401                 while (idx != std::string::npos)
 
  403                     data.groups.emplace(fname.substr(0, idx));
 
  404                     idx = fname.find(
'_', idx + 1);
 
  408             if (activeGroup == groupAll || (
data.groups.empty() && activeGroup == groupUngrouped))
 
  411                 widget.remoteTabWidget->addTab(tabHolder, qTabId);
 
  413             else if (
data.groups.count(activeGroup))
 
  415                 widget.remoteTabWidget->addTab(tabHolder,
 
  416                                                QString::fromStdString(
data.name(activeGroup)));
 
  419             for (
const auto& group : 
data.groups)
 
  421                 if (tabsPerGroup.count(group))
 
  423                     ++tabsPerGroup.at(group);
 
  427                     tabsPerGroup[group] = 1;
 
  428                     const auto box = widget.comboBoxTabGroups;
 
  429                     box->blockSignals(
true);
 
  430                     box->addItem(QString::fromStdString(group));
 
  431                     box->blockSignals(
false);
 
  438         guiWidgets[tabId].clear();
 
  439         QWidget* newTab = createWidgetFromDescription(tabId, widgetP);
 
  441         newTab->setParent(tabHolder);
 
  442         layout->addWidget(newTab, 0, 0);
 
  443         layout->addItem(
new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding), 1, 1);
 
  444         layout->addItem(
new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 1);
 
  448     RemoteGuiWidgetController::removeObsoleteTabs()
 
  450         for (
auto iter = qtTabs.begin(); iter != qtTabs.end();)
 
  452             std::string 
const& tabId = iter->first;
 
  453             TabData 
const& 
data = iter->second;
 
  455             if (tabs.count(tabId) > 0)
 
  462             QString qTabId = QString::fromStdString(tabId);
 
  464             QWidget* tabHolder = 
data.w;
 
  465             tabHolder->deleteLater();
 
  466             QTabWidget* tab = widget.remoteTabWidget;
 
  467             int i = 
data.findTabIndex(tab);
 
  473             for (
const std::string& group : 
data.groups)
 
  475                 std::size_t& tabCount = tabsPerGroup.at(group);
 
  479                     tabsPerGroup.erase(group);
 
  480                     QComboBox* box = widget.comboBoxTabGroups;
 
  481                     int boxIdx = box->findText(QString::fromStdString(group));
 
  485                         box->blockSignals(
true);
 
  486                         box->setCurrentIndex(0);
 
  487                         box->removeItem(boxIdx);
 
  488                         box->blockSignals(
false);
 
  491                     box->setCurrentIndex(0);
 
  495             iter = qtTabs.erase(iter);
 
  496             guiWidgets.erase(tabId);
 
  503     RemoteGuiWidgetController::updateWidgets(std::string 
const& tabId)
 
  506         RemoteGui::WidgetStateMap 
const& states = tabWidgetStates.at(tabId);
 
  507         std::map<std::string, QWidget*> 
const& widgets = guiWidgets.at(tabId);
 
  509         for (
auto& nameState : states)
 
  511             std::string 
const& name = nameState.first;
 
  512             RemoteGui::WidgetState 
const& state = nameState.second;
 
  513             QWidget* widget = widgets.at(name);
 
  515             widget->setHidden(state.hidden);
 
  516             widget->setDisabled(state.disabled);
 
  521     RemoteGuiWidgetController::updateState(std::string 
const& tabId)
 
  524         std::unique_lock<std::mutex> lock(stateMutex);
 
  527         InternalUpdateGuard guard(&internalUpdate);
 
  530         std::map<std::string, QWidget*> 
const& widgets = guiWidgets.at(tabId);
 
  531         RemoteGui::WidgetMap 
const& widgetDesc = guiDescriptions.at(tabId);
 
  535             std::string 
const& name = pair.first;
 
  536             RemoteGui::ValueVariant 
const& 
value = pair.second;
 
  538             QWidget* widget = widgets.at(name);
 
  541             widgetHandler.updateGui(*desc, widget, 
value);
 
  543         tabDirtyMap.at(tabId).clear();
 
  547     setNameProp(QWidget* w, QString 
const& name, QString 
const& 
id)
 
  549         if (w->property(REMOTE_WIDGET_NAME).toString() == 
"")
 
  551             w->setProperty(REMOTE_WIDGET_NAME, name);
 
  552             w->setProperty(REMOTE_TAB_ID, 
id);
 
  553             for (
auto child : w->findChildren<QWidget*>(QString{}, Qt::FindDirectChildrenOnly))
 
  555                 setNameProp(child, name, 
id);
 
  561     RemoteGuiWidgetController::createWidgetFromDescription(
const std::string& tabId,
 
  565         QWidget* widget = 
nullptr;
 
  568         bool useDefaultValue = 
values.count(desc->name) == 0;
 
  569         RemoteGui::ValueVariant 
const& initialValue =
 
  570             useDefaultValue ? desc->defaultValue : 
values[desc->name];
 
  576             return this->createWidgetFromDescription(tabId, desc);
 
  582             InternalUpdateGuard guard(&internalUpdate);
 
  585             widget = widgetHandler.createWidget(
 
  591         setNameProp(widget, QString::fromStdString(desc->name), QString::fromStdString(tabId));
 
  594         if (!desc->name.empty())
 
  597             auto result = guiWidgets[tabId].emplace(desc->name, widget);
 
  598             bool inserted = result.second;
 
  601                 guiDescriptions[tabId][desc->name] = desc;
 
  602                 values[desc->name] = initialValue;
 
  607                 ARMARX_WARNING << 
"Tried to add a widget with duplicate name '" << desc->name
 
  608                                << 
"' to remote tab ID '" << tabId << 
"'";
 
  618         widget.widgetTopBar->setVisible(
false);
 
  619         widget.remoteTabWidget->tabBar()->setVisible(
false);
 
  625         widget.widgetTopBar->setVisible(
true);
 
  626         widget.remoteTabWidget->tabBar()->setVisible(
true);
 
  630     RemoteGuiWidgetController::doAutoUpdate(std::string 
const& 
id)
 
  632         if (widget.autoUpdateCheckBox->checkState() == Qt::Checked)
 
  634             remoteGuiProvider->setValues(
id, tabValueMap[
id]);
 
  641         widget.comboBoxTabGroups->setEnabled(checked);
 
  642         widget.comboBoxTabGroups->setVisible(checked);
 
  643         widget.comboBoxTabGroups->setCurrentIndex(0);
 
  649         activeGroup = group.toStdString();
 
  650         auto tab = widget.remoteTabWidget;
 
  657         for (
const auto& pair : qtTabs)
 
  659             TabData 
const& 
data = pair.second;
 
  661             if (activeGroup == groupAll || (
data.groups.empty() && activeGroup == groupUngrouped))
 
  664                 tab->addTab(
data.w, QString::fromStdString(
data.fullName()));
 
  666             else if (!
data.groups.empty() && 
data.groups.count(activeGroup))
 
  668                 tab->addTab(
data.w, QString::fromStdString(
data.name(activeGroup)));
 
  674     RemoteGuiWidgetController::TabData::fullName()
 const 
  676         return w->objectName().toStdString();
 
  680     RemoteGuiWidgetController::TabData::name(
const std::string& pre)
 const 
  682         return fullName().substr(pre.size() + 1);
 
  686     RemoteGuiWidgetController::TabData::findTabIndex(QTabWidget* tab)
 const 
  688         for (
auto idx = 0; idx < tab->count(); ++idx)
 
  690             if (w == tab->widget(idx))