OperatorViewWidgetController.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 ArmarXGui::gui-plugins::OperatorViewWidgetController
19  * \author Leonie Leven
20  * \date 2024
21  * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
26 
27 #include <string>
28 
29 #include <QDebug>
30 #include <QHBoxLayout>
31 #include <QPalette>
32 #include <QStringList>
33 #include <QTimer>
34 
38 
39 static const std::string config_key_imrecman = "imrecman_name";
40 static const std::string config_key_start_in = "start_in";
41 
42 namespace armarx
43 {
45  DEFAULT_SETTINGS_PLUGIN_NAME("OperatorViewWidgetGuiPlugin"),
46  DEFAULT_SETTINGS_CUSTOM_TEXT("custom text")
47  {
48  // init gui
49  // getWidget() returns a container into which this widget is embedded
50  widget.setupUi(getWidget());
51  widget.clear->setStyleSheet("background-color: green;");
52  ARMARX_INFO << " setup of ui finished" << flush;
53  }
54 
55  void
57  {
59 
60  demoStateManagerName =
61  settings
62  ->value(QString::fromStdString(::config_key_imrecman), "DemoStateManagerInterface")
63  .toString()
64  .toStdString();
65  }
66 
67  void
69  {
71 
72  settings->setValue(QString::fromStdString(::config_key_imrecman),
73  QString::fromStdString(demoStateManagerName));
74  }
75 
76  void
78  {
80 
81  if (not demoStateManagerName.empty())
82  {
83  usingProxy(demoStateManagerName);
84  }
85  }
86 
87  void
89  {
90 
92  getProxy(demoStateManagerPrx, demoStateManagerName);
93  Q_ASSERT(widget.clear != nullptr);
94 
95  connect(widget.clear, SIGNAL(clicked()), this, SLOT(clearButtonPressed()));
96  connect(widget.sendOnly, SIGNAL(clicked()), this, SLOT(sendOnlyButtonPressed()));
97  connect(widget.insert, SIGNAL(clicked()), this, SLOT(insertButtonPressed()));
98  connect(widget.insertSend, SIGNAL(clicked()), this, SLOT(insertAndSendButtonPressed()));
99  connect(
100  widget.exportButtons, SIGNAL(clicked()), this, SLOT(exportButtonsToPropertyFormat()));
101 
102  connect(this,
104  this,
106 
107 
108  try
109  {
110  this->defaultStateValues = demoStateManagerPrx->getDefaultStates();
111  emit defaultValuesLoaded();
112  QObject::disconnect(this,
114  this,
116  }
117  catch (Ice::Exception const&)
118  {
119  ARMARX_WARNING << "Could not fetch default states." << deactivateSpam(10);
120  }
121  }
122 
123  void
125  {
126 
127  QWidget* container = getWidget();
128  QLayout* existingLayout = container->layout();
129 
130  this->layoutNormal = new QHBoxLayout();
131  this->layoutWarning = new QHBoxLayout();
132  this->layoutError = new QHBoxLayout();
133  this->layoutFatal = new QHBoxLayout();
134 
135  if (!existingLayout)
136  {
137  existingLayout = new QVBoxLayout(container);
138  container->setLayout(existingLayout);
139  ARMARX_IMPORTANT << "no existing layout";
140  }
141 
142  createButtons(QString::fromStdString(this->defaultStateValues));
143 
144  if (QVBoxLayout* hLayout = qobject_cast<QVBoxLayout*>(existingLayout))
145  {
146  hLayout->addLayout(this->layoutNormal);
147  hLayout->addLayout(this->layoutWarning);
148  hLayout->addLayout(this->layoutError);
149  hLayout->addLayout(this->layoutFatal);
150  }
151  }
152 
153  void
155  {
156 
157  try
158  {
159  this->demoStateManagerPrx->clear();
160  }
161  catch (Ice::Exception const&)
162  {
163  ARMARX_WARNING << "Could not set state clear." << deactivateSpam(10);
164  }
165  }
166 
167  void
169  {
170  QString newState = this->widget.newState->toPlainText();
171  int newSeverity = this->widget.severty->currentIndex();
172  this->sendOnlyButtonPressed(newState, newSeverity);
173  this->insertButtonPressed(newState, newSeverity);
174  }
175 
176  void
178  {
179  QString newState = text.toStdString() == "" ? this->widget.newState->toPlainText() : text;
180  int newSeverity = severity == -1 ? this->widget.severty->currentIndex() : severity;
181 
182  if (this->buttonText.find(newState.toStdString()) != this->buttonText.end())
183  {
184  ARMARX_IMPORTANT << "This button with text " << newState.toStdString()
185  << " already exists!";
186  return;
187  }
188 
189  this->buttonText.insert(newState.toStdString());
190 
191  armarx::severity::SeverityEnum buttonSeverity =
192  static_cast<armarx::severity::SeverityEnum>(newSeverity);
193 
194  QPushButton* button = new QPushButton(newState, getWidget());
195 
196  QString color = QString::fromStdString(mapColor(buttonSeverity));
197  if (!color.isEmpty())
198  {
199  QPalette palette = button->palette();
200  palette.setColor(QPalette::Button, QColor(color));
201  button->setPalette(palette);
202  button->setStyleSheet("background-color: " + color + ";");
203  }
204  switch (buttonSeverity)
205  {
206  case armarx::severity::SeverityEnum::normal:
207  this->layoutNormal->addWidget(button);
208  break;
209  case armarx::severity::SeverityEnum::warning:
210  this->layoutWarning->addWidget(button);
211  break;
212  case armarx::severity::SeverityEnum::error:
213  this->layoutError->addWidget(button);
214  break;
215  case armarx::severity::SeverityEnum::fatal:
216  this->layoutFatal->addWidget(button);
217  break;
218  }
219 
220  connect(button,
221  &QPushButton::clicked,
222  this,
223  [this, newState, buttonSeverity]()
224  { this->defaultButtonPressed(newState.toStdString(), buttonSeverity); });
225  }
226 
227  void
229  {
230  std::string newState = text.toStdString() == ""
231  ? this->widget.newState->toPlainText().toStdString()
232  : text.toStdString();
233  int newSeverity = severity == -1 ? this->widget.severty->currentIndex() : severity;
234 
235  try
236  {
237  this->demoStateManagerPrx->setState(
238  newState, static_cast<armarx::severity::SeverityEnum>(newSeverity));
239  }
240  catch (Ice::Exception const&)
241  {
242  ARMARX_WARNING << "Could not send current state and severity." << deactivateSpam(10);
243  }
244  }
245 
246  void
247  OperatorViewWidgetController::createButtons(const QString& input)
248  {
249  QStringList pairs = input.split(";");
250 
251  for (const QString& pair : pairs)
252  {
253  QStringList keyValue = pair.split(":");
254  if (keyValue.size() == 2)
255  {
256  QString text = keyValue[0].trimmed();
257  int value = keyValue[1].toInt();
258  armarx::severity::SeverityEnum buttonSeverity =
259  static_cast<armarx::severity::SeverityEnum>(value);
260 
261  QPushButton* button = new QPushButton(text, getWidget());
262 
263  QString color = QString::fromStdString(mapColor(buttonSeverity));
264  if (!color.isEmpty())
265  {
266  QPalette palette = button->palette();
267  palette.setColor(QPalette::Button, QColor(color));
268  button->setPalette(palette);
269  button->setStyleSheet("background-color: " + color + ";");
270  }
271  this->buttonText.insert(text.toStdString());
272  switch (buttonSeverity)
273  {
274  case armarx::severity::SeverityEnum::normal:
275  this->layoutNormal->addWidget(button);
276  break;
277  case armarx::severity::SeverityEnum::warning:
278  this->layoutWarning->addWidget(button);
279  break;
280  case armarx::severity::SeverityEnum::error:
281  this->layoutError->addWidget(button);
282  break;
283  case armarx::severity::SeverityEnum::fatal:
284  this->layoutFatal->addWidget(button);
285  break;
286  }
287 
288  connect(button,
289  &QPushButton::clicked,
290  this,
291  [this, text, buttonSeverity]()
292  { this->defaultButtonPressed(text.toStdString(), buttonSeverity); });
293  }
294  }
295  }
296 
297  void
299  armarx::severity::SeverityEnum severity)
300  {
301  try
302  {
303  this->demoStateManagerPrx->setState(state, severity);
304  }
305  catch (Ice::Exception const&)
306  {
307  ARMARX_WARNING << "Could not send current state and severity." << deactivateSpam(10);
308  }
309  }
310 
311  void
313  {
314  std::string exportProperty = "";
315  QList<QPushButton*> normalButtons = getButtonsFromLayout(this->layoutNormal);
316  QList<QPushButton*> warningButtons = getButtonsFromLayout(this->layoutWarning);
317  QList<QPushButton*> errorButtons = getButtonsFromLayout(this->layoutError);
318  QList<QPushButton*> fatalButtons = getButtonsFromLayout(this->layoutFatal);
319  std::vector<QList<QPushButton*>> buttons;
320  buttons.push_back(normalButtons);
321  buttons.push_back(warningButtons);
322  buttons.push_back(errorButtons);
323  buttons.push_back(fatalButtons);
324 
325  for (unsigned long i = 0; i < buttons.size(); i++)
326  {
327  auto buttonList = buttons[i];
328 
329  for (auto it = buttonList.begin(); it != buttonList.end(); ++it)
330  {
331  std::string buttonText = (*it)->text().toStdString();
332  exportProperty.append(buttonText + ":" + std::to_string(i) + ";");
333  }
334  }
335  QClipboard* clipboard = QGuiApplication::clipboard();
336  clipboard->setText(QString::fromStdString(exportProperty));
337  ARMARX_INFO << "Button configuration: " << exportProperty;
338  }
339 
340  QList<QPushButton*>
341  OperatorViewWidgetController::getButtonsFromLayout(QLayout* layout)
342  {
343  QList<QPushButton*> buttons;
344 
345  if (!layout)
346  return buttons;
347 
348  for (int i = 0; i < layout->count(); ++i)
349  {
350  if (auto* button = qobject_cast<QPushButton*>(layout->itemAt(i)->widget()))
351  {
352  buttons.append(button);
353  }
354  }
355 
356  return buttons;
357  }
358 
359  std::string
360  OperatorViewWidgetController::mapColor(severity::SeverityEnum severity)
361  {
362  std::string color;
363  switch (severity)
364  {
365  case severity::SeverityEnum::normal:
366  color = "green";
367  break;
368  case severity::SeverityEnum::warning:
369  color = "orange";
370  break;
371  case severity::SeverityEnum::error:
372  color = "red";
373  break;
374  case severity::SeverityEnum::fatal:
375  color = "magenta";
376  break;
377  default:
378  color = "black";
379  }
380  return color;
381  }
382 
383  void
385  {
386 
387  QObject::disconnect(widget.clear, SIGNAL(clicked()), this, SLOT(clearButtonPressed()));
388  QObject::disconnect(
389  widget.sendOnly, SIGNAL(clicked()), this, SLOT(sendOnlyButtonPressed()));
390  QObject::disconnect(widget.insert, SIGNAL(clicked()), this, SLOT(insertButtonPressed()));
391  QObject::disconnect(
392  widget.insertSend, SIGNAL(clicked()), this, SLOT(insertAndSendButtonPressed()));
393  QObject::disconnect(
394  widget.exportButtons, SIGNAL(clicked()), this, SLOT(exportButtonsToPropertyFormat()));
395 
396  clearLayout(this->layoutNormal);
397  clearLayout(this->layoutWarning);
398  clearLayout(this->layoutError);
399  clearLayout(this->layoutFatal);
400 
401  delete this->layoutNormal;
402  delete this->layoutWarning;
403  delete this->layoutError;
404  delete this->layoutFatal;
405 
406  this->layoutNormal = nullptr;
407  this->layoutWarning = nullptr;
408  this->layoutError = nullptr;
409  this->layoutFatal = nullptr;
410 
411  this->buttonText.clear();
412 
413  ARMARX_INFO << "UI cleaned successfully";
414  }
415 
416  void
417  OperatorViewWidgetController::clearLayout(QLayout* layout)
418  {
419  if (!layout)
420  return;
421 
422  while (QLayoutItem* item = layout->takeAt(0))
423  {
424  if (QWidget* widget = item->widget())
425  {
426  widget->deleteLater();
427  }
428  else if (QLayout* subLayout = item->layout())
429  {
430  clearLayout(subLayout);
431  }
432  delete item;
433  }
434  }
435 
436  void
438  {
439 
440  cleanUI();
441  ARMARX_INFO << "Disconnect";
442  }
443 
444  void
446  {
447  ARMARX_INFO << "Exit";
448  }
449 
450  QPointer<QDialog>
452  {
453  ARMARX_TRACE;
454 
455  if (not m_config_dialog)
456  {
457  m_config_dialog = new armarx::SimpleConfigDialog{parent};
458  m_config_dialog->addProxyFinder<DemoStateManagerInterfacePrx>(
459  {::config_key_imrecman, "Demo State Manager", "*"});
460  }
461  return qobject_cast<QDialog*>(m_config_dialog);
462  }
463 
464  void
466  {
467  ARMARX_TRACE;
468 
469  if (m_config_dialog)
470  {
471  demoStateManagerName = m_config_dialog->getProxyName(::config_key_imrecman);
472  }
473  }
474 
475 
476 } // namespace armarx
armarx::OperatorViewWidgetController::insertButtonPressed
void insertButtonPressed(QString text="", int severity=-1)
Definition: OperatorViewWidgetController.cpp:177
armarx::OperatorViewWidgetController::createButtonLayout
void createButtonLayout()
Definition: OperatorViewWidgetController.cpp:124
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
armarx::OperatorViewWidgetController::onInitComponent
virtual void onInitComponent()
Pure virtual hook for the subclass.
Definition: OperatorViewWidgetController.cpp:77
armarx::OperatorViewWidgetController::saveSettings
virtual void saveSettings(QSettings *settings)
Implement to save the settings as part of the GUI configuration.
Definition: OperatorViewWidgetController.cpp:68
armarx::OperatorViewWidgetController::getConfigDialog
QPointer< QDialog > getConfigDialog(QWidget *parent) override
getConfigDialog returns a pointer to the a configuration widget of this controller.
Definition: OperatorViewWidgetController.cpp:451
armarx::OperatorViewWidgetController::loadSettings
virtual void loadSettings(QSettings *settings)
Implement to load the settings that are part of the GUI configuration.
Definition: OperatorViewWidgetController.cpp:56
armarx::OperatorViewWidgetController::cleanUI
void cleanUI()
Definition: OperatorViewWidgetController.cpp:384
armarx::OperatorViewWidgetController::defaultValuesLoaded
void defaultValuesLoaded()
armarx::OperatorViewWidgetController::insertAndSendButtonPressed
void insertAndSendButtonPressed()
Definition: OperatorViewWidgetController.cpp:168
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:77
armarx::OperatorViewWidgetController::onConnectComponent
virtual void onConnectComponent()
Pure virtual hook for the subclass.
Definition: OperatorViewWidgetController.cpp:88
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
LocalTimeServer.h
armarx::flush
const LogSender::manipulator flush
Definition: LogSender.h:251
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:12
armarx::OperatorViewWidgetController::exportButtonsToPropertyFormat
void exportButtonsToPropertyFormat()
Definition: OperatorViewWidgetController.cpp:312
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:41
armarx::SimpleConfigDialog::addProxyFinder
void addProxyFinder(const std::vector< EntryData > &entryData)
Definition: SimpleConfigDialog.h:103
OperatorViewWidgetController.h
armarx::OperatorViewWidgetController::onExitComponent
virtual void onExitComponent()
Hook for subclass.
Definition: OperatorViewWidgetController.cpp:445
TimeUtil.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::OperatorViewWidgetController::clearButtonPressed
void clearButtonPressed()
Definition: OperatorViewWidgetController.cpp:154
DEFAULT_SETTINGS_PLUGIN_NAME
#define DEFAULT_SETTINGS_PLUGIN_NAME
Definition: PriorMemoryEditorPlugin.cpp:92
armarx::OperatorViewWidgetController::configured
void configured() override
This function must be implemented by the user, if he supplies a config dialog.
Definition: OperatorViewWidgetController.cpp:465
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:99
armarx::ArmarXWidgetController::getWidget
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
Definition: ArmarXWidgetController.cpp:54
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::OperatorViewWidgetController::OperatorViewWidgetController
OperatorViewWidgetController()
Definition: OperatorViewWidgetController.cpp:44
armarx::OperatorViewWidgetController::sendOnlyButtonPressed
void sendOnlyButtonPressed(QString text="", int severity=-1)
Definition: OperatorViewWidgetController.cpp:228
armarx::ManagedIceObject::getProxy
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Definition: ManagedIceObject.cpp:407
armarx::OperatorViewWidgetController::onDisconnectComponent
virtual void onDisconnectComponent()
Hook for subclass.
Definition: OperatorViewWidgetController.cpp:437
armarx::OperatorViewWidgetController::defaultButtonPressed
void defaultButtonPressed(std::string state, armarx::severity::SeverityEnum severity)
Definition: OperatorViewWidgetController.cpp:298
armarx::ManagedIceObject::usingProxy
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Definition: ManagedIceObject.cpp:154
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
Application.h
armarx::SimpleConfigDialog
A config-dialog containing one (or multiple) proxy finders.
Definition: SimpleConfigDialog.h:84