29#include <QDialogButtonBox>
30#include <QInputDialog>
35#include <QStyledItemDelegate>
40#include <Ice/ObjectFactory.h>
51 QTableWidget(parent), defaultValueState(Qt::Unchecked)
54 setlocale(LC_ALL,
"C");
57 qRegisterMetaType<StateParameterMap>(
"StateParameterMap");
58 qRegisterMetaType<std::map<QString, std::pair<QString, QString>>>(
59 "std::map<QString,std::pair<QString,QString> >");
62 SIGNAL(
buildRequested(StateParameterMap, std::map<QString, std::pair<QString, QString>>)),
64 SLOT(__buildFromMap(StateParameterMap, std::map<QString, std::pair<QString, QString>>)),
65 Qt::QueuedConnection);
68 if (params.size() == 0)
78 setItemDelegateForColumn(
eKey, &delegate);
84 this->keyBlackList = keyBlackList;
92 for (
int row = 0; row < rowCount(); row++)
94 if (item(row,
eKey) && !item(row,
eKey)->text().isEmpty())
96 result.insert(item(row,
eKey)->text());
103StateParameterIceBasePtr
106 if (
getKey(row).isEmpty())
121 StateParameterMap result;
123 for (
int row = 0; row < rowCount(); ++row)
129 result[
getKey(row).toStdString()] = param;
147StringVariantContainerBaseMap
150 StringVariantContainerBaseMap result;
152 for (
int row = 0; row < rowCount(); ++row)
155 if (
getKey(row).length() == 0)
161 result[
getKey(row).toStdString()] = con;
170 if (row >= rowCount())
172 throw LocalException(
"row index out of range: ") << row;
175 QLineEdit* valueEdit = qobject_cast<QLineEdit*>(cellWidget(row,
eValue));
179 throw LocalException(
"value edit ptr is NULL");
182 return valueEdit->text();
190 for (
int i = 0; i < rowCount(); i++)
201 throw LocalException(
"row index out of range: ") << row;
204 if (row >= rowCount())
206 throw LocalException(
"row index out of range: ") << row;
209 VariantContainerBasePtr container;
212 QLineEdit* valueEdit = qobject_cast<QLineEdit*>(cellWidget(row,
eValue));
213 QPushButton* editButton = qobject_cast<QPushButton*>(cellWidget(row,
eValue));
218 if (valueEdit && valueEdit->isEnabled())
225 variant.
setInt(valueEdit->text().toInt());
229 variant.
setLong(valueEdit->text().toLong());
233 if (valueEdit->text() ==
"true" || valueEdit->text() ==
"1")
244 variant.
setFloat(valueEdit->text().toFloat());
248 variant.
setDouble(valueEdit->text().toDouble());
253 variant.
setString(valueEdit->text().trimmed().toStdString());
257 jsonObject->serializeIceObject(container);
258 return QString::fromUtf8(jsonObject->toString().c_str());
260 else if (editButton && editButton->isEnabled())
262 QString jsonValue = editButton->property(
"JsonValue").toString();
271VariantContainerBasePtr
274 if (row >= rowCount())
276 throw LocalException(
"row index out of range: ") << row;
279 VariantContainerBasePtr result;
282 QLineEdit* valueEdit = qobject_cast<QLineEdit*>(cellWidget(row,
eValue));
283 QPushButton* editButton = qobject_cast<QPushButton*>(cellWidget(row,
eValue));
285 if ((valueEdit && valueEdit->isEnabled()) || item(row,
eValue))
289 QString valueStr = valueEdit ? valueEdit->text() : item(row,
eValue)->text();
293 variant.
setInt(valueStr.toInt());
297 variant.
setLong(valueStr.toLong());
301 if (valueStr.compare(
"true", Qt::CaseInsensitive) == 0 || valueStr ==
"1")
312 variant.
setFloat(valueStr.toFloat());
321 variant.
setString(valueStr.trimmed().toStdString());
326 else if (editButton && editButton->isEnabled())
328 QString jsonValue = editButton->property(
"JsonValue").toString();
330 if (jsonValue.isEmpty())
337 jsonObject->fromString(jsonValue.toUtf8().data());
341 SerializablePtr obj = jsonObject->deserializeIceObject();
342 result = VariantContainerBasePtr::dynamicCast(obj);
350 catch (std::exception& e)
353 <<
" could not be deserialized: " << e.what();
364 if (row >= rowCount())
366 throw LocalException(
"row index out of range: ") << row;
369 if (!item(row,
eKey))
374 return item(row,
eKey)->text();
380 if (row >= rowCount())
382 throw LocalException(
"row index out of range: ") << row;
385 QComboBox* CBvalueType = qobject_cast<QComboBox*>(cellWidget(row, 1));
392 QString type = getBaseNameFromHumanName(CBvalueType->currentText());
408 for (
int i = 0; i < rowCount(); i++)
419 throw LocalException(
"could not find key ") << key.toStdString();
428 if (row >= rowCount())
430 throw LocalException(
"row index out of range: ") << row;
433 QComboBox* cbOptional = qobject_cast<QComboBox*>(cellWidget(row,
eOptional));
434 return cbOptional->currentText() ==
"true";
441 int row = rowCount();
443 setItem(row,
eKey,
new QTableWidgetItem());
449 QComboBox* valueTypebox =
new QComboBox;
450 valueTypebox->setEditable(
true);
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)));
462 QComboBox* cbOptional;
463 cbOptional =
new QComboBox();
464 cbOptional->addItems(QString(
"true;false").
split(
";"));
465 cbOptional->setCurrentIndex(1);
466 setCellWidget(row,
eOptional, cbOptional);
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");
475 connect(deleteButton, SIGNAL(clicked()),
this, SLOT(
deleteRow()));
482 QString variantIdStr,
488 item(row,
eKey)->setText(key);
490 QComboBox* valueTypeBox = qobject_cast<QComboBox*>(cellWidget(row,
eType));
492 valueTypeBox->setEditText(getHumanNameFromBaseName(variantIdStr));
494 QComboBox* optionalBox = qobject_cast<QComboBox*>(cellWidget(row,
eOptional));
498 optionalBox->setCurrentIndex(0);
502 optionalBox->setCurrentIndex(1);
505 if (!value.isEmpty())
516 QLineEdit* valueEdit =
new QLineEdit;
520 valueEdit->setEnabled(
false);
523 setCellWidget(row,
eValue, valueEdit);
527 if (value.at(0) ==
'\"')
532 if (value.at(value.length() - 1) ==
'\"')
534 value.remove(value.length() - 1, 1);
537 value = value.replace(
"\\\"",
"\"").replace(
"\\\\",
"\\");
540 valueEdit->setText(value);
554 QComboBox* typeBox = qobject_cast<QComboBox*>(cellWidget(row,
eType));
556 QString typeString = getBaseNameFromHumanName(typeBox->currentText());
557 QWidget* oldWidget = qobject_cast<QWidget*>(cellWidget(row,
eValue));
564 QPushButton* editValueButton =
new QPushButton(
"Edit");
568 editValueButton->setEnabled(
false);
571 setCellWidget(row,
eValue, editValueButton);
575 if (jsonValue.isEmpty())
582 Ice::ValueFactoryPtr factory =
583 communicator->getValueFactoryManager()->find(variantContainerType->typeId);
587 Ice::ValuePtr objectPtr = factory->create(variantContainerType->typeId);
589 VariantDataPtr var = VariantDataPtr::dynamicCast(objectPtr);
595 Ice::ValueFactoryPtr subfactory = communicator->getValueFactoryManager()->find(
596 variantContainerType->subType->typeId);
601 subfactory = IceInternal::factoryTable->getValueFactory(
602 variantContainerType->subType->typeId);
607 Ice::ValuePtr subObj =
608 subfactory->create(variantContainerType->subType->typeId);
609 VariantDataPtr var = VariantDataPtr::dynamicCast(subObj);
616 SingleTypeVariantListPtr::dynamicCast(objectPtr);
620 list->addVariant(
Variant(var));
627 map->addVariant(
"mykey",
Variant(var));
636 jsonObject->serializeIceObject(SerializablePtr::dynamicCast(objectPtr));
639 editValueButton->setProperty(
"JsonValue",
640 QString::fromStdString(jsonObject->asString(
true)));
644 editValueButton->setProperty(
"JsonValue", jsonValue);
652 editValueButton->setEnabled(
false);
659 QWidget* wid = qobject_cast<QWidget*>(sender());
666 int row = rowAt(wid->pos().y());
668 QWidget* valueWidget = cellWidget(row,
eValue);
670 QComboBox* typeBox = qobject_cast<QComboBox*>(cellWidget(row,
eType));
671 std::string typeStr = getBaseNameFromHumanName(typeBox->currentText()).toStdString();
678 QLineEdit* valueLineEdit = qobject_cast<QLineEdit*>(valueWidget);
682 valueLineEdit =
new QLineEdit;
683 setCellWidget(row,
eValue, valueLineEdit);
688 valueLineEdit->setEnabled(
false);
693 valueLineEdit->setValidator(NULL);
697 valueLineEdit->setValidator(
new QIntValidator(
this));
701 QRegExp rx(
"((1|0)|(true|false))");
702 QValidator* validator =
new QRegExpValidator(rx,
this);
703 valueLineEdit->setValidator(validator);
707 valueLineEdit->setValidator(
new QDoubleValidator(
this));
710 QString value = valueLineEdit->text();
713 if (valueLineEdit->validator() &&
714 valueLineEdit->validator()->validate(value, pos) != QValidator::Acceptable)
716 valueLineEdit->setText(
"");
729 QWidget* wid = qobject_cast<QWidget*>(sender());
730 QModelIndex mIndex = indexAt(wid->pos());
741 connectUserEditSlots();
753 QWidget* valueWidget = cellWidget(row,
eValue);
754 QWidget* valueLineEdit = qobject_cast<QWidget*>(valueWidget);
758 valueLineEdit->setEnabled(
false);
763 QWidget* valueWidget = cellWidget(row,
eValue);
764 QWidget* valueLineEdit = qobject_cast<QWidget*>(valueWidget);
768 valueLineEdit->setEnabled(
true);
772 else if (column ==
eKey)
774 auto keyitem = item(row,
eKey);
778 if ((keyBlackList.find(keyitem->text()) != keyBlackList.end() ||
779 findItems(keyitem->text(), Qt::MatchExactly).size() > 1))
781 keyitem->setText(item(row,
eKey)->text() +
"_2");
783 <<
"Keys must be unique (input and local parameters share the same key pool)";
788 if (row >= rowCount() - 1 && item(rowCount() - 1, 0) &&
789 !item(rowCount() - 1, 0)->text().isEmpty())
798 for (
int row = 0; row < rowCount(); row++)
800 QComboBox* valueTypeBox = qobject_cast<QComboBox*>(cellWidget(row,
eType));
801 addVariantTypesToComboBox(valueTypeBox);
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());
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);
824 connect(buttonBox, SIGNAL(accepted()), &editDefaultDialog, SLOT(accept()));
825 connect(buttonBox, SIGNAL(rejected()), &editDefaultDialog, SLOT(reject()));
827 if (editDefaultDialog.exec() == QDialog::Accepted)
829 sender()->setProperty(
"JsonValue", dialogTextEdit->toPlainText());
834StateParameterEditor::connectUserEditSlots()
837 SIGNAL(cellEntered(
int,
int)),
840 Qt::UniqueConnection);
842 SIGNAL(cellPressed(
int,
int)),
845 Qt::UniqueConnection);
847 SIGNAL(cellChanged(
int,
int)),
850 Qt::UniqueConnection);
854StateParameterEditor::addVariantTypesToComboBox(QComboBox* combo)
867 QString typeName = tr(pair.second.c_str());
870 if (typeName.contains(
"Invalid"))
875 list.append(getHumanNameFromBaseName(typeName));
882 std::vector<VariantContainerType> containers;
886 for (VariantContainerType
c : containers)
890 QString typeName = tr(it.second.c_str());
893 if (typeName.contains(
"Invalid"))
899 typeName = QString::fromStdString(typeStr);
900 list.append(getHumanNameFromBaseName(typeName));
908 qSort(list.begin(), list.end(), compareVariantNames);
909 combo->addItems(list);
913StateParameterEditor::getHumanNameFromBaseName(QString variantBaseTypeName)
const
917 return variantBaseTypeName;
920 std::string humanName =
921 variantInfo->getNestedHumanNameFromBaseName(variantBaseTypeName.toUtf8().data());
923 if (humanName.empty())
925 return variantBaseTypeName;
928 return QString::fromUtf8(humanName.c_str());
932StateParameterEditor::getBaseNameFromHumanName(QString humanName)
const
939 std::string variantBaseTypeName =
940 variantInfo->getNestedBaseNameFromHumanName(humanName.toUtf8().data());
942 if (variantBaseTypeName.empty())
947 return QString::fromUtf8(variantBaseTypeName.c_str());
951StateParameterEditor::compareVariantNames(
const QString& a,
const QString& b)
956 pa =
a.contains(
"(");
957 pb = b.contains(
"(");
965 pa =
a.contains(
":");
966 pb = b.contains(
":");
974 pa =
a.count() > 0 &&
a[0].isLower();
975 pb = b.count() > 0 && b[0].isLower();
982 return a.compare(b) < 0;
988 return defaultValueState;
994 defaultValueState = value;
1000 setHorizontalHeaderLabels(QString(
"Key;Type;Optional;Def;Value;Del").
split(
";"));
1001 setColumnWidth(
eKey, 180);
1002 setColumnWidth(
eType, 225);
1005 setColumnWidth(
eValue, 200);
1011 const StateParameterMap& map,
1012 const std::map<QString, std::pair<QString, QString>>& jsonStringMap)
1018StateParameterEditor::__buildFromMap(
1019 const StateParameterMap& map,
1020 const std::map<QString, std::pair<QString, QString>>& jsonStringMap)
1023 QWidget* tempW =
new QLabel(
"mylabel",
this);
1024 tempW->deleteLater();
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();
1032 for (; it != map.end(); it++)
1034 StateParameterIceBasePtr p = it->second;
1039 if (p->defaultValue)
1041 json->serializeIceObject(p->defaultValue);
1042 typeStr = QString::fromStdString(
1049 jsonStr = QString::fromUtf8(
1050 json->getElement(
"variant")->getElement(
"value")->toString().c_str());
1054 jsonStr = QString::fromUtf8(json->asString(
true).c_str());
1059 else if (jsonStringMap.find(QString::fromStdString(it->first)) != jsonStringMap.end())
1061 typeStr = jsonStringMap.at(QString::fromStdString(it->first)).first;
1062 jsonStr = jsonStringMap.at(QString::fromStdString(it->first)).second;
1065 addParameterRow(QString::fromStdString(it->first), typeStr, jsonStr, p->optionalParam);
1069 connectUserEditSlots();
1074StateParameterEditor::LineEditDelegate::createEditor(QWidget* parent,
1075 const QStyleOptionViewItem&
option,
1076 const QModelIndex&
index)
const
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));
The JSONObject class is used to represent and (de)serialize JSON objects.
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 > >())
QString getKey(int row) const
void refreshVariantTypes()
void setKeyBlackList(const QSet< QString > &keyBlackList)
int getRow(const QString &key) const
void editDefaultButtonClicked()
StateParameterEditor(QWidget *parent=0, const StateParameterMap ¶ms=StateParameterMap())
void buildRequested(const StateParameterMap &map, const std::map< QString, std::pair< QString, QString > > &jsonStringMap)
VariantContainerBasePtr getVariantContainer(int row) const
bool getIsOptional(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 getType(int row) const
QString getJson(QString key) const
QSet< QString > getKeys() 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.
static const std::map< VariantTypeId, std::string > & getTypes()
Returns the mapping of currently registered types.
void setLong(long n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
void setFloat(float f, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to f.
void setInt(int n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
void setString(const std::string &s, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to s.
void setBool(bool b, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to b.
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
void setDouble(double d, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to d.
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
const VariantTypeId String
bool IsBasicType(VariantTypeId id)
const VariantTypeId Double
const VariantContainerType Map
const VariantTypeId Float
const VariantContainerType List
double a(double t, double a0, double j)
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)
IceInternal::Handle< StringValueMap > StringValueMapPtr
IceInternal::Handle< JSONObject > JSONObjectPtr