StatechartEditorParameterEditor.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 <QAction>
27#include <QComboBox>
28#include <QCompleter>
29#include <QDialog>
30#include <QDialogButtonBox>
31#include <QInputDialog>
32#include <QLabel>
33#include <QLineEdit>
34#include <QMenu>
35#include <QMessageBox>
36#include <QPropertyAnimation>
37#include <QPushButton>
38#include <QStyledItemDelegate>
39#include <QTableWidgetItem>
40#include <QTextEdit>
41#include <QToolButton>
42#include <QVBoxLayout>
43
46
47//#include <ArmarXCore/statechart/StateParameter.h>
52
54//#include <ArmarXCore/statechart/StateParameter.h>
55#include <memory>
56
57#include <Ice/ObjectFactory.h>
58
60
64
65namespace armarx
66{
67 void
72
74 QWidget* parent,
77 QTableWidget(parent),
78 // currentProfile(currentProfile),
79 state(state),
80 defaultValueState(Qt::Unchecked)
81 {
82
83 // For jsonobject double/float serilization on german/spanish pcs....
84 setlocale(LC_ALL, "C");
85
86 setColumnCount(6);
87 qRegisterMetaType<statechartmodel::StateParameterMap>("statechartmodel::StateParameterMap");
88 // qRegisterMetaType<QVector<QString>>("QVector<QString>");
89 connect(this,
91 this,
92 SLOT(__buildFromMap(statechartmodel::StateParameterMap)),
93 Qt::QueuedConnection);
94
95 setHeaders();
96
97 if (params.size() == 0)
98 {
100 }
101 else
102 {
103 buildFromMap(params);
104 }
105
106
107 setItemDelegateForColumn(eKey, &delegate);
108
109 // horizontalHeaderItem(eAddtoParent)->setT;
110 connect(this, SIGNAL(rowAdded(int)), this, SLOT(addCustomColumn(int)));
111 connect(this, SIGNAL(rowFilled(int, QString)), this, SLOT(fillCustomColumn(int, QString)));
112
113 connect(this,
115 this,
117 }
118
119 void
121 {
122
123
124 AnimatedToolButton* showHelpButton = new AnimatedToolButton(this);
125
126
127 QIcon icon;
128 icon.addFile(
129 QString::fromUtf8(":/icons/help-about.ico"), QSize(), QIcon::Normal, QIcon::Off);
130 showHelpButton->setIcon(icon);
131 showHelpButton->setToolTip("Show or edit help to this parameter.");
132 connect(showHelpButton, SIGNAL(clicked()), this, SLOT(showHelpDialog()));
133
134 if (state && state->getParent())
135 {
136
137 QAction* addInputToParentAction = new QAction(showHelpButton);
138 QIcon icon;
139 icon.addFile(QString::fromUtf8(":/icons/add.png"), QSize(), QIcon::Normal, QIcon::Off);
140 addInputToParentAction->setIcon(icon);
141 addInputToParentAction->setIconVisibleInMenu(true);
142 addInputToParentAction->setText("Add to parent's input");
143 addInputToParentAction->setToolTip(
144 "Add this parameter to parent's input. This applies immediatly.");
145 addInputToParentAction->setData(row);
146 connect(addInputToParentAction, SIGNAL(triggered()), this, SLOT(addInputToParent()));
147
148 QMenu* subMenu = new QMenu(showHelpButton);
149 subMenu->addAction(addInputToParentAction);
150 showHelpButton->setMenu(subMenu);
151 }
152
153 setCellWidget(row, eAdditionalButtons, showHelpButton);
154 }
155
156 void
158 {
159 QToolButton* showHelpButton =
160 qobject_cast<QToolButton*>(cellWidget(row, eAdditionalButtons));
161
162 if (showHelpButton)
163 {
164 auto it = originalParamMap.find(key);
165
166 if (it != originalParamMap.end())
167 {
169
170 if (pm)
171 {
172 showHelpButton->setProperty("MarkdownDocText", pm->description);
173 QColor color =
174 pm->description.isEmpty() ? QColor{250, 0, 0} : QColor{0, 0, 250};
175
176 QPalette pal = showHelpButton->palette();
177 showHelpButton->setAutoFillBackground(true);
178 QPropertyAnimation* animation =
179 new QPropertyAnimation(showHelpButton, "color", this);
180 animation->setDuration(3000);
181 float t = 0;
182 while (t < 1)
183 {
184 animation->setKeyValueAt(t, color);
185 t += 0.1f;
186 animation->setKeyValueAt(t, pal.color(QPalette::Button));
187 t += 0.1f;
188 }
189 animation->setKeyValueAt(1, pal.color(QPalette::Button));
190 animation->setEasingCurve(QEasingCurve::InOutQuad);
191 animation->start();
192 }
193
194 originalParamMap.erase(it);
195 }
196 }
197 }
198
199 void
201 {
202
203 QDialog editDefaultDialog;
204 editDefaultDialog.setWindowTitle("Statechart Parameter Documentation Editor");
205 editDefaultDialog.resize(QSize(600, 400));
206 MarkdownEditor* dialogTextEdit = new MarkdownEditor(this);
207 dialogTextEdit->setPlainText(sender()->property("MarkdownDocText").toString());
208
209 QVBoxLayout* layout = new QVBoxLayout;
210 layout->addWidget(dialogTextEdit);
211 QDialogButtonBox* buttonBox = new QDialogButtonBox(dialogTextEdit);
212 buttonBox->setOrientation(Qt::Horizontal);
213 buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
214 layout->addWidget(buttonBox);
215 editDefaultDialog.setLayout(layout);
216
217 connect(buttonBox, SIGNAL(accepted()), &editDefaultDialog, SLOT(accept()));
218 connect(buttonBox, SIGNAL(rejected()), &editDefaultDialog, SLOT(reject()));
219
220 if (editDefaultDialog.exec() == QDialog::Accepted)
221 {
222 sender()->setProperty("MarkdownDocText", dialogTextEdit->toPlainText());
223 }
224 }
225
226 void
228 {
229
230 int row;
231 QAction* action = qobject_cast<QAction*>(sender());
232 row = action->data().toInt();
233 QString keyName = item(row, eKey)->text();
235 auto parent = state->getParent();
237 ARMARX_CHECK_EXPRESSION(keyName.length() > 0);
238 auto inputAndLocal = parent->getInputAndLocalParameters();
239
240 if (inputAndLocal.count(keyName) > 0)
241 {
242 QMessageBox::warning(
243 this, "State Editing Error", "The key '" + keyName + "' already exists");
244 return;
245 }
246
247 statechartmodel::StateParameterMap input = parent->getInputParameters();
248 input.insert(keyName, getStateParameter(row));
249 state->getParent()->setInputParameters(input);
250 }
251
252 void
254 {
255 auto profileNames = getRelevantProfiles();
256 int columnCount = eEditableValue + profileNames.size();
257
258 setColumnCount(columnCount);
259 setColumnWidth(eAdditionalButtons, 35);
260
261 if (!horizontalHeaderItem(eAdditionalButtons))
262 {
263 setHorizontalHeaderItem(eAdditionalButtons, new QTableWidgetItem(""));
264 }
265
266 for (int i = 0; i < profileNames.size(); ++i)
267 {
268 setColumnWidth(eEditableValue + i, 200);
269 setHorizontalHeaderItem(eEditableValue + i, new QTableWidgetItem(profileNames[i]));
270 }
271
272
273 if (state && state->getParent())
274 {
275 // horizontalHeaderItem(eAddtoParent)->setText();
276 }
277 }
278
279 void
280 StatechartEditorParameterEditor::setKeyBlackList(const QSet<QString>& keyBlackList)
281 {
282 this->keyBlackList = keyBlackList;
283 }
284
285 QSet<QString>
287 {
288 QSet<QString> result;
289
290 for (int row = 0; row < rowCount(); row++)
291 {
292 if (item(row, eKey) && !item(row, eKey)->text().isEmpty())
293 {
294 result.insert(item(row, eKey)->text());
295 }
296 }
297
298 return result;
299 }
300
301 QSet<QString>
303 {
304 QSet<QString> types;
305 for (int i = 0; i < rowCount(); ++i)
306 {
307 types.insert(getType(i));
308 }
309 return types;
310 }
311
314 {
315 if (getKey(row).isEmpty())
316 {
318 }
319
320 statechartmodel::StateParameterPtr p = std::make_shared<statechartmodel::StateParameter>();
321 p->type = getType(getKey(row));
322 p->optional = getIsOptional(row);
323
324 if (auto descriptionWidget =
326 {
327 p->description = descriptionWidget->property("MarkdownDocText").toString();
328 }
329
330 auto jsonValues = getProfileJsonMap(getKey(row));
331 auto variants = getProfileVariantContainerMap(row);
332
333 for (const auto& profileName : getRelevantProfiles())
334 {
335 p->profileDefaultValues[profileName] = {variants[profileName], jsonValues[profileName]};
336 }
337
338 return p;
339 }
340
343 {
345
346 for (int row = 0; row < rowCount(); ++row)
347 {
348 if (auto param = getStateParameter(row))
349 {
350 result[getKey(row)] = param;
351 }
352 }
353
354 return result;
355 }
356
357 //StateParameterMap StatechartEditorParameterEditor::getStateParametersWithoutValue()
358 //{
359 // StateParameterMap result;
360 // for (int row = 0; row < rowCount(); ++row) {
361 // StateParameterIceBasePtr param = new StateParameterIceBase();
362 //if(getKey(row).length() == 0)
363 // continue;
364
365 // }
366 //}
367
368 QMap<QString, QString>
370 {
371 if (row >= rowCount() || row < 0)
372 {
373 throw LocalException("row index out of range: ") << row;
374 }
375
376 QMap<QString, QString> result;
377
378 auto profileNames = getRelevantProfiles();
379
380 for (int i = 0; i < profileNames.size(); ++i)
381 {
382 auto widget =
383 qobject_cast<ProfileDefaultValueEditWidget*>(cellWidget(row, eEditableValue + i));
384
385 if (auto value = widget->getValueAsString())
386 {
387 result[profileNames[i]] = *value;
388 }
389 }
390
391 return result;
392 }
393
394 QMap<QString, QString>
396 {
397 int row = -1;
398
399 for (int i = 0; i < rowCount(); i++)
400 {
401 if (getKey(i) == key)
402 {
403 row = i;
404 break;
405 }
406 }
407
408 if (row >= rowCount() || row < 0)
409 {
410 throw LocalException("row index out of range: ") << row;
411 }
412
413 QMap<QString, QString> result;
414
415 auto profileNames = getRelevantProfiles();
416
417 for (int i = 0; i < profileNames.size(); ++i)
418 {
419 auto widget =
420 qobject_cast<ProfileDefaultValueEditWidget*>(cellWidget(row, eEditableValue + i));
421
422 if (auto value = widget->getValueAsJson())
423 {
424 result[profileNames[i]] = *value;
425 }
426 }
427
428 return result;
429 }
430
431 QMap<QString, VariantContainerBasePtr>
433 {
434 if (row >= rowCount() || row < 0)
435 {
436 throw LocalException("row index out of range: ") << row;
437 }
438
439 QMap<QString, VariantContainerBasePtr> result;
440
441 auto profileNames = getRelevantProfiles();
442
443 for (int i = 0; i < profileNames.size(); ++i)
444 {
445 auto widget =
446 qobject_cast<ProfileDefaultValueEditWidget*>(cellWidget(row, eEditableValue + i));
447 result[profileNames[i]] = widget->getVariantContainer();
448 }
449
450 return result;
451 }
452
453 QString
455 {
456 if (row >= rowCount())
457 {
458 throw LocalException("row index out of range: ") << row;
459 }
460
461 if (!item(row, eKey))
462 {
463 return "";
464 }
465
466 return item(row, eKey)->text();
467 }
468
469 QString
471 {
472 if (row >= rowCount())
473 {
474 throw LocalException("row index out of range: ") << row;
475 }
476
477 QComboBox* CBvalueType = qobject_cast<QComboBox*>(cellWidget(row, 1));
478
479 if (!CBvalueType)
480 {
481 return "";
482 }
483
484 QString type = getBaseNameFromHumanName(CBvalueType->currentText()); //@@@
485 return type;
486 }
487
488 QString
490 {
491 int row = getRow(key);
492 return getType(row);
493 }
494
495 int
497 {
498 int row = -1;
499
500 for (int i = 0; i < rowCount(); i++)
501 {
502 if (getKey(i) == key)
503 {
504 row = i;
505 break;
506 }
507 }
508
509 if (row == -1)
510 {
511 throw LocalException("could not find key ") << key.toStdString();
512 }
513
514 return row;
515 }
516
517 bool
519 {
520 if (row >= rowCount())
521 {
522 throw LocalException("row index out of range: ") << row;
523 }
524
525 QComboBox* cbOptional = qobject_cast<QComboBox*>(cellWidget(row, eOptional));
526 return cbOptional->currentText() == "true";
527 }
528
529 int
531 {
532 // ARMARX_IMPORTANT_S << "Adding row";
533 int row = rowCount();
534 insertRow(row);
535 setItem(row, eKey, new QTableWidgetItem());
536
537 // setItem(row, eProvideDefaultValue, new QTableWidgetItem());
538 // item(row, eProvideDefaultValue)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
539 // item(row, eProvideDefaultValue)->setCheckState(defaultValueState);
540
541 QComboBox* valueTypebox = new QComboBox;
542 valueTypebox->setEditable(true);
543 // valueTypebox->setInsertPolicy(QComboBox::InsertAlphabetically);
544 // valueTypebox->setValidator(new QIntValidator(this));
545 setCellWidget(row, eType, valueTypebox);
546 QStringList types = addVariantTypesToComboBox(valueTypebox);
547 InfixCompleter* fullCompleter = new InfixCompleter(types, this);
548 fullCompleter->setCompletionMode(QCompleter::PopupCompletion);
549 fullCompleter->setCaseSensitivity(Qt::CaseInsensitive);
550 valueTypebox->setCompleter(fullCompleter);
551 valueTypebox->setEditText("string");
552 connect(valueTypebox, SIGNAL(editTextChanged(QString)), this, SLOT(typeCbChanged(QString)));
553 connect(valueTypebox->lineEdit(),
554 SIGNAL(textEdited(QString)),
555 fullCompleter,
556 SLOT(setCompletionInfix(QString)));
557 //valueTypebox->model()->sort(0);
558 QComboBox* cbOptional;
559 cbOptional = new QComboBox();
560 cbOptional->addItems(QString("true;false").split(";"));
561 cbOptional->setCurrentIndex(1);
562 setCellWidget(row, eOptional, cbOptional);
563
564
565 QIcon icon;
566 icon.addFile(
567 QString::fromUtf8(":/icons/dialog-close.ico"), QSize(), QIcon::Normal, QIcon::Off);
568 QToolButton* deleteButton = new QToolButton(this);
569 deleteButton->setIcon(icon);
570 deleteButton->setToolTip("Add this parameter to parent's input");
571 deleteButton->setToolTip("Delete this row");
572 setCellWidget(row, eDeleteButton, deleteButton);
573 connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteRow()));
574
575 auto profileNames = getRelevantProfiles();
576
577 for (int i = 0; i < profileNames.size(); ++i)
578 {
580 getBaseNameFromHumanName(valueTypebox->currentText()), QString(), communicator);
581 setCellWidget(row, eEditableValue + i, valueWidget);
582 }
583
584 emit rowAdded(row);
585 return row;
586 }
587
588 void
590 QString variantIdStr,
591 QVector<QString> values,
592 bool optional)
593 {
594 int row = addParameterRow();
595
596 item(row, eKey)->setText(key);
597
598 QComboBox* valueTypeBox = qobject_cast<QComboBox*>(cellWidget(row, eType));
599 // ARMARX_INFO_S << "type id: " << variantIdStr.toStdString() << " size: " << valueTypeBox->count();
600 valueTypeBox->setEditText(getHumanNameFromBaseName(variantIdStr));
601
602 QComboBox* optionalBox = qobject_cast<QComboBox*>(cellWidget(row, eOptional));
603 optionalBox->setCurrentIndex(optional ? 0 : 1);
604
605 for (int i = 0; i < values.size(); ++i)
606 {
607 ProfileDefaultValueEditWidget* valueWidget =
608 new ProfileDefaultValueEditWidget(variantIdStr, values[i], communicator);
609 setCellWidget(row, eEditableValue + i, valueWidget);
610 }
611
612 emit rowFilled(row, key);
613 }
614
615 void
617 {
618 QWidget* wid = qobject_cast<QWidget*>(sender());
619
620 /*QModelIndex mIndex =*/indexAt(
621 wid->pos()); // Some strange bug happens here: If this is used, it will deliver on table creation zero
622 // If indexAt is not called, wid->pos() delivers a 0,0 Point and then rowAt() also return wrong index
623 // ARMARX_INFO_S << VAROUT(wid->pos()) << VAROUT(rowAt(wid->pos().y()));
624
625 int row = rowAt(wid->pos().y());
626
627 QComboBox* typeBox = qobject_cast<QComboBox*>(cellWidget(row, eType));
628 QString typeStr = getBaseNameFromHumanName(typeBox->currentText()); //@@@
629
630 for (int i = eEditableValue; i < columnCount(); ++i)
631 {
632 if (ProfileDefaultValueEditWidget* valueWidget =
633 qobject_cast<ProfileDefaultValueEditWidget*>(cellWidget(row, i)))
634 {
635 if (typeStr != valueWidget->getType())
636 {
637 auto newWidget =
638 new ProfileDefaultValueEditWidget(typeStr, QString(), communicator);
639 setCellWidget(row, i, newWidget);
640 }
641
642 // valueWidget->setType(typeStr);
643 }
644 }
645 emit typeChanged(row, typeStr);
646 }
647
648 void
650 {
651 int row;
652 QWidget* wid = qobject_cast<QWidget*>(sender());
653 QModelIndex mIndex = indexAt(wid->pos());
654 row = mIndex.row();
655
656 disconnect(this);
657 removeRow(row);
658
659 if (rowCount() == 0)
660 {
662 }
663
664 connectUserEditSlots();
665 }
666
667 void
669 {
670 // ARMARX_IMPORTANT_S << "checking row: " << row << ", " << column;
671
672 // if(column == eProvideDefaultValue)
673 // {
674 // if(item(row,eProvideDefaultValue)->checkState() == Qt::Unchecked)
675 // {
676 // QWidget* valueWidget = cellWidget(row, eValue);
677 // QWidget* valueLineEdit = qobject_cast<QWidget*>(valueWidget);
678 // if(valueLineEdit){
679 // valueLineEdit->setEnabled(false);
680 // }
681 // }
682 // else
683 // {
684 // QWidget* valueWidget = cellWidget(row, eValue);
685 // QWidget* valueLineEdit = qobject_cast<QWidget*>(valueWidget);
686 // if(valueLineEdit){
687 // valueLineEdit->setEnabled(true);
688 // }
689 // }
690 // }
691 if (column == eKey)
692 {
693 auto keyitem = item(row, eKey);
694
695 if (keyitem)
696 {
697 if ((keyBlackList.find(keyitem->text()) != keyBlackList.end() ||
698 findItems(keyitem->text(), Qt::MatchExactly).size() > 1))
699 {
700 keyitem->setText(item(row, eKey)->text() + "_2");
701 ARMARX_WARNING_S << "Keys must be unique (input and local parameters share the "
702 "same key pool)";
703 }
704 }
705 }
706
707 if (row >= rowCount() - 1 && item(rowCount() - 1, 0) &&
708 !item(rowCount() - 1, 0)->text().isEmpty())
709 {
711 }
712 }
713
714 void
716 {
717 for (int row = 0; row < rowCount(); row++)
718 {
719 QComboBox* valueTypeBox = qobject_cast<QComboBox*>(cellWidget(row, eType));
720 addVariantTypesToComboBox(valueTypeBox);
721 // valueTypeBox->model()->sort(0);
722 }
723 }
724
725 void
726 StatechartEditorParameterEditor::connectUserEditSlots()
727 {
728 connect(this,
729 SIGNAL(cellEntered(int, int)),
730 this,
731 SLOT(checkAndUpdateRowCount(int, int)),
732 Qt::UniqueConnection);
733 connect(this,
734 SIGNAL(cellPressed(int, int)),
735 this,
736 SLOT(checkAndUpdateRowCount(int, int)),
737 Qt::UniqueConnection);
738 connect(this,
739 SIGNAL(cellChanged(int, int)),
740 this,
741 SLOT(checkAndUpdateRowCount(int, int)),
742 Qt::UniqueConnection);
743 }
744
745 QStringList
746 StatechartEditorParameterEditor::addVariantTypesToComboBox(QComboBox* combo)
747 {
748 if (!combo)
749 {
750 return QStringList();
751 }
752
753 combo->clear();
754
755
756 auto types = Variant::getTypes();
757 QStringList list;
758 for (std::pair<VariantTypeId, std::string> pair : types)
759 {
760 QString typeName = tr(pair.second.c_str());
761 //QString humanName = tr(Variant::getHumanName(pair->first).c_str());
762
763 if (typeName.contains("Invalid"))
764 {
765 continue;
766 }
767
768 list.append(getHumanNameFromBaseName(typeName));
769 /*if(combo->findText(typeName) == -1)
770 {
771 combo->addItem(getHumanNameFromBaseName(typeName));
772 }*/
773 }
774
775 std::vector<VariantContainerType> containers;
776 containers.push_back(VariantType::List);
777 containers.push_back(VariantType::Map);
778
779 for (VariantContainerType c : containers)
780 {
781 for (auto it : types)
782 {
783 QString typeName = tr(it.second.c_str());
784
785
786 if (typeName.contains("Invalid"))
787 {
788 continue;
789 }
790
791 std::string typeStr = VariantContainerType::allTypesToString(c(it.first).clone());
792 typeName = QString::fromStdString(typeStr);
793 list.append(getHumanNameFromBaseName(typeName));
794 /*if(combo->findText(typeName) == -1)
795 {
796 combo->addItem(getHumanNameFromBaseName(typeName));
797 }*/
798 }
799 }
800
801 qSort(list.begin(), list.end(), compareVariantNames);
802 combo->addItems(list);
803 return list;
804 }
805
806 QString
807 StatechartEditorParameterEditor::getHumanNameFromBaseName(QString variantBaseTypeName) const
808 {
809 if (!variantInfo)
810 {
811 return variantBaseTypeName;
812 }
813
814 std::string humanName =
815 variantInfo->getNestedHumanNameFromBaseName(variantBaseTypeName.toUtf8().data());
816
817 if (humanName.empty())
818 {
819 return variantBaseTypeName;
820 }
821
822 return QString::fromUtf8(humanName.c_str());
823 }
824
825 QString
826 StatechartEditorParameterEditor::getBaseNameFromHumanName(QString humanName) const
827 {
828 if (!variantInfo)
829 {
830 return humanName;
831 }
832
833 std::string variantBaseTypeName =
834 variantInfo->getNestedBaseNameFromHumanName(humanName.toUtf8().data());
835
836 if (variantBaseTypeName.empty())
837 {
838 return humanName;
839 }
840
841 return QString::fromUtf8(variantBaseTypeName.c_str());
842 }
843
844 bool
845 StatechartEditorParameterEditor::compareVariantNames(const QString& a, const QString& b)
846 {
847 bool pa, pb;
848
849 // list nested types after basic ones
850 pa = a.contains("(");
851 pb = b.contains("(");
852
853 if (pa != pb)
854 {
855 return pb;
856 }
857
858 // list human types before non resolved ones
859 pa = a.contains(":");
860 pb = b.contains(":");
861
862 if (pa != pb)
863 {
864 return pb;
865 }
866
867 // nested lower case (basic types) first
868 int ia = a.indexOf("(");
869 int ib = b.indexOf("(");
870 pa = ia > 0 && a.count() > ia + 1 && a[ia + 1].isLower();
871 pb = ib > 0 && b.count() > ib + 1 && b[ib + 1].isLower();
872 if (pa != pb && a.left(ia) == b.left(ib))
873 {
874 return !pb;
875 }
876
877 // lower case (basic types) first
878 pa = a.count() > 0 && a[0].isLower();
879 pb = b.count() > 0 && b[0].isLower();
880
881 if (pa != pb)
882 {
883 return pa;
884 }
885
886 return a.compare(b) < 0;
887 }
888
889 Qt::CheckState
891 {
892 return defaultValueState;
893 }
894
895 void
897 {
898 defaultValueState = value;
899 }
900
901 void
903 {
904 const auto& relevantProfiles = getRelevantProfiles();
905
906 for (int i = 0; i < relevantProfiles.size(); ++i)
907 {
908 hideColumn(eEditableValue + i);
909 }
910 }
911
912 void
914 {
915 QStringList headerLabels{"Key", "Type", "Optional", "Del"};
916 setColumnWidth(eKey, 180);
917 setColumnWidth(eType, 225);
918 setColumnWidth(eOptional, 70);
919 setColumnWidth(eDeleteButton, 25);
920 // setColumnWidth(eAdditionalButtons, 25);
921
922 auto profileNames = getRelevantProfiles();
923 int col = eEditableValue;
924
925 for (int i = 0; i < profileNames.size(); ++i)
926 {
927 setColumnWidth(col + i, 200);
928 headerLabels.push_back(profileNames[i]);
929 }
930
931 setHorizontalHeaderLabels(headerLabels);
932 }
933
934 void
940
941 void
942 StatechartEditorParameterEditor::__buildFromMap(const statechartmodel::StateParameterMap& map)
943 {
944 clearContents();
945 QWidget* tempW = new QLabel("mylabel", this);
946 tempW->deleteLater();
947 setRowCount(0);
948 // disconnect(this);
949 disconnect(this, SIGNAL(cellEntered(int, int)));
950 disconnect(this, SIGNAL(cellPressed(int, int)));
951 disconnect(this, SIGNAL(cellChanged(int, int)));
952
953 auto relevantProfiles = getRelevantProfiles();
954
955 for (const auto& entry : map.toStdMap())
956 {
957 const QString& name = entry.first;
958 const statechartmodel::StateParameterPtr& param = entry.second;
959
960 //JSONObjectPtr json = new JSONObject(communicator);
961 QVector<QString> jsonStrs;
962 QString typeStr = param->type;
963
964 for (const QString& profile : relevantProfiles)
965 {
966 QString jsonStr = param->profileDefaultValues[profile].second;
967 jsonStrs.push_back(jsonStr);
968 }
969
970 addParameterRow(name, typeStr, jsonStrs, param->optional);
971 }
972
974 connectUserEditSlots();
975 // setHeaders();
976 }
977
978 QVector<QString>
979 StatechartEditorParameterEditor::getRelevantProfiles() const
980 {
981 if (!currentProfile)
982 {
983 return QVector<QString>();
984 }
985
986 QVector<QString> result{QString::fromUtf8(currentProfile->getName().c_str())};
987 auto profile = currentProfile;
988
989 while ((profile = profile->getParent()))
990 {
991 result.push_back(QString::fromUtf8(profile->getName().c_str()));
992 }
993
994 return result;
995 }
996
997 QWidget*
998 StatechartEditorParameterEditor::LineEditDelegate::createEditor(
999 QWidget* parent,
1000 const QStyleOptionViewItem& option,
1001 const QModelIndex& index) const
1002 {
1003 QLineEdit* lineEdit = new QLineEdit(parent);
1004 QString regExpStr("(|([a-z_]{1})([a-z_0-9]*))");
1005 QRegExp reg(regExpStr, Qt::CaseInsensitive);
1006 lineEdit->setValidator(new QRegExpValidator(reg, lineEdit));
1007 return lineEdit;
1008 }
1009
1010 void
1012 {
1013 QString val = QString("background-color: rgb(%1, %2, %3);")
1014 .arg(color.red())
1015 .arg(color.green())
1016 .arg(color.blue());
1017 // ARMARX_INFO << "Setting value to " << val.toStdString();
1018 setStyleSheet(val);
1019 }
1020} // namespace armarx
uint8_t index
#define option(type, fn)
constexpr T c
This class changes the standard QCompleter to an infix match completer.
The MarkdownEditor is a widget that provides editing of raw text and viewing of processed markdown te...
QString toPlainText() const
void setPlainText(const QString &plainText)
QMap< QString, VariantContainerBasePtr > getProfileVariantContainerMap(int row) const
statechartmodel::StateParameterPtr getStateParameter(int row) const
void setKeyBlackList(const QSet< QString > &keyBlackList)
QMap< QString, QString > getValuesAsString(int row) const
QMap< QString, QString > getProfileJsonMap(QString key) const
statechartmodel::StateParameterMap getStateParameters() const
void typeChanged(int row, const QString &newType)
void buildFromMap(const statechartmodel::StateParameterMap &map)
void buildRequested(const statechartmodel::StateParameterMap &map)
void rowFilled(int rowId, const QString &key)
StatechartEditorParameterEditor(QWidget *parent=0, statechartmodel::StateInstancePtr state=statechartmodel::StateInstancePtr(), const statechartmodel::StateParameterMap &params=statechartmodel::StateParameterMap())
statechartmodel::StateParameterMap originalParamMap
void setStateInstance(statechartmodel::StateInstancePtr state)
void init(const statechartmodel::StateParameterMap &params)
static std::string allTypesToString(const ContainerTypePtr &type)
static const std::map< VariantTypeId, std::string > & getTypes()
Returns the mapping of currently registered types.
Definition Variant.cpp:863
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
const VariantContainerType Map
const VariantContainerType List
double a(double t, double a0, double j)
Definition CtrlUtil.h:45
QMap< QString, StateParameterPtr > StateParameterMap
std::shared_ptr< StateInstance > StateInstancePtr
std::shared_ptr< StateParameter > StateParameterPtr
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)