StateParameterEditor.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
19  * @author
20  * @date
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 #include "StateParameterEditor.h"
25 
27 
31 
32 #include <Ice/ObjectFactory.h>
33 
34 #include <QComboBox>
35 #include <QDialog>
36 #include <QPushButton>
37 #include <QTextEdit>
38 #include <QVBoxLayout>
39 #include <QInputDialog>
40 #include <QLineEdit>
41 #include <QDialogButtonBox>
42 #include <QLabel>
43 #include <QToolButton>
44 #include <QMessageBox>
45 #include <QStyledItemDelegate>
46 #include <QCompleter>
47 
48 using namespace armarx;
49 
51  QTableWidget(parent),
52  defaultValueState(Qt::Unchecked)
53 {
54  // For jsonobject double/float serilization on german/spanish pcs....
55  setlocale(LC_ALL, "C");
56 
57  setColumnCount(6);
58  qRegisterMetaType<StateParameterMap>("StateParameterMap");
59  qRegisterMetaType<std::map<QString, std::pair<QString, QString> > >("std::map<QString,std::pair<QString,QString> >");
60  connect(this, SIGNAL(buildRequested(StateParameterMap, std::map<QString, std::pair<QString, QString> >)), this, SLOT(__buildFromMap(StateParameterMap, std::map<QString, std::pair<QString, QString> >)), Qt::QueuedConnection);
61  setHeaders();
62 
63  if (params.size() == 0)
64  {
66  }
67  else
68  {
69  buildFromMap(params);
70  }
71 
72 
73 
74  setItemDelegateForColumn(eKey, &delegate);
75 
76 
77 }
78 
79 void StateParameterEditor::setKeyBlackList(const QSet<QString>& keyBlackList)
80 {
81  this->keyBlackList = keyBlackList;
82 }
83 
84 QSet<QString> StateParameterEditor::getKeys() const
85 {
86  QSet<QString> result;
87 
88  for (int row = 0; row < rowCount(); row++)
89  {
90  if (item(row, eKey) && !item(row, eKey)->text().isEmpty())
91  {
92  result.insert(item(row, eKey)->text());
93  }
94  }
95 
96  return result;
97 }
98 
99 StateParameterIceBasePtr StateParameterEditor::getStateParameter(int row) const
100 {
101  if (getKey(row).isEmpty())
102  {
103  return NULL;
104  }
105 
106  StateParameterIceBasePtr param = StateParameter::create();
107  param->defaultValue = getVariantContainer(row);
108  param->optionalParam = getIsOptional(row);
109  param->set = false;
110  return param;
111 }
112 
114 {
115  StateParameterMap result;
116 
117  for (int row = 0; row < rowCount(); ++row)
118  {
119  auto param = getStateParameter(row);
120 
121  if (param)
122  {
123  result[getKey(row).toStdString()] = param;
124  }
125  }
126 
127  return result;
128 }
129 
130 //StateParameterMap StateParameterEditor::getStateParametersWithoutValue()
131 //{
132 // StateParameterMap result;
133 // for (int row = 0; row < rowCount(); ++row) {
134 // StateParameterIceBasePtr param = new StateParameterIceBase();
135 //if(getKey(row).length() == 0)
136 // continue;
137 
138 // }
139 //}
140 
141 StringVariantContainerBaseMap StateParameterEditor::getStringValueMap() const
142 {
143  StringVariantContainerBaseMap result;
144 
145  for (int row = 0; row < rowCount(); ++row)
146  {
147  // StateParameterIceBasePtr param = new StateParameter();
148  if (getKey(row).length() == 0)
149  {
150  continue;
151  }
152 
153  VariantContainerBasePtr con = getVariantContainer(row);
154  result[getKey(row).toStdString()] = con;
155  }
156 
157  return result;
158 }
159 
161 {
162  if (row >= rowCount())
163  {
164  throw LocalException("row index out of range: ") << row;
165  }
166 
167  QLineEdit* valueEdit = qobject_cast<QLineEdit*>(cellWidget(row, eValue));
168 
169  if (!valueEdit)
170  {
171  throw LocalException("value edit ptr is NULL");
172  }
173 
174  return valueEdit->text();
175 }
176 
177 QString StateParameterEditor::getJson(QString key) const
178 {
179  int row = -1;
180 
181  for (int i = 0; i < rowCount(); i++)
182  {
183  if (getKey(i) == key)
184  {
185  row = i;
186  break;
187  }
188  }
189 
190  if (row == -1)
191  {
192  throw LocalException("row index out of range: ") << row;
193  }
194 
195  if (row >= rowCount())
196  {
197  throw LocalException("row index out of range: ") << row;
198  }
199 
200  VariantContainerBasePtr container;
201 
202  QString type = getType(row);
203  QLineEdit* valueEdit = qobject_cast<QLineEdit*>(cellWidget(row, eValue));
204  QPushButton* editButton = qobject_cast<QPushButton*>(cellWidget(row, eValue));
205 
206 
207  JSONObjectPtr jsonObject = new JSONObject(communicator);
208 
209  if (valueEdit && valueEdit->isEnabled())
210  {
211  int typeId = Variant::hashTypeName(type.toStdString());
212  Variant variant;
213 
214  if (typeId == VariantType::Int)
215  {
216  variant.setInt(valueEdit->text().toInt());
217  }
218  else if (typeId == VariantType::Long)
219  {
220  variant.setLong(valueEdit->text().toLong());
221  }
222 
223  else if (typeId == VariantType::Bool)
224  if (valueEdit->text() == "true" || valueEdit->text() == "1")
225  {
226  variant.setBool(true);
227  }
228  else
229  {
230  variant.setBool(false);
231  }
232 
233  else if (typeId == VariantType::Float)
234  {
235  variant.setFloat(valueEdit->text().toFloat());
236  }
237  else if (typeId == VariantType::Double)
238  {
239  variant.setDouble(valueEdit->text().toDouble());
240  }
241 
242  else if (typeId == VariantType::String)
243  {
244  variant.setString(valueEdit->text().trimmed().toStdString());
245  }
246 
247  container = new SingleVariant(variant);
248  jsonObject->serializeIceObject(container);
249  return QString::fromUtf8(jsonObject->toString().c_str());
250  }
251  else if (editButton && editButton->isEnabled())
252  {
253  QString jsonValue = editButton->property("JsonValue").toString();
254  return jsonValue;
255  }
256 
257  // else
258  // throw LocalException("Neither QLineEdit nor QPushButton found!");
259  return "";
260 }
261 
262 
263 VariantContainerBasePtr StateParameterEditor::getVariantContainer(int row) const
264 {
265  if (row >= rowCount())
266  {
267  throw LocalException("row index out of range: ") << row;
268  }
269 
270  VariantContainerBasePtr result;
271 
272  QString type = getType(row);
273  QLineEdit* valueEdit = qobject_cast<QLineEdit*>(cellWidget(row, eValue));
274  QPushButton* editButton = qobject_cast<QPushButton*>(cellWidget(row, eValue));
275 
276  if ((valueEdit && valueEdit->isEnabled()) || item(row, eValue))
277  {
278  int typeId = Variant::hashTypeName(type.toStdString());
279  Variant variant;
280  QString valueStr = valueEdit ? valueEdit->text() : item(row, eValue)->text();
281 
282  if (typeId == VariantType::Int)
283  {
284  variant.setInt(valueStr.toInt());
285  }
286  else if (typeId == VariantType::Long)
287  {
288  variant.setLong(valueStr.toLong());
289  }
290 
291  else if (typeId == VariantType::Bool)
292  if (valueStr.compare("true", Qt::CaseInsensitive) == 0 || valueStr == "1")
293  {
294  variant.setBool(true);
295  }
296  else
297  {
298  variant.setBool(false);
299  }
300 
301  else if (typeId == VariantType::Float)
302  {
303  variant.setFloat(valueStr.toFloat());
304  }
305  else if (typeId == VariantType::Double)
306  {
307  variant.setDouble(valueStr.toDouble());
308  }
309 
310  else if (typeId == VariantType::String)
311  {
312  variant.setString(valueStr.trimmed().toStdString());
313  }
314 
315  result = new SingleVariant(variant);
316  }
317  else if (editButton && editButton->isEnabled())
318  {
319  QString jsonValue = editButton->property("JsonValue").toString();
320 
321  if (jsonValue.isEmpty())
322  {
323  return result;
324  }
325 
326  JSONObjectPtr jsonObject = new JSONObject(communicator);
327  // ARMARX_INFO_S << VAROUT(jsonValue.toUtf8().data());
328  jsonObject->fromString(jsonValue.toUtf8().data());
329 
330  try
331  {
332  SerializablePtr obj = jsonObject->deserializeIceObject();
333  result = VariantContainerBasePtr::dynamicCast(obj);
334 
335  if (!result)
336  {
337  // must be simple variant
338  result = new SingleVariant(Variant(VariantDataPtr::dynamicCast(obj)));
339  }
340  }
341  catch (std::exception& e)
342  {
343  ARMARX_WARNING_S << "JSON string for type " << type.toStdString() << " could not be deserialized: " << e.what();
344  return result;
345  }
346  }
347 
348  return result;
349 }
350 
351 QString StateParameterEditor::getKey(int row) const
352 {
353  if (row >= rowCount())
354  {
355  throw LocalException("row index out of range: ") << row;
356  }
357 
358  if (!item(row, eKey))
359  {
360  return "";
361  }
362 
363  return item(row, eKey)->text();
364 }
365 
366 QString StateParameterEditor::getType(int row) const
367 {
368  if (row >= rowCount())
369  {
370  throw LocalException("row index out of range: ") << row;
371  }
372 
373  QComboBox* CBvalueType = qobject_cast<QComboBox*>(cellWidget(row, 1));
374 
375  if (!CBvalueType)
376  {
377  return "";
378  }
379 
380  QString type = getBaseNameFromHumanName(CBvalueType->currentText()); //@@@
381  return type;
382 
383 }
384 
385 QString StateParameterEditor::getType(QString key) const
386 {
387  int row = getRow(key);
388  return getType(row);
389 }
390 
391 int StateParameterEditor::getRow(const QString& key) const
392 {
393  int row = -1;
394 
395  for (int i = 0; i < rowCount(); i++)
396  {
397  if (getKey(i) == key)
398  {
399  row = i;
400  break;
401  }
402  }
403 
404  if (row == -1)
405  {
406  throw LocalException("could not find key ") << key.toStdString();
407  }
408 
409  return row;
410 }
411 
413 {
414  if (row >= rowCount())
415  {
416  throw LocalException("row index out of range: ") << row;
417  }
418 
419  QComboBox* cbOptional = qobject_cast<QComboBox*>(cellWidget(row, eOptional));
420  return cbOptional->currentText() == "true";
421 }
422 
423 
425 {
426  // ARMARX_IMPORTANT_S << "Adding row";
427  int row = rowCount();
428  insertRow(row);
429  setItem(row, eKey, new QTableWidgetItem());
430 
431  setItem(row, eProvideDefaultValue, new QTableWidgetItem());
432  item(row, eProvideDefaultValue)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
433  item(row, eProvideDefaultValue)->setCheckState(defaultValueState);
434 
435  QComboBox* valueTypebox = new QComboBox;
436  valueTypebox->setEditable(true);
437  // valueTypebox->setInsertPolicy(QComboBox::InsertAlphabetically);
438  // valueTypebox->setValidator(new QIntValidator(this));
439  setCellWidget(row, eType, valueTypebox);
440  addVariantTypesToComboBox(valueTypebox);
441  QCompleter* fullCompleter = new QCompleter(valueTypebox->model(), this);
442  fullCompleter->setCompletionMode(QCompleter::PopupCompletion);
443  fullCompleter->setCaseSensitivity(Qt::CaseSensitive);
444  valueTypebox->setCompleter(fullCompleter);
445  valueTypebox->setEditText("string");
446  connect(valueTypebox, SIGNAL(editTextChanged(QString)), this, SLOT(typeCbChanged(QString)));
447  //valueTypebox->model()->sort(0);
448  QComboBox* cbOptional;
449  cbOptional = new QComboBox();
450  cbOptional->addItems(QString("true;false").split(";"));
451  cbOptional->setCurrentIndex(1);
452  setCellWidget(row, eOptional, cbOptional);
453 
454 
455  QIcon icon;
456  icon.addFile(QString::fromUtf8(":/icons/dialog-close.ico"), QSize(), QIcon::Normal, QIcon::Off);
457  QToolButton* deleteButton = new QToolButton(this);
458  deleteButton->setIcon(icon);
459  deleteButton->setToolTip("Delete this row");
460  setCellWidget(row, eDeleteButton, deleteButton);
461  connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteRow()));
462  emit rowAdded(row);
463  return row;
464 }
465 
466 
467 void StateParameterEditor::addParameterRow(QString key, QString variantIdStr, QString value, bool optional)
468 {
469  int row = addParameterRow();
470 
471  item(row, eKey)->setText(key);
472 
473  QComboBox* valueTypeBox = qobject_cast<QComboBox*>(cellWidget(row, eType));
474  // ARMARX_INFO_S << "type id: " << variantIdStr.toStdString() << " size: " << valueTypeBox->count();
475  valueTypeBox->setEditText(getHumanNameFromBaseName(variantIdStr));
476 
477  QComboBox* optionalBox = qobject_cast<QComboBox*>(cellWidget(row, eOptional));
478 
479  if (optional)
480  {
481  optionalBox->setCurrentIndex(0);
482  }
483  else
484  {
485  optionalBox->setCurrentIndex(1);
486  }
487 
488  if (!value.isEmpty())
489  {
490  item(row, eProvideDefaultValue)->setCheckState(Qt::Checked);
491  }
492 
493  int variantId = Variant::hashTypeName(variantIdStr.toStdString());
494 
495  if (variantId == VariantType::String || variantId == VariantType::Int || variantId == VariantType::Long || variantId == VariantType::Bool || variantId == VariantType::Float || variantId == VariantType::Double)
496  {
497  QLineEdit* valueEdit = new QLineEdit;
498 
499  if (item(row, eProvideDefaultValue)->checkState() == Qt::Unchecked)
500  {
501  valueEdit->setEnabled(false);
502  }
503 
504  setCellWidget(row, eValue, valueEdit);
505 
506  if (variantId == VariantType::String)
507  {
508  if (value.at(0) == '\"')
509  {
510  value.remove(0, 1);
511  }
512 
513  if (value.at(value.length() - 1) == '\"')
514  {
515  value.remove(value.length() - 1, 1);
516  }
517 
518  value = value.replace("\\\"", "\"").replace("\\\\", "\\");
519  }
520 
521  valueEdit->setText(value);
522  }
523  else
524  {
525  createValueButton(row, value);
526  }
527 
528  emit rowFilled(row, key);
529 }
530 
531 void StateParameterEditor::createValueButton(int row, const QString& jsonValue)
532 {
533  // ARMARX_INFO_S << VAROUT(row) << VAROUT(jsonValue.toStdString());
534  QComboBox* typeBox = qobject_cast<QComboBox*>(cellWidget(row, eType));
535 
536  QString typeString = getBaseNameFromHumanName(typeBox->currentText()); //@@@
537  QWidget* oldWidget = qobject_cast<QWidget*>(cellWidget(row, eValue));
538 
539  if (oldWidget)
540  {
541  oldWidget->hide();
542  }
543 
544  QPushButton* editValueButton = new QPushButton("Edit");
545 
546  if (item(row, eProvideDefaultValue)->checkState() == Qt::Unchecked)
547  {
548  editValueButton->setEnabled(false);
549  }
550 
551  setCellWidget(row, eValue, editValueButton);
552 
553  try
554  {
555  if (jsonValue.isEmpty())
556  {
557  auto variantContainerType = VariantContainerType::FromString(typeString.toStdString());
558  JSONObjectPtr jsonObject = new JSONObject(communicator);
559 
560  // ARMARX_INFO_S << VAROUT(variantContainerType->typeId);
561 
562  Ice::ValueFactoryPtr factory = communicator->getValueFactoryManager()->find(variantContainerType->typeId);
563 
564  if (factory)
565  {
566  Ice::ValuePtr objectPtr = factory->create(variantContainerType->typeId);
567 
568  VariantDataPtr var = VariantDataPtr::dynamicCast(objectPtr);
569 
570  if (!var)
571  {
572  // TODO: make better with dummy element function for all containers/variants?!
573  // ARMARX_INFO_S << VAROUT(variantContainerType->subType->typeId);
574  Ice::ValueFactoryPtr subfactory = communicator->getValueFactoryManager()->find(variantContainerType->subType->typeId);
575 
576  if (!subfactory)
577  {
578  // ARMARX_INFO_S << " no factory";
579  subfactory = IceInternal::factoryTable->getValueFactory(variantContainerType->subType->typeId);
580  }
581 
582  if (subfactory)
583  {
584  Ice::ValuePtr subObj = subfactory->create(variantContainerType->subType->typeId);
585  VariantDataPtr var = VariantDataPtr::dynamicCast(subObj);
586 
587  if (!var)
588  {
589 
590  }
591 
592  SingleTypeVariantListPtr list = SingleTypeVariantListPtr::dynamicCast(objectPtr);
593 
594  if (var && list)
595  {
596  list->addVariant(Variant(var));
597  }
598 
599  StringValueMapPtr map = StringValueMapPtr::dynamicCast(objectPtr);
600 
601  if (var && map)
602  {
603  map->addVariant("mykey", Variant(var));
604  }
605  }
606  else
607  {
608  ARMARX_INFO_S << " no base factory";
609  }
610  }
611 
612  jsonObject->serializeIceObject(SerializablePtr::dynamicCast(objectPtr));
613  }
614 
615  editValueButton->setProperty("JsonValue", QString::fromStdString(jsonObject->asString(true)));
616  }
617  else
618  {
619  editValueButton->setProperty("JsonValue", jsonValue);
620  }
621 
622  connect(editValueButton, SIGNAL(clicked()), this, SLOT(editDefaultButtonClicked()));
623  }
624  catch (...)
625  {
627  editValueButton->setEnabled(false);
628  }
629 
630 
631 }
632 
633 void StateParameterEditor::typeCbChanged(const QString& /*text*/)
634 {
635  QWidget* wid = qobject_cast<QWidget*>(sender());
636 
637  /*QModelIndex mIndex =*/ indexAt(wid->pos()); // Some strange bug happens here: If this is used, it will deliver on table creation zero
638  // If indexAt is not called, wid->pos() delivers a 0,0 Point and then rowAt() also return wrong index
639  // ARMARX_INFO_S << VAROUT(wid->pos()) << VAROUT(rowAt(wid->pos().y()));
640 
641  int row = rowAt(wid->pos().y());
642 
643  QWidget* valueWidget = cellWidget(row, eValue);
644 
645  QComboBox* typeBox = qobject_cast<QComboBox*>(cellWidget(row, eType));
646  std::string typeStr = getBaseNameFromHumanName(typeBox->currentText()).toStdString(); //@@@
647  int typeId = Variant::hashTypeName(typeStr);
648 
649  if (typeId == VariantType::String || typeId == VariantType::Int || typeId == VariantType::Long || typeId == VariantType::Bool || typeId == VariantType::Float || typeId == VariantType::Double)
650  {
651  QLineEdit* valueLineEdit = qobject_cast<QLineEdit*>(valueWidget);
652 
653  if (!valueLineEdit)
654  {
655  valueLineEdit = new QLineEdit;
656  setCellWidget(row, eValue, valueLineEdit);
657  }
658 
659  if (item(row, eProvideDefaultValue)->checkState() == Qt::Unchecked)
660  {
661  valueLineEdit->setEnabled(false);
662  }
663 
664  if (typeId == VariantType::String)
665  {
666  valueLineEdit->setValidator(NULL);
667  }
668  else if (typeId == VariantType::Int || typeId == VariantType::Long)
669  {
670  valueLineEdit->setValidator(new QIntValidator(this));
671  }
672  else if (typeId == VariantType::Bool)
673  {
674  QRegExp rx("((1|0)|(true|false))");
675  QValidator* validator = new QRegExpValidator(rx, this);
676  valueLineEdit->setValidator(validator);
677  }
678  else if (typeId == VariantType::Float || typeId == VariantType::Double)
679  {
680  valueLineEdit->setValidator(new QDoubleValidator(this));
681  }
682 
683  QString value = valueLineEdit->text();
684  int pos;
685 
686  if (valueLineEdit->validator() && valueLineEdit->validator()->validate(value, pos) != QValidator::Acceptable)
687  {
688  valueLineEdit->setText("");
689  }
690  }
691  else
692  {
693  createValueButton(row, "");
694  }
695 }
696 
697 
699 {
700  int row;
701  QWidget* wid = qobject_cast<QWidget*>(sender());
702  QModelIndex mIndex = indexAt(wid->pos());
703  row = mIndex.row();
704 
705  disconnect(this);
706  removeRow(row);
707 
708  if (rowCount() == 0)
709  {
710  addParameterRow();
711  }
712 
713  connectUserEditSlots();
714 }
715 
717 {
718  // ARMARX_IMPORTANT_S << "checking row: " << row << ", " << column;
719 
720  if (column == eProvideDefaultValue)
721  {
722  if (item(row, eProvideDefaultValue)->checkState() == Qt::Unchecked)
723  {
724  QWidget* valueWidget = cellWidget(row, eValue);
725  QWidget* valueLineEdit = qobject_cast<QWidget*>(valueWidget);
726 
727  if (valueLineEdit)
728  {
729  valueLineEdit->setEnabled(false);
730  }
731  }
732  else
733  {
734  QWidget* valueWidget = cellWidget(row, eValue);
735  QWidget* valueLineEdit = qobject_cast<QWidget*>(valueWidget);
736 
737  if (valueLineEdit)
738  {
739  valueLineEdit->setEnabled(true);
740  }
741  }
742  }
743  else if (column == eKey)
744  {
745  auto keyitem = item(row, eKey);
746 
747  if (keyitem)
748  {
749  if ((keyBlackList.find(keyitem->text()) != keyBlackList.end() || findItems(keyitem->text(), Qt::MatchExactly).size() > 1))
750  {
751  keyitem->setText(item(row, eKey)->text() + "_2");
752  ARMARX_WARNING_S << "Keys must be unique (input and local parameters share the same key pool)";
753  }
754  }
755  }
756 
757  if (row >= rowCount() - 1 && item(rowCount() - 1, 0) && !item(rowCount() - 1, 0)->text().isEmpty())
758  {
759  addParameterRow();
760  }
761 }
762 
764 {
765  for (int row = 0; row < rowCount(); row++)
766  {
767  QComboBox* valueTypeBox = qobject_cast<QComboBox*>(cellWidget(row, eType));
768  addVariantTypesToComboBox(valueTypeBox);
769  // valueTypeBox->model()->sort(0);
770  }
771 
772 }
773 
775 {
776  QDialog editDefaultDialog;
777  editDefaultDialog.setWindowTitle("Statechart Parameter Complex Value Editor");
778  editDefaultDialog.resize(QSize(600, 400));
779  QTextEdit* dialogTextEdit = new QTextEdit();
780  dialogTextEdit->setAcceptRichText(false);
781  dialogTextEdit->setPlainText(sender()->property("JsonValue").toString());
782 
783  QVBoxLayout* layout = new QVBoxLayout;
784  layout->addWidget(dialogTextEdit);
785  QDialogButtonBox* buttonBox = new QDialogButtonBox(dialogTextEdit);
786  buttonBox->setOrientation(Qt::Horizontal);
787  buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
788  layout->addWidget(buttonBox);
789  editDefaultDialog.setLayout(layout);
790 
791  connect(buttonBox, SIGNAL(accepted()), &editDefaultDialog, SLOT(accept()));
792  connect(buttonBox, SIGNAL(rejected()), &editDefaultDialog, SLOT(reject()));
793 
794  if (editDefaultDialog.exec() == QDialog::Accepted)
795  {
796  sender()->setProperty("JsonValue", dialogTextEdit->toPlainText());
797  }
798 }
799 
800 void StateParameterEditor::connectUserEditSlots()
801 {
802  connect(this, SIGNAL(cellEntered(int, int)), this, SLOT(checkAndUpdateRowCount(int, int)), Qt::UniqueConnection);
803  connect(this, SIGNAL(cellPressed(int, int)), this, SLOT(checkAndUpdateRowCount(int, int)), Qt::UniqueConnection);
804  connect(this, SIGNAL(cellChanged(int, int)), this, SLOT(checkAndUpdateRowCount(int, int)), Qt::UniqueConnection);
805 }
806 
807 void StateParameterEditor::addVariantTypesToComboBox(QComboBox* combo)
808 {
809  if (!combo)
810  {
811  return;
812  }
813 
814  combo->clear();
815 
816  QList<QString> list;
817 
818  for (std::pair<VariantTypeId, std::string> pair : Variant::getTypes())
819  {
820  QString typeName = tr(pair.second.c_str());
821  //QString humanName = tr(Variant::getHumanName(pair->first).c_str());
822 
823  if (typeName.contains("Invalid"))
824  {
825  continue;
826  }
827 
828  list.append(getHumanNameFromBaseName(typeName));
829  /*if(combo->findText(typeName) == -1)
830  {
831  combo->addItem(getHumanNameFromBaseName(typeName));
832  }*/
833  }
834 
835  std::vector<VariantContainerType> containers;
836  containers.push_back(VariantType::List);
837  containers.push_back(VariantType::Map);
838 
839  for (VariantContainerType c : containers)
840  {
841  for (auto it : Variant::getTypes())
842  {
843  QString typeName = tr(it.second.c_str());
844 
845 
846  if (typeName.contains("Invalid"))
847  {
848  continue;
849  }
850 
851  std::string typeStr = VariantContainerType::allTypesToString(c(it.first).clone());
852  typeName = QString::fromStdString(typeStr);
853  list.append(getHumanNameFromBaseName(typeName));
854  /*if(combo->findText(typeName) == -1)
855  {
856  combo->addItem(getHumanNameFromBaseName(typeName));
857  }*/
858  }
859  }
860 
861  qSort(list.begin(), list.end(), compareVariantNames);
862  combo->addItems(list);
863 }
864 
865 QString StateParameterEditor::getHumanNameFromBaseName(QString variantBaseTypeName) const
866 {
867  if (!variantInfo)
868  {
869  return variantBaseTypeName;
870  }
871 
872  std::string humanName = variantInfo->getNestedHumanNameFromBaseName(variantBaseTypeName.toUtf8().data());
873 
874  if (humanName.empty())
875  {
876  return variantBaseTypeName;
877  }
878 
879  return QString::fromUtf8(humanName.c_str());
880 }
881 
882 QString StateParameterEditor::getBaseNameFromHumanName(QString humanName) const
883 {
884  if (!variantInfo)
885  {
886  return humanName;
887  }
888 
889  std::string variantBaseTypeName = variantInfo->getNestedBaseNameFromHumanName(humanName.toUtf8().data());
890 
891  if (variantBaseTypeName.empty())
892  {
893  return humanName;
894  }
895 
896  return QString::fromUtf8(variantBaseTypeName.c_str());
897 }
898 
899 bool StateParameterEditor::compareVariantNames(const QString& a, const QString& b)
900 {
901  bool pa, pb;
902 
903  // list nested types after basic ones
904  pa = a.contains("(");
905  pb = b.contains("(");
906 
907  if (pa != pb)
908  {
909  return pb;
910  }
911 
912  // list human types before non resolved ones
913  pa = a.contains(":");
914  pb = b.contains(":");
915 
916  if (pa != pb)
917  {
918  return pb;
919  }
920 
921  // lower case (basic types) first
922  pa = a.count() > 0 && a[0].isLower();
923  pb = b.count() > 0 && b[0].isLower();
924 
925  if (pa != pb)
926  {
927  return pa;
928  }
929 
930  return a.compare(b) < 0;
931 }
933 {
934  return defaultValueState;
935 }
936 
938 {
939  defaultValueState = value;
940 }
941 
942 
943 
944 
946 {
947  setHorizontalHeaderLabels(QString("Key;Type;Optional;Def;Value;Del").split(";"));
948  setColumnWidth(eKey, 180);
949  setColumnWidth(eType, 225);
950  setColumnWidth(eOptional, 70);
951  setColumnWidth(eProvideDefaultValue, 29);
952  setColumnWidth(eValue, 200);
953  setColumnWidth(eDeleteButton, 25);
954 }
955 
956 void StateParameterEditor::buildFromMap(const StateParameterMap& map, const std::map<QString, std::pair<QString, QString> >& jsonStringMap)
957 {
958  emit buildRequested(map, jsonStringMap);
959 }
960 
961 void StateParameterEditor::__buildFromMap(const StateParameterMap& map, const std::map<QString, std::pair<QString, QString> >& jsonStringMap)
962 {
963  clearContents();
964  QWidget* tempW = new QLabel("mylabel", this);
965  tempW->deleteLater();
966  setRowCount(0);
967  // disconnect(this);
968  disconnect(this, SIGNAL(cellEntered(int, int)));
969  disconnect(this, SIGNAL(cellPressed(int, int)));
970  disconnect(this, SIGNAL(cellChanged(int, int)));
971  StateParameterMap::const_iterator it = map.begin();
972 
973  for (; it != map.end(); it++)
974  {
975  StateParameterIceBasePtr p = it->second;
976  JSONObjectPtr json = new JSONObject(communicator);
977  QString typeStr;
978  QString jsonStr;
979 
980  if (p->defaultValue)
981  {
982  json->serializeIceObject(p->defaultValue);
983  typeStr = QString::fromStdString(VariantContainerType::allTypesToString(p->defaultValue->getContainerType()));
984 
985  // ARMARX_INFO_S << VAROUT(typeStr.toStdString());
986  // ARMARX_INFO_S << VAROUT(json->asString(true));
987  if (VariantType::IsBasicType(Variant::hashTypeName(typeStr.toStdString())))
988  {
989  jsonStr = QString::fromUtf8(json->getElement("variant")->getElement("value")->toString().c_str());
990  }
991  else
992  {
993  jsonStr = QString::fromUtf8(json->asString(true).c_str());
994  }
995 
996  // ARMARX_INFO_S << VAROUT(jsonStr.toStdString());
997  }
998  else if (jsonStringMap.find(QString::fromStdString(it->first)) != jsonStringMap.end())
999  {
1000  typeStr = jsonStringMap.at(QString::fromStdString(it->first)).first;
1001  jsonStr = jsonStringMap.at(QString::fromStdString(it->first)).second;
1002  }
1003 
1004  addParameterRow(QString::fromStdString(it->first),
1005  typeStr,
1006  jsonStr,
1007  p->optionalParam);
1008  }
1009 
1010  addParameterRow();
1011  connectUserEditSlots();
1012  // setHeaders();
1013 
1014 }
1015 
1016 
1017 
1018 QWidget* StateParameterEditor::LineEditDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
1019 {
1020  QLineEdit* lineEdit = new QLineEdit(parent);
1021  QString regExpStr("(|([a-z_]{1})([a-z_0-9]*))");
1022  QRegExp reg(regExpStr, Qt::CaseInsensitive);
1023  lineEdit->setValidator(new QRegExpValidator(reg, lineEdit));
1024  return lineEdit;
1025 }
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
armarx::StateParameterEditor::eOptional
@ eOptional
Definition: StateParameterEditor.h:49
armarx::StateParameterEditor::eType
@ eType
Definition: StateParameterEditor.h:48
armarx::StateParameterEditor::getKeys
QSet< QString > getKeys() const
Definition: StateParameterEditor.cpp:84
armarx::StateParameterEditor::eKey
@ eKey
Definition: StateParameterEditor.h:47
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
armarx::StateParameterEditor::getDefaultValueState
Qt::CheckState getDefaultValueState() const
Definition: StateParameterEditor.cpp:932
armarx::VariantType::List
const VariantContainerType List
Definition: SingleTypeVariantList.h:191
armarx::Variant::setLong
void setLong(long n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition: Variant.cpp:290
armarx::StateParameterEditor::getStringValueMap
StringVariantContainerBaseMap getStringValueMap() const
Definition: StateParameterEditor.cpp:141
JSONObject.h
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::StateParameterEditor::setDefaultValueState
void setDefaultValueState(const Qt::CheckState &value)
Definition: StateParameterEditor.cpp:937
list
list(APPEND SOURCES ${QT_RESOURCES}) set(COMPONENT_LIBS ArmarXGui ArmarXCoreObservers ArmarXCoreEigen3Variants PlotterController $
Definition: CMakeLists.txt:49
armarx::JSONObject
The JSONObject class is used to represent and (de)serialize JSON objects.
Definition: JSONObject.h:43
armarx::VariantType::Map
const VariantContainerType Map
Definition: StringValueMap.h:247
armarx::Variant::setString
void setString(const std::string &s, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to s.
Definition: Variant.cpp:340
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::Variant::getTypes
static const std::map< VariantTypeId, std::string > & getTypes()
Returns the mapping of currently registered types.
Definition: Variant.cpp:746
armarx::VariantType::Bool
const VariantTypeId Bool
Definition: Variant.h:915
armarx::StateParameterEditor::getStateParameters
StateParameterMap getStateParameters() const
Definition: StateParameterEditor.cpp:113
armarx::StateParameterEditor::addParameterRow
int addParameterRow()
Definition: StateParameterEditor.cpp:424
armarx::StateParameterEditor::createValueButton
void createValueButton(int row, const QString &jsonValue)
Definition: StateParameterEditor.cpp:531
StateParameter.h
armarx::Variant::setInt
void setInt(int n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition: Variant.cpp:274
armarx::StateParameterEditor::getType
QString getType(int row) const
Definition: StateParameterEditor.cpp:366
armarx::StateParameterEditor::editDefaultButtonClicked
void editDefaultButtonClicked()
Definition: StateParameterEditor.cpp:774
armarx::StateParameterEditor::buildFromMap
void buildFromMap(const StateParameterMap &map, const std::map< QString, std::pair< QString, QString > > &jsonStringMap=std::map< QString, std::pair< QString, QString >>())
Definition: StateParameterEditor.cpp:956
IceInternal::Handle< JSONObject >
armarx::StateParameterEditor::getStateParameter
StateParameterIceBasePtr getStateParameter(int row) const
Definition: StateParameterEditor.cpp:99
armarx::StateParameterEditor::getValueAsString
QString getValueAsString(int row) const
Definition: StateParameterEditor.cpp:160
armarx::StateParameterEditor::getKey
QString getKey(int row) const
Definition: StateParameterEditor.cpp:351
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:919
armarx::Variant::setDouble
void setDouble(double d, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to d.
Definition: Variant.cpp:323
armarx::StateParameterEditor::eDeleteButton
@ eDeleteButton
Definition: StateParameterEditor.h:52
armarx::StateParameterEditor::setKeyBlackList
void setKeyBlackList(const QSet< QString > &keyBlackList)
Definition: StateParameterEditor.cpp:79
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::Variant::setBool
void setBool(bool b, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to b.
Definition: Variant.cpp:357
armarx::SingleVariant
The SingleVariant class is required to store single Variant instances in VariantContainer subclasses.
Definition: VariantContainer.h:109
armarx::StateParameterEditor::getVariantContainer
VariantContainerBasePtr getVariantContainer(int row) const
Definition: StateParameterEditor.cpp:263
armarx::statechartmodel::StateParameterMap
QMap< QString, StateParameterPtr > StateParameterMap
Definition: StateParameter.h:46
armarx::StateParameterEditor::getJson
QString getJson(QString key) const
Definition: StateParameterEditor.cpp:177
armarx::StateParameterEditor::refreshVariantTypes
void refreshVariantTypes()
Definition: StateParameterEditor.cpp:763
armarx::Variant::setFloat
void setFloat(float f, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to f.
Definition: Variant.cpp:306
armarx::StateParameterEditor::getIsOptional
bool getIsOptional(int row) const
Definition: StateParameterEditor.cpp:412
armarx::StateParameterEditor::getRow
int getRow(const QString &key) const
Definition: StateParameterEditor.cpp:391
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
armarx::StateParameterEditor::setHeaders
void setHeaders()
Definition: StateParameterEditor.cpp:945
armarx::VariantType::IsBasicType
bool IsBasicType(VariantTypeId id)
Definition: Variant.cpp:772
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::StateParameterEditor::eProvideDefaultValue
@ eProvideDefaultValue
Definition: StateParameterEditor.h:50
armarx::StateParameterEditor::rowFilled
void rowFilled(int rowId, const QString &key)
armarx::VariantContainerType
Definition: VariantContainer.h:185
GfxTL::Off
OnOff< false > Off
Definition: OnOff.h:11
option
#define option(type, fn)
ArmarXWidgetController.h
armarx::StateParameterEditor::buildRequested
void buildRequested(const StateParameterMap &map, const std::map< QString, std::pair< QString, QString > > &jsonStringMap)
armarx::viz::toString
const char * toString(InteractionFeedbackType type)
Definition: Interaction.h:27
StateParameterEditor.h
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
armarx::StateParameterEditor::checkAndUpdateRowCount
void checkAndUpdateRowCount(int row, int column)
Definition: StateParameterEditor.cpp:716
armarx::Variant::hashTypeName
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
Definition: Variant.cpp:699
armarx::StateParameter::create
static StateParameterPtr create()
Definition: StateParameter.cpp:58
armarx::StateParameterEditor::StateParameterEditor
StateParameterEditor(QWidget *parent=0, const StateParameterMap &params=StateParameterMap())
Definition: StateParameterEditor.cpp:50
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:141
armarx::VariantType::String
const VariantTypeId String
Definition: Variant.h:920
armarx::StateParameterEditor::deleteRow
void deleteRow()
Definition: StateParameterEditor.cpp:698
armarx::StateParameterEditor::eValue
@ eValue
Definition: StateParameterEditor.h:51
armarx::StateParameterEditor::rowAdded
void rowAdded(int rowId)
Variant.h
armarx::VariantContainerType::FromString
static ContainerTypePtr FromString(const std::string &typeStr)
Definition: VariantContainer.cpp:262
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::StateParameterEditor::typeCbChanged
void typeCbChanged(const QString &text)
Definition: StateParameterEditor.cpp:633
armarx::VariantContainerType::allTypesToString
static std::string allTypesToString(const ContainerTypePtr &type)
Definition: VariantContainer.cpp:232
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:36