32 #include <Ice/ObjectFactory.h>
36 #include <QPushButton>
38 #include <QVBoxLayout>
39 #include <QInputDialog>
41 #include <QDialogButtonBox>
43 #include <QToolButton>
44 #include <QMessageBox>
45 #include <QStyledItemDelegate>
52 defaultValueState(Qt::Unchecked)
55 setlocale(LC_ALL,
"C");
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);
63 if (params.size() == 0)
74 setItemDelegateForColumn(
eKey, &delegate);
81 this->keyBlackList = keyBlackList;
88 for (
int row = 0; row < rowCount(); row++)
90 if (item(row,
eKey) && !item(row,
eKey)->text().isEmpty())
92 result.insert(item(row,
eKey)->text());
101 if (
getKey(row).isEmpty())
117 for (
int row = 0; row < rowCount(); ++row)
123 result[
getKey(row).toStdString()] = param;
143 StringVariantContainerBaseMap result;
145 for (
int row = 0; row < rowCount(); ++row)
148 if (
getKey(row).length() == 0)
154 result[
getKey(row).toStdString()] = con;
162 if (row >= rowCount())
164 throw LocalException(
"row index out of range: ") << row;
167 QLineEdit* valueEdit = qobject_cast<QLineEdit*>(cellWidget(row,
eValue));
171 throw LocalException(
"value edit ptr is NULL");
174 return valueEdit->text();
181 for (
int i = 0; i < rowCount(); i++)
192 throw LocalException(
"row index out of range: ") << row;
195 if (row >= rowCount())
197 throw LocalException(
"row index out of range: ") << row;
200 VariantContainerBasePtr container;
203 QLineEdit* valueEdit = qobject_cast<QLineEdit*>(cellWidget(row,
eValue));
204 QPushButton* editButton = qobject_cast<QPushButton*>(cellWidget(row,
eValue));
209 if (valueEdit && valueEdit->isEnabled())
216 variant.
setInt(valueEdit->text().toInt());
220 variant.
setLong(valueEdit->text().toLong());
224 if (valueEdit->text() ==
"true" || valueEdit->text() ==
"1")
235 variant.
setFloat(valueEdit->text().toFloat());
239 variant.
setDouble(valueEdit->text().toDouble());
244 variant.
setString(valueEdit->text().trimmed().toStdString());
248 jsonObject->serializeIceObject(container);
249 return QString::fromUtf8(jsonObject->toString().c_str());
251 else if (editButton && editButton->isEnabled())
253 QString jsonValue = editButton->property(
"JsonValue").toString();
265 if (row >= rowCount())
267 throw LocalException(
"row index out of range: ") << row;
270 VariantContainerBasePtr result;
273 QLineEdit* valueEdit = qobject_cast<QLineEdit*>(cellWidget(row,
eValue));
274 QPushButton* editButton = qobject_cast<QPushButton*>(cellWidget(row,
eValue));
276 if ((valueEdit && valueEdit->isEnabled()) || item(row,
eValue))
280 QString valueStr = valueEdit ? valueEdit->text() : item(row,
eValue)->text();
284 variant.
setInt(valueStr.toInt());
288 variant.
setLong(valueStr.toLong());
292 if (valueStr.compare(
"true", Qt::CaseInsensitive) == 0 || valueStr ==
"1")
303 variant.
setFloat(valueStr.toFloat());
312 variant.
setString(valueStr.trimmed().toStdString());
317 else if (editButton && editButton->isEnabled())
319 QString jsonValue = editButton->property(
"JsonValue").toString();
321 if (jsonValue.isEmpty())
328 jsonObject->fromString(jsonValue.toUtf8().data());
332 SerializablePtr obj = jsonObject->deserializeIceObject();
333 result = VariantContainerBasePtr::dynamicCast(obj);
341 catch (std::exception& e)
343 ARMARX_WARNING_S <<
"JSON string for type " << type.toStdString() <<
" could not be deserialized: " << e.what();
353 if (row >= rowCount())
355 throw LocalException(
"row index out of range: ") << row;
358 if (!item(row,
eKey))
363 return item(row,
eKey)->text();
368 if (row >= rowCount())
370 throw LocalException(
"row index out of range: ") << row;
373 QComboBox* CBvalueType = qobject_cast<QComboBox*>(cellWidget(row, 1));
380 QString type = getBaseNameFromHumanName(CBvalueType->currentText());
395 for (
int i = 0; i < rowCount(); i++)
406 throw LocalException(
"could not find key ") << key.toStdString();
414 if (row >= rowCount())
416 throw LocalException(
"row index out of range: ") << row;
419 QComboBox* cbOptional = qobject_cast<QComboBox*>(cellWidget(row,
eOptional));
420 return cbOptional->currentText() ==
"true";
427 int row = rowCount();
429 setItem(row,
eKey,
new QTableWidgetItem());
435 QComboBox* valueTypebox =
new QComboBox;
436 valueTypebox->setEditable(
true);
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)));
448 QComboBox* cbOptional;
449 cbOptional =
new QComboBox();
450 cbOptional->addItems(QString(
"true;false").
split(
";"));
451 cbOptional->setCurrentIndex(1);
452 setCellWidget(row,
eOptional, cbOptional);
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");
461 connect(deleteButton, SIGNAL(clicked()),
this, SLOT(
deleteRow()));
471 item(row,
eKey)->setText(key);
473 QComboBox* valueTypeBox = qobject_cast<QComboBox*>(cellWidget(row,
eType));
475 valueTypeBox->setEditText(getHumanNameFromBaseName(variantIdStr));
477 QComboBox* optionalBox = qobject_cast<QComboBox*>(cellWidget(row,
eOptional));
481 optionalBox->setCurrentIndex(0);
485 optionalBox->setCurrentIndex(1);
488 if (!
value.isEmpty())
497 QLineEdit* valueEdit =
new QLineEdit;
501 valueEdit->setEnabled(
false);
504 setCellWidget(row,
eValue, valueEdit);
508 if (
value.at(0) ==
'\"')
518 value =
value.replace(
"\\\"",
"\"").replace(
"\\\\",
"\\");
521 valueEdit->setText(
value);
534 QComboBox* typeBox = qobject_cast<QComboBox*>(cellWidget(row,
eType));
536 QString typeString = getBaseNameFromHumanName(typeBox->currentText());
537 QWidget* oldWidget = qobject_cast<QWidget*>(cellWidget(row,
eValue));
544 QPushButton* editValueButton =
new QPushButton(
"Edit");
548 editValueButton->setEnabled(
false);
551 setCellWidget(row,
eValue, editValueButton);
555 if (jsonValue.isEmpty())
562 Ice::ValueFactoryPtr factory = communicator->getValueFactoryManager()->find(variantContainerType->typeId);
566 Ice::ValuePtr objectPtr = factory->create(variantContainerType->typeId);
568 VariantDataPtr var = VariantDataPtr::dynamicCast(objectPtr);
574 Ice::ValueFactoryPtr subfactory = communicator->getValueFactoryManager()->find(variantContainerType->subType->typeId);
579 subfactory = IceInternal::factoryTable->getValueFactory(variantContainerType->subType->typeId);
584 Ice::ValuePtr subObj = subfactory->create(variantContainerType->subType->typeId);
585 VariantDataPtr var = VariantDataPtr::dynamicCast(subObj);
603 map->addVariant(
"mykey",
Variant(var));
612 jsonObject->serializeIceObject(SerializablePtr::dynamicCast(objectPtr));
615 editValueButton->setProperty(
"JsonValue", QString::fromStdString(jsonObject->asString(
true)));
619 editValueButton->setProperty(
"JsonValue", jsonValue);
627 editValueButton->setEnabled(
false);
635 QWidget* wid = qobject_cast<QWidget*>(sender());
641 int row = rowAt(wid->pos().y());
643 QWidget* valueWidget = cellWidget(row,
eValue);
645 QComboBox* typeBox = qobject_cast<QComboBox*>(cellWidget(row,
eType));
646 std::string typeStr = getBaseNameFromHumanName(typeBox->currentText()).toStdString();
651 QLineEdit* valueLineEdit = qobject_cast<QLineEdit*>(valueWidget);
655 valueLineEdit =
new QLineEdit;
656 setCellWidget(row,
eValue, valueLineEdit);
661 valueLineEdit->setEnabled(
false);
666 valueLineEdit->setValidator(NULL);
670 valueLineEdit->setValidator(
new QIntValidator(
this));
674 QRegExp rx(
"((1|0)|(true|false))");
675 QValidator* validator =
new QRegExpValidator(rx,
this);
676 valueLineEdit->setValidator(validator);
680 valueLineEdit->setValidator(
new QDoubleValidator(
this));
683 QString
value = valueLineEdit->text();
686 if (valueLineEdit->validator() && valueLineEdit->validator()->validate(
value, pos) != QValidator::Acceptable)
688 valueLineEdit->setText(
"");
701 QWidget* wid = qobject_cast<QWidget*>(sender());
702 QModelIndex mIndex = indexAt(wid->pos());
713 connectUserEditSlots();
724 QWidget* valueWidget = cellWidget(row,
eValue);
725 QWidget* valueLineEdit = qobject_cast<QWidget*>(valueWidget);
729 valueLineEdit->setEnabled(
false);
734 QWidget* valueWidget = cellWidget(row,
eValue);
735 QWidget* valueLineEdit = qobject_cast<QWidget*>(valueWidget);
739 valueLineEdit->setEnabled(
true);
743 else if (column ==
eKey)
745 auto keyitem = item(row,
eKey);
749 if ((keyBlackList.find(keyitem->text()) != keyBlackList.end() || findItems(keyitem->text(), Qt::MatchExactly).size() > 1))
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)";
757 if (row >= rowCount() - 1 && item(rowCount() - 1, 0) && !item(rowCount() - 1, 0)->text().isEmpty())
765 for (
int row = 0; row < rowCount(); row++)
767 QComboBox* valueTypeBox = qobject_cast<QComboBox*>(cellWidget(row,
eType));
768 addVariantTypesToComboBox(valueTypeBox);
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());
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);
791 connect(buttonBox, SIGNAL(accepted()), &editDefaultDialog, SLOT(accept()));
792 connect(buttonBox, SIGNAL(rejected()), &editDefaultDialog, SLOT(reject()));
794 if (editDefaultDialog.exec() == QDialog::Accepted)
796 sender()->setProperty(
"JsonValue", dialogTextEdit->toPlainText());
800 void StateParameterEditor::connectUserEditSlots()
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);
807 void StateParameterEditor::addVariantTypesToComboBox(QComboBox* combo)
820 QString typeName = tr(pair.second.c_str());
823 if (typeName.contains(
"Invalid"))
828 list.append(getHumanNameFromBaseName(typeName));
835 std::vector<VariantContainerType> containers;
843 QString typeName = tr(it.second.c_str());
846 if (typeName.contains(
"Invalid"))
852 typeName = QString::fromStdString(typeStr);
853 list.append(getHumanNameFromBaseName(typeName));
861 qSort(
list.begin(),
list.end(), compareVariantNames);
862 combo->addItems(
list);
865 QString StateParameterEditor::getHumanNameFromBaseName(QString variantBaseTypeName)
const
869 return variantBaseTypeName;
872 std::string humanName = variantInfo->getNestedHumanNameFromBaseName(variantBaseTypeName.toUtf8().data());
874 if (humanName.empty())
876 return variantBaseTypeName;
879 return QString::fromUtf8(humanName.c_str());
882 QString StateParameterEditor::getBaseNameFromHumanName(QString humanName)
const
889 std::string variantBaseTypeName = variantInfo->getNestedBaseNameFromHumanName(humanName.toUtf8().data());
891 if (variantBaseTypeName.empty())
896 return QString::fromUtf8(variantBaseTypeName.c_str());
899 bool StateParameterEditor::compareVariantNames(
const QString&
a,
const QString& b)
904 pa =
a.contains(
"(");
905 pb = b.contains(
"(");
913 pa =
a.contains(
":");
914 pb = b.contains(
":");
922 pa =
a.count() > 0 &&
a[0].isLower();
923 pb = b.count() > 0 && b[0].isLower();
930 return a.compare(b) < 0;
934 return defaultValueState;
939 defaultValueState =
value;
947 setHorizontalHeaderLabels(QString(
"Key;Type;Optional;Def;Value;Del").
split(
";"));
948 setColumnWidth(
eKey, 180);
949 setColumnWidth(
eType, 225);
952 setColumnWidth(
eValue, 200);
961 void StateParameterEditor::__buildFromMap(
const StateParameterMap& map,
const std::map<QString, std::pair<QString, QString> >& jsonStringMap)
964 QWidget* tempW =
new QLabel(
"mylabel",
this);
965 tempW->deleteLater();
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();
973 for (; it != map.end(); it++)
975 StateParameterIceBasePtr p = it->second;
982 json->serializeIceObject(p->defaultValue);
989 jsonStr = QString::fromUtf8(json->getElement(
"variant")->getElement(
"value")->toString().c_str());
993 jsonStr = QString::fromUtf8(json->asString(
true).c_str());
998 else if (jsonStringMap.find(QString::fromStdString(it->first)) != jsonStringMap.end())
1000 typeStr = jsonStringMap.at(QString::fromStdString(it->first)).first;
1001 jsonStr = jsonStringMap.at(QString::fromStdString(it->first)).second;
1011 connectUserEditSlots();
1018 QWidget* StateParameterEditor::LineEditDelegate::createEditor(QWidget* parent,
const QStyleOptionViewItem&
option,
const QModelIndex&
index)
const
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));