180 lines
5.9 KiB
C++
180 lines
5.9 KiB
C++
|
#include "attribute_dialog.h"
|
||
|
#include "mainwindow.h"
|
||
|
|
||
|
#include "application.h"
|
||
|
#include "error_dialog.h"
|
||
|
#include "warning_dialog.h"
|
||
|
|
||
|
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<domain::ValidationError> 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::exception();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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<int>::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("da", group);
|
||
|
connect(isTrue, &QRadioButton::clicked, [this]() {
|
||
|
this->value = domain::Value::fromBool(true);
|
||
|
});
|
||
|
auto isFalse = new QRadioButton("ne", 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<domain::ValidationError> 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;
|
||
|
}
|
||
|
|
||
|
}
|