#include "attribute_dialog.h" #include "mainwindow.h" #include "application.h" #include "error_dialog.h" #include "warning_dialog.h" #include "message_source.h" #include namespace display { long long int parseInt(std::string expression) { try { if (expression.size() > 2) { if (expression.substr(0, 2) == "0x") { return std::stoll(expression, nullptr, 16); } else if (expression.substr(0, 2) == "0b") { return std::stoll(expression, nullptr, 2); } else { return std::stoll(expression, nullptr, 10); } } else { return std::stoll(expression, nullptr, 10); } } catch (std::exception &e) { return 0; } } AttributeDialog::AttributeDialog(std::string title, std::string action, domain::InstanceAttribute *attribute): GenericDialog(title, action), attributeValue(attribute), value(attribute->value), popup(*attribute->attribute.getPopup()) { auto *contentLayout = new QVBoxLayout(); content->setLayout(contentLayout); contentLayout->addWidget(new QLabel(popup.getTitle().c_str())); contentLayout->addWidget(new QLabel(popup.getText().c_str())); auto type = attribute->value.getType(); if(popup.isEnumerated()) { contentLayout->addWidget(setupEnumeration()); } else if(type == domain::Value::INT || type == domain::Value::STRING) { contentLayout->addWidget(setupLineEdit(type)); } else if(type == domain::Value::BOOL) { contentLayout->addWidget(setupBool()); } } bool AttributeDialog::onUpdate() { auto validationErrors = validate(); if (validationErrors.empty()) { attributeValue->value = value; return true; } std::vector errors, warnings; for (auto &err: validationErrors) { if (err.type == domain::Action::ERROR) { errors.push_back(err); } else { warnings.push_back(err); } } if (!errors.empty()) { auto errorDialog = new ErrorDialog(errors); errorDialog->exec(); return false; } bool canAccept = true; for (auto &warning: warnings) { auto warningDialog = new WarningDialog(warning); int response = warningDialog->exec(); if (response == QDialog::Rejected) { canAccept = false; } } if(canAccept) { attributeValue->value = value; } return canAccept; } void AttributeDialog::onTextChanged(const QString &string) { switch (value.getType()) { case domain::Value::STRING: value.setString(string.toStdString()); break; case domain::Value::INT: value = domain::Value::fromInt(parseInt(string.toStdString())); break; default: throw std::runtime_error("invalid value type in text change"); } } void AttributeDialog::onEnumerationChanged(int index) { value = attributeValue->attribute.getPopup()->getEnumeration()[index].getValue(); } QComboBox *AttributeDialog::setupEnumeration() { auto *combo = new QComboBox(this); auto enumeration = popup.getEnumeration(); for (auto entry: enumeration) { combo->addItem(QString::fromStdString(entry.getName())); } connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, &AttributeDialog::onEnumerationChanged); for (int i = 0; i < enumeration.size(); i++) { if (attributeValue->value.equals(enumeration[i].getValue())) { combo->setCurrentIndex(i); break; } } return combo; } QLineEdit *AttributeDialog::setupLineEdit(domain::Value::ValueType type) { auto edit = new QLineEdit(this); connect(edit, &QLineEdit::textChanged, this, &AttributeDialog::onTextChanged); switch (type) { case domain::Value::ValueType::INT: edit->setValidator(new QIntValidator(-10000000, 10000000, edit)); edit->insert(std::to_string(value.asInt()).c_str()); break; case domain::Value::ValueType::STRING: edit->insert(value.asString().c_str()); break; } return edit; } QGroupBox *AttributeDialog::setupBool() { auto *group = new QGroupBox(this); auto *radioLayout = new QHBoxLayout(group); group->setLayout(radioLayout); auto isTrue = new QRadioButton(QMESSAGE("msg_boolean_true"), group); connect(isTrue, &QRadioButton::clicked, [this]() { this->value = domain::Value::fromBool(true); }); auto isFalse = new QRadioButton(QMESSAGE("msg_boolean_false"), group); connect(isFalse, &QRadioButton::clicked, [this]() { this->value = domain::Value::fromBool(false); }); if (value.asBool()) { isTrue->setChecked(true); } else { isFalse->setChecked(true); } radioLayout->addWidget(isTrue); radioLayout->addWidget(isFalse); return group; } std::vector AttributeDialog::validate() { domain::ComdelValidator validator(domain::getSupportedValidators()); auto currentValue = attributeValue->value; attributeValue->value = value; domain::ValidationContext context; for (auto &addressSpace: Application::instance()->getLibrary()->getAddressSpaces()) { context.addressSpaces.insert(std::make_pair(addressSpace.getName(), addressSpace)); } auto errors = validator.validateAttribute(attributeValue, context); attributeValue->value = currentValue; return errors; } }