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