schema_editor/comdel/display/attribute_dialog.cpp

269 lines
9.0 KiB
C++

//
// Created by bbr on 18. 04. 2022..
//
#include "attribute_dialog.h"
#include "mainwindow.h"
#include "application.h"
namespace display {
void AttributeDialog::onUpdate() {
auto oldValue = attributeValue->value;
attributeValue->value = value;
domain::ComdelValidator validator(domain::getSupportedValidators());
domain::ValidationContext context;
for (auto &addressSpace: Application::instance()->getLibrary()->getAddressSpaces()) {
context.addressSpaces.insert(std::make_pair(addressSpace.getName(), addressSpace));
}
auto validationErrors = validator.validateAttribute(attributeValue, context);
if (validationErrors.empty()) {
accept();
} else {
bool canAccept = true;
std::vector<domain::ValidationError> errors;
std::vector<domain::ValidationError> warnings;
for (auto &err: validationErrors) {
if (err.type == domain::Action::ERROR) {
errors.push_back(err);
} else {
warnings.push_back(err);
}
}
if (!errors.empty()) {
canAccept = false;
auto errorDialog = new ErrorDialog(errors);
errorDialog->exec();
}
for (auto &warning: warnings) {
auto warningDialog = new WarningDialog(warning);
int response = warningDialog->exec();
if (response == QDialog::Rejected) {
canAccept = false;
}
}
if (canAccept) {
accept();
} else {
attributeValue->value = oldValue;
}
}
}
AttributeDialog::AttributeDialog(domain::InstanceAttribute *attribute, bool updating) {
setAttribute(Qt::WA_DeleteOnClose);
attributeValue = attribute;
auto actionType = updating ? "Izmjeni " : "Postavi ";
this->setWindowTitle(QString::fromStdString(actionType + attribute->attribute.getName()));
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
auto popup = *attribute->attribute.getPopup();
layout->addWidget(new QLabel(popup.getTitle().c_str()));
layout->addWidget(new QLabel(popup.getText().c_str()));
auto type = attribute->attribute.getDefault().getType();
value = attribute->value;
if (attribute->attribute.getPopup()->isEnumerated()) {
auto *combo = new QComboBox(this);
auto enumeration = attribute->attribute.getPopup()->getEnumeration();
for (auto entry: enumeration) {
combo->addItem(QString::fromStdString(entry.getName()));
}
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&AttributeDialog::onEnumerationChanged);
layout->addWidget(combo);
for (int i = 0; i < enumeration.size(); i++) {
if (attributeValue->value.equals(enumeration[i].getValue())) {
combo->setCurrentIndex(i);
break;
}
}
} else if (!(type == domain::Value::ValueType::WIRE_REFERENCE || type == domain::Value::ValueType::BOOL)) {
auto edit = new QLineEdit(this);
connect(edit, &QLineEdit::textChanged, this, &AttributeDialog::onTextChanged);
layout->addWidget(edit);
switch (attribute->attribute.getDefault().getType()) {
case domain::Value::ValueType::INT:
edit->setValidator(new QIntValidator(-10000000, 10000000, edit));
edit->insert(std::to_string(attribute->value.asInt()).c_str());
break;
case domain::Value::ValueType::STRING:
edit->insert(attribute->value.asString().c_str());
break;
default:
throw std::exception();
}
} else if (type == domain::Value::ValueType::BOOL) {
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 (attribute->value.asBool()) {
isTrue->setChecked(true);
} else {
isFalse->setChecked(true);
}
radioLayout->addWidget(isTrue);
radioLayout->addWidget(isFalse);
layout->addWidget(group);
}
auto button = new QPushButton(updating ? "Ažuriraj" : "Postavi");
connect(button, &QPushButton::clicked, this, &AttributeDialog::onUpdate);
layout->addWidget(button);
}
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();
}
void MemoryDialog::onUpdate() {
attributeValue->value = value;
accept();
}
MemoryDialog::MemoryDialog(domain::InstanceAttribute *attribute,
std::vector<std::shared_ptr<domain::ComponentInstance>> instances, bool updating) {
memoryInstances = std::vector<std::string>();
setAttribute(Qt::WA_DeleteOnClose);
attributeValue = attribute;
auto actionType = updating ? "Izmjeni memoriju" : "Postavi memoriju";
this->setWindowTitle(QString::fromStdString(actionType));
for (auto &instance: instances) {
if (instance->component.getType() == domain::Component::MEMORY) {
memoryInstances.push_back(instance->name);
}
}
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
auto popup = *attribute->attribute.getPopup();
layout->addWidget(new QLabel(popup.getTitle().c_str()));
layout->addWidget(new QLabel(popup.getText().c_str()));
value = attribute->value;
auto *combo = new QComboBox(this);
for (auto &entry: memoryInstances) {
combo->addItem(QString::fromStdString(entry));
}
combo->addItem("null");
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MemoryDialog::onMemoryChanged);
layout->addWidget(combo);
combo->setCurrentIndex(memoryInstances.size());
for (int i = 0; i < memoryInstances.size(); i++) {
if (attributeValue->value.asMemoryReference().has_value() &&
attributeValue->value.asMemoryReference() == memoryInstances[i]) {
combo->setCurrentIndex(i);
break;
}
}
auto button = new QPushButton(updating ? "Ažuriraj" : "Postavi");
connect(button, &QPushButton::clicked, this, &MemoryDialog::onUpdate);
layout->addWidget(button);
}
void MemoryDialog::onMemoryChanged(int index) {
if (index == memoryInstances.size()) {
value = domain::Value::fromMemoryReference(std::nullopt);
} else {
value = domain::Value::fromMemoryReference(memoryInstances[index]);
}
}
ErrorDialog::ErrorDialog(std::vector<domain::ValidationError> errors) {
setAttribute(Qt::WA_DeleteOnClose);
this->setWindowTitle("Greške");
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
for (auto &err: errors) {
layout->addWidget(new QLabel(QString::fromStdString(err.message), this));
}
}
WarningDialog::WarningDialog(domain::ValidationError error) {
setAttribute(Qt::WA_DeleteOnClose);
this->setWindowTitle("Upozorenje");
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
layout->addWidget(new QLabel(QString::fromStdString(error.message), this));
auto buttonLayout = new QHBoxLayout(this);
auto okButton = new QPushButton("U redu", this);
auto cancelButton = new QPushButton("Odustani", this);
connect(okButton, &QPushButton::clicked, [this]() { accept(); });
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
buttonLayout->addWidget(okButton);
buttonLayout->addWidget(cancelButton);
layout->addItem(buttonLayout);
}
}