Refactored validation
This commit is contained in:
parent
fe4a39803c
commit
7be3a1b5bc
|
@ -37,5 +37,5 @@ add_executable(SchemeEditor
|
|||
comdel/parser/comdel_lexer.cpp
|
||||
main.cpp
|
||||
mainwindow.ui
|
||||
comdel/domain/comdel_validator.cpp comdel/domain/comdel_validator.h comdel/display/attribute_dialog.cpp comdel/display/attribute_dialog.h comdel/display/name_dialog.cpp comdel/display/name_dialog.h comdel/domain/comdel_generator.cpp comdel/domain/comdel_generator.h comdel/display/library_list.cpp comdel/display/library_list.h application.cpp application.h comdel/display/single_automatic_dialog.cpp comdel/display/single_automatic_dialog.h comdel/parser/color.h)
|
||||
comdel/domain/comdel_validator.cpp comdel/domain/comdel_validator.h comdel/display/dialog/attribute_dialog.cpp comdel/display/dialog/attribute_dialog.h comdel/display/dialog/name_dialog.cpp comdel/display/dialog/name_dialog.h comdel/domain/comdel_generator.cpp comdel/domain/comdel_generator.h comdel/display/library_list.cpp comdel/display/library_list.h application.cpp application.h comdel/display/dialog/single_automatic_dialog.cpp comdel/display/dialog/single_automatic_dialog.h comdel/parser/color.h comdel/display/dialog/generic_dialog.cpp comdel/display/dialog/generic_dialog.h comdel/display/dialog/warning_dialog.cpp comdel/display/dialog/warning_dialog.h comdel/display/dialog/error_dialog.cpp comdel/display/dialog/error_dialog.h comdel/display/dialog/memory_dialog.cpp comdel/display/dialog/memory_dialog.h comdel/display/dialog/success_dialog.cpp comdel/display/dialog/success_dialog.h)
|
||||
target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
|
|
|
@ -1,283 +0,0 @@
|
|||
//
|
||||
// Created by bbr on 18. 04. 2022..
|
||||
//
|
||||
|
||||
#include "attribute_dialog.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "application.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
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 buttonLayout = new QHBoxLayout(this);
|
||||
|
||||
auto okButton = new QPushButton(updating ? "Ažuriraj" : "Postavi", this);
|
||||
auto cancelButton = new QPushButton("Odustani", this);
|
||||
|
||||
connect(okButton, &QPushButton::clicked, this, &AttributeDialog::onUpdate);
|
||||
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
|
||||
|
||||
buttonLayout->addWidget(okButton);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
layout->addLayout(buttonLayout);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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 buttonLayout = new QHBoxLayout(this);
|
||||
|
||||
auto okButton = new QPushButton(updating ? "Ažuriraj" : "Postavi");
|
||||
auto cancelButton = new QPushButton("Odustani", this);
|
||||
|
||||
connect(okButton, &QPushButton::clicked, this, &MemoryDialog::onUpdate);
|
||||
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
|
||||
|
||||
buttonLayout->addWidget(okButton);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
layout->addLayout(buttonLayout);
|
||||
}
|
||||
|
||||
void MemoryDialog::onUpdate() {
|
||||
attributeValue->value = value;
|
||||
accept();
|
||||
}
|
||||
|
||||
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->addLayout(buttonLayout);
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
#ifndef ATTRIBUTE_DIALOG_H
|
||||
#define ATTRIBUTE_DIALOG_H
|
||||
|
||||
#include <QIntValidator>
|
||||
#include <QPushButton>
|
||||
#include <QComboBox>
|
||||
#include <QGroupBox>
|
||||
#include <QRadioButton>
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <utility>
|
||||
#include <comdel/domain/instance_attribute.h>
|
||||
|
||||
#include <comdel/domain/value.h>
|
||||
#include "comdel/domain/comdel_validator.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class AttributeDialog : public QDialog {
|
||||
domain::Value value;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
domain::InstanceAttribute *attributeValue;
|
||||
|
||||
public:
|
||||
AttributeDialog(domain::InstanceAttribute *attribute, bool updating = true);
|
||||
|
||||
public slots:
|
||||
|
||||
void onTextChanged(const QString &string);
|
||||
|
||||
void onEnumerationChanged(int index);
|
||||
|
||||
void onUpdate();
|
||||
|
||||
};
|
||||
|
||||
|
||||
class MemoryDialog : public QDialog {
|
||||
domain::Value value;
|
||||
|
||||
domain::InstanceAttribute *attributeValue;
|
||||
std::vector<std::string> memoryInstances;
|
||||
|
||||
public:
|
||||
MemoryDialog(domain::InstanceAttribute *attribute,
|
||||
std::vector<std::shared_ptr<domain::ComponentInstance>> instances, bool updating = true);
|
||||
|
||||
public slots:
|
||||
|
||||
void onMemoryChanged(int index);
|
||||
|
||||
void onUpdate();
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ErrorDialog : public QDialog {
|
||||
public:
|
||||
ErrorDialog(std::vector<domain::ValidationError> errors);
|
||||
};
|
||||
|
||||
class WarningDialog : public QDialog {
|
||||
public:
|
||||
WarningDialog(domain::ValidationError error);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //ATTRIBUTE_DIALOG_H
|
|
@ -1,9 +1,10 @@
|
|||
#include "component_display.h"
|
||||
#include "attribute_dialog.h"
|
||||
#include "name_dialog.h"
|
||||
#include "comdel/display/dialog/attribute_dialog.h"
|
||||
#include "comdel/display/dialog/name_dialog.h"
|
||||
#include "mainwindow.h"
|
||||
#include "application.h"
|
||||
#include "single_automatic_dialog.h"
|
||||
#include "comdel/display/dialog/single_automatic_dialog.h"
|
||||
#include "comdel/display/dialog/memory_dialog.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QLine>
|
||||
|
@ -45,14 +46,14 @@ namespace display {
|
|||
|
||||
if(attr->value.getType() == domain::Value::MEMORY_REFERENCE) {
|
||||
menu.addAction("Izmjeni memoriju", [attr]() {
|
||||
auto dialog = new MemoryDialog(attr,
|
||||
auto dialog = new MemoryDialog("Izmjeni memoriju", "Izmjeni", attr,
|
||||
Application::instance()->getSchema()->componentInstances);
|
||||
dialog->exec();
|
||||
});
|
||||
} else {
|
||||
auto action = menu.addAction(QString::fromStdString("Izmjeni '" + attr->name + "'"),
|
||||
[attr]() {
|
||||
auto dialog = new AttributeDialog(attr);
|
||||
auto dialog = new AttributeDialog("Izmjeni " + attr->name, "Izmjeni", attr);
|
||||
dialog->exec();
|
||||
});
|
||||
action->setEnabled(enabled);
|
||||
|
@ -83,7 +84,7 @@ namespace display {
|
|||
auto connectionName = directConnection->attributes[0].value.stringify() + "-" +
|
||||
directConnection->attributes[1].value.stringify();
|
||||
update->addAction(QString::fromStdString("Izmjeni " + connectionName), [directConnection]() {
|
||||
auto dialog = new SingleAutomaticDialog(directConnection->attributes);
|
||||
auto dialog = new SingleAutomaticDialog("Izmjeni sabirnicu", "Izmjeni", directConnection->attributes);
|
||||
dialog->exec();
|
||||
});
|
||||
remove->addAction(QString::fromStdString("Ukloni " + connectionName),
|
||||
|
@ -109,7 +110,7 @@ namespace display {
|
|||
for (int i = 0; i < pinConnection->attributes.size(); i++) {
|
||||
auto *attr = &pinConnection->attributes[i];
|
||||
menu.addAction(QString::fromStdString("Izmjeni '" + attr->name + "'"),[attr]() {
|
||||
auto dialog = new AttributeDialog(attr);
|
||||
auto dialog = new AttributeDialog("Izmjeni '" + attr->name + "'", "Izmjeni", attr);
|
||||
dialog->exec();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef ATTRIBUTE_DIALOG_H
|
||||
#define ATTRIBUTE_DIALOG_H
|
||||
|
||||
#include <QIntValidator>
|
||||
#include <QPushButton>
|
||||
#include <QComboBox>
|
||||
#include <QGroupBox>
|
||||
#include <QRadioButton>
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <utility>
|
||||
#include "comdel/domain/instance_attribute.h"
|
||||
|
||||
#include "comdel/domain/value.h"
|
||||
#include "comdel/domain/comdel_validator.h"
|
||||
#include "generic_dialog.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class AttributeDialog : public GenericDialog {
|
||||
public:
|
||||
AttributeDialog(std::string title, std::string action, domain::InstanceAttribute *attribute);
|
||||
|
||||
public slots:
|
||||
void onTextChanged(const QString &string);
|
||||
void onEnumerationChanged(int index);
|
||||
|
||||
protected:
|
||||
bool onUpdate() override;
|
||||
|
||||
private:
|
||||
QComboBox *setupEnumeration();
|
||||
QLineEdit *setupLineEdit(domain::Value::ValueType type);
|
||||
QGroupBox *setupBool();
|
||||
|
||||
std::vector<domain::ValidationError> validate();
|
||||
|
||||
domain::Value value;
|
||||
domain::InstanceAttribute *attributeValue;
|
||||
domain::Popup popup;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //ATTRIBUTE_DIALOG_H
|
|
@ -0,0 +1,34 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPlainTextEdit>
|
||||
#include "error_dialog.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
ErrorDialog::ErrorDialog(std::vector<domain::ValidationError> errors)
|
||||
: GenericDialog("Greške", "") {
|
||||
|
||||
auto contentLayout = new QVBoxLayout();
|
||||
content->setLayout(contentLayout);
|
||||
|
||||
for (auto &err: errors) {
|
||||
contentLayout->addWidget(new QLabel(QString::fromStdString(err.message), this));
|
||||
}
|
||||
}
|
||||
|
||||
ErrorDialog::ErrorDialog(std::ostringstream& errorStream)
|
||||
: GenericDialog("Greške", "") {
|
||||
|
||||
auto contentLayout = new QVBoxLayout();
|
||||
content->setLayout(contentLayout);
|
||||
|
||||
setMinimumWidth(1000);
|
||||
|
||||
auto log = new QPlainTextEdit();
|
||||
log->setFont(QFont("Courier"));
|
||||
log->appendPlainText(QString::fromStdString(errorStream.str()));
|
||||
log->setReadOnly(true);
|
||||
contentLayout->addWidget(log);
|
||||
}
|
||||
|
||||
} // display
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef SCHEMEEDITOR_ERROR_DIALOG_H
|
||||
#define SCHEMEEDITOR_ERROR_DIALOG_H
|
||||
|
||||
#include "generic_dialog.h"
|
||||
#include "comdel/domain/comdel_validator.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace display {
|
||||
|
||||
class ErrorDialog : public GenericDialog {
|
||||
public:
|
||||
ErrorDialog(std::vector<domain::ValidationError> errors);
|
||||
ErrorDialog(std::ostringstream& errorStream);
|
||||
|
||||
protected:
|
||||
bool onUpdate() override { return true; }
|
||||
};
|
||||
|
||||
} // display
|
||||
|
||||
#endif //SCHEMEEDITOR_ERROR_DIALOG_H
|
|
@ -0,0 +1,29 @@
|
|||
#include <QVBoxLayout>
|
||||
#include "generic_dialog.h"
|
||||
|
||||
display::GenericDialog::GenericDialog(std::string title, std::string action) {
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowTitle(QString::fromStdString(title));
|
||||
|
||||
setLayout(new QVBoxLayout());
|
||||
content = new QWidget(this);
|
||||
layout()->addWidget(content);
|
||||
|
||||
auto actionWidget = new QWidget(this);
|
||||
auto actionBar = new QHBoxLayout(actionWidget);
|
||||
layout()->addWidget(actionWidget);
|
||||
|
||||
// if action isn't defined only close button is offered
|
||||
if(!action.empty()) {
|
||||
okButton = new QPushButton(QString::fromStdString(action), this);
|
||||
connect(okButton, &QPushButton::clicked, this, [this](){if(this->onUpdate()) this->accept();});
|
||||
actionBar->addWidget(okButton);
|
||||
}
|
||||
cancelButton = new QPushButton("Odustani", this);
|
||||
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
|
||||
actionBar->addWidget(cancelButton);
|
||||
}
|
||||
|
||||
void display::GenericDialog::setOkButtonDisabled(bool disabled) {
|
||||
okButton->setDisabled(disabled);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef SCHEMEEDITOR_GENERIC_DIALOG_H
|
||||
#define SCHEMEEDITOR_GENERIC_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QWidget>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace display {
|
||||
|
||||
class GenericDialog: public QDialog {
|
||||
public:
|
||||
|
||||
GenericDialog(std::string title, std::string action = "Ažuriraj");
|
||||
|
||||
protected:
|
||||
void setOkButtonDisabled(bool disabled);
|
||||
virtual bool onUpdate() = 0;
|
||||
|
||||
private:
|
||||
QPushButton *okButton;
|
||||
QPushButton *cancelButton;
|
||||
|
||||
protected:
|
||||
QWidget *content;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //SCHEMEEDITOR_GENERIC_DIALOG_H
|
|
@ -0,0 +1,59 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include "memory_dialog.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
|
||||
MemoryDialog::MemoryDialog(std::string title, std::string action, domain::InstanceAttribute *attribute,
|
||||
std::vector<std::shared_ptr<domain::ComponentInstance>> instances)
|
||||
: GenericDialog(title, action), value(attribute->value), attributeValue(attribute), popup(*attribute->attribute.getPopup()) {
|
||||
|
||||
for (auto &instance: instances) {
|
||||
if (instance->component.getType() == domain::Component::MEMORY) {
|
||||
memoryInstances.push_back(instance->name);
|
||||
}
|
||||
}
|
||||
|
||||
auto contentLayout = new QVBoxLayout(content);
|
||||
content->setLayout(contentLayout);
|
||||
|
||||
contentLayout->addWidget(new QLabel(popup.getTitle().c_str()));
|
||||
contentLayout->addWidget(new QLabel(popup.getText().c_str()));
|
||||
|
||||
contentLayout->addWidget(setupEnumeration());
|
||||
}
|
||||
|
||||
bool MemoryDialog::onUpdate() {
|
||||
attributeValue->value = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
QComboBox *MemoryDialog::setupEnumeration() {
|
||||
auto *combo = new QComboBox(this);
|
||||
|
||||
for (const auto& entry: memoryInstances) {
|
||||
combo->addItem(QString::fromStdString(entry));
|
||||
}
|
||||
combo->addItem("null");
|
||||
|
||||
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
if(index == memoryInstances.size()) {
|
||||
value = domain::Value::fromMemoryReference(std::nullopt);
|
||||
} else {
|
||||
value = domain::Value::fromMemoryReference(this->memoryInstances[index]);
|
||||
}
|
||||
});
|
||||
|
||||
combo->setCurrentIndex(memoryInstances.size());
|
||||
for (int i = 0; i < memoryInstances.size(); i++) {
|
||||
if (attributeValue->value.equals(domain::Value::fromMemoryReference(memoryInstances[i]))) {
|
||||
combo->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return combo;
|
||||
}
|
||||
|
||||
} // display
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef SCHEMEEDITOR_MEMORY_DIALOG_H
|
||||
#define SCHEMEEDITOR_MEMORY_DIALOG_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include "generic_dialog.h"
|
||||
#include "comdel/domain/instance_attribute.h"
|
||||
#include "comdel/domain/instance.h"
|
||||
|
||||
|
||||
namespace display {
|
||||
|
||||
class MemoryDialog : public GenericDialog {
|
||||
public:
|
||||
MemoryDialog(std::string title, std::string action, domain::InstanceAttribute *attribute,
|
||||
std::vector<std::shared_ptr<domain::ComponentInstance>> instances);
|
||||
|
||||
protected:
|
||||
bool onUpdate() override;
|
||||
|
||||
private:
|
||||
QComboBox *setupEnumeration();
|
||||
|
||||
domain::Value value;
|
||||
domain::InstanceAttribute *attributeValue;
|
||||
std::vector<std::string> memoryInstances;
|
||||
|
||||
domain::Popup popup;
|
||||
};
|
||||
|
||||
|
||||
} // display
|
||||
|
||||
#endif //SCHEMEEDITOR_MEMORY_DIALOG_H
|
|
@ -0,0 +1,39 @@
|
|||
#include <set>
|
||||
#include "name_dialog.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
NameDialog::NameDialog(std::string currentName, std::set<std::string> &names)
|
||||
: GenericDialog("Izmjeni ime", "Izmjeni"), currentName(currentName), usedNames(names) {
|
||||
|
||||
usedNames.erase(currentName);
|
||||
|
||||
auto *contentLayout = new QVBoxLayout();
|
||||
contentLayout->addWidget(new QLabel("Izmjeni ime", this));
|
||||
|
||||
edit = new QLineEdit(this);
|
||||
edit->insert(currentName.c_str());
|
||||
connect(edit, &QLineEdit::textChanged, this, &NameDialog::onNameUpdate);
|
||||
contentLayout->addWidget(edit);
|
||||
|
||||
content->setLayout(contentLayout);
|
||||
}
|
||||
|
||||
void NameDialog::onNameUpdate(const QString &text) {
|
||||
if(usedNames.find(text.toStdString()) == usedNames.end()) {
|
||||
setOkButtonDisabled(false);
|
||||
} else {
|
||||
setOkButtonDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
std::string NameDialog::getName() {
|
||||
return currentName;
|
||||
}
|
||||
|
||||
bool NameDialog::onUpdate() {
|
||||
currentName = edit->text().toStdString();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,25 +9,29 @@
|
|||
|
||||
#include <set>
|
||||
|
||||
#include <comdel/domain/instance.h>
|
||||
#include "comdel/domain/instance.h"
|
||||
#include "generic_dialog.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class NameDialog : public QDialog {
|
||||
|
||||
std::set<std::string> usedNames;
|
||||
QLineEdit *edit = nullptr;
|
||||
std::string currentName;
|
||||
QPushButton *button;
|
||||
class NameDialog : public GenericDialog {
|
||||
|
||||
public:
|
||||
NameDialog(std::string currentName, std::set<std::string>& names);
|
||||
|
||||
std::string getName();
|
||||
|
||||
protected:
|
||||
bool onUpdate() override;
|
||||
|
||||
public slots:
|
||||
void onNameUpdate(const QString& text);
|
||||
void onNameChange();
|
||||
|
||||
private:
|
||||
std::set<std::string> usedNames;
|
||||
QLineEdit *edit = nullptr;
|
||||
std::string currentName;
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -1,7 +1,3 @@
|
|||
//
|
||||
// Created by bbr on 05.06.22..
|
||||
//
|
||||
|
||||
#include "single_automatic_dialog.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
|
@ -9,38 +5,23 @@
|
|||
#include <QPushButton>
|
||||
|
||||
namespace display {
|
||||
SingleAutomaticDialog::SingleAutomaticDialog(std::vector<domain::InstanceAttribute> &values, bool updating): attributes(values) {
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowTitle(QString::fromStdString(updating ? "Ažuriraj poveznicu" : "Postavi poveznicu"));
|
||||
|
||||
SingleAutomaticDialog::SingleAutomaticDialog(std::string title, std::string action,
|
||||
std::vector<domain::InstanceAttribute> &values)
|
||||
: GenericDialog(title, action), attributes(values) {
|
||||
firstValue = values[0].value;
|
||||
secondValue = values[1].value;
|
||||
|
||||
auto *parentLayout = new QVBoxLayout(this);
|
||||
auto *contentLayout = new QHBoxLayout(this);
|
||||
auto *firstLayout = new QVBoxLayout(this);
|
||||
auto *secondLayout = new QVBoxLayout(this);
|
||||
auto *contentLayout = new QHBoxLayout();
|
||||
auto *firstLayout = new QVBoxLayout();
|
||||
auto *secondLayout = new QVBoxLayout();
|
||||
|
||||
parentLayout->addLayout(contentLayout);
|
||||
content->setLayout(contentLayout);
|
||||
contentLayout->addLayout(firstLayout);
|
||||
contentLayout->addLayout(secondLayout);
|
||||
this->setLayout(parentLayout);
|
||||
|
||||
setupValues(firstLayout, values[0], &SingleAutomaticDialog::onFirstEnumerationChanged);
|
||||
setupValues(secondLayout, values[1], &SingleAutomaticDialog::onSecondEnumerationChanged);
|
||||
|
||||
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);
|
||||
|
||||
parentLayout->addLayout(buttonLayout);
|
||||
}
|
||||
|
||||
void SingleAutomaticDialog::setupValues(QVBoxLayout *layout, domain::InstanceAttribute &attribute, void (display::SingleAutomaticDialog::* handler)(int)) {
|
||||
|
@ -75,10 +56,10 @@ namespace display {
|
|||
secondValue = attributes[1].attribute.getPopup()->getEnumeration()[index].getValue();
|
||||
}
|
||||
|
||||
void SingleAutomaticDialog::onUpdate() {
|
||||
bool SingleAutomaticDialog::onUpdate() {
|
||||
attributes[0].value = firstValue;
|
||||
attributes[1].value = secondValue;
|
||||
accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // display
|
|
@ -1,7 +1,3 @@
|
|||
//
|
||||
// Created by bbr on 05.06.22..
|
||||
//
|
||||
|
||||
#ifndef SCHEMEEDITOR_SINGLE_AUTOMATIC_DIALOG_H
|
||||
#define SCHEMEEDITOR_SINGLE_AUTOMATIC_DIALOG_H
|
||||
|
||||
|
@ -10,24 +6,29 @@
|
|||
#include <QVBoxLayout>
|
||||
#include "comdel/domain/value.h"
|
||||
#include "comdel/domain/instance_attribute.h"
|
||||
#include "generic_dialog.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class SingleAutomaticDialog: public QDialog {
|
||||
class SingleAutomaticDialog: public GenericDialog {
|
||||
domain::Value firstValue;
|
||||
domain::Value secondValue;
|
||||
std::vector<domain::InstanceAttribute> &attributes;
|
||||
|
||||
public:
|
||||
explicit SingleAutomaticDialog(std::vector<domain::InstanceAttribute>& values, bool updating = true);
|
||||
explicit SingleAutomaticDialog(
|
||||
std::string title,
|
||||
std::string action,
|
||||
std::vector<domain::InstanceAttribute>& values);
|
||||
|
||||
protected:
|
||||
bool onUpdate() override;
|
||||
void setupValues(QVBoxLayout *layout, domain::InstanceAttribute &attribute, void (display::SingleAutomaticDialog::* handler)(int));
|
||||
|
||||
public slots:
|
||||
|
||||
void onFirstEnumerationChanged(int index);
|
||||
void onSecondEnumerationChanged(int index);
|
||||
void onUpdate();
|
||||
};
|
||||
|
||||
} // display
|
|
@ -0,0 +1,17 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include "success_dialog.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
SuccessDialog::SuccessDialog(std::string message, std::string action) {
|
||||
setLayout(new QVBoxLayout());
|
||||
layout()->addWidget(new QLabel(QString::fromStdString(message)));
|
||||
|
||||
auto button = new QPushButton(QString::fromStdString(action));
|
||||
connect(button, &QPushButton::clicked, [this]() {accept();});
|
||||
layout()->addWidget(button);
|
||||
}
|
||||
|
||||
} // display
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Created by bbr on 14.06.22..
|
||||
//
|
||||
|
||||
#ifndef SCHEMEEDITOR_SUCCESS_DIALOG_H
|
||||
#define SCHEMEEDITOR_SUCCESS_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace display {
|
||||
|
||||
class SuccessDialog: public QDialog {
|
||||
public:
|
||||
explicit SuccessDialog(std::string message, std::string action = "Ok");
|
||||
};
|
||||
|
||||
} // display
|
||||
|
||||
#endif //SCHEMEEDITOR_SUCCESS_DIALOG_H
|
|
@ -0,0 +1,16 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include "warning_dialog.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
WarningDialog::WarningDialog(domain::ValidationError error)
|
||||
: GenericDialog("Upozorenje", "U redu") {
|
||||
|
||||
auto contentLayout = new QVBoxLayout();
|
||||
content->setLayout(contentLayout);
|
||||
|
||||
contentLayout->addWidget(new QLabel(QString::fromStdString(error.message), this));
|
||||
}
|
||||
|
||||
} // display
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef SCHEMEEDITOR_WARNING_DIALOG_H
|
||||
#define SCHEMEEDITOR_WARNING_DIALOG_H
|
||||
|
||||
#include "generic_dialog.h"
|
||||
#include "comdel/domain/comdel_validator.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class WarningDialog : public GenericDialog {
|
||||
public:
|
||||
WarningDialog(domain::ValidationError error);
|
||||
|
||||
protected:
|
||||
bool onUpdate() override { return true; };
|
||||
};
|
||||
|
||||
|
||||
} // display
|
||||
|
||||
#endif //SCHEMEEDITOR_WARNING_DIALOG_H
|
|
@ -1,50 +0,0 @@
|
|||
//
|
||||
// Created by bbr on 18. 04. 2022..
|
||||
//
|
||||
|
||||
#include <set>
|
||||
#include "name_dialog.h"
|
||||
|
||||
display::NameDialog::NameDialog(std::string currentName, std::set<std::string> &names): currentName(currentName) {
|
||||
usedNames.erase(currentName);
|
||||
|
||||
auto *layout = new QVBoxLayout(this);
|
||||
layout->addWidget(new QLabel("Izmjeni ime", this));
|
||||
|
||||
edit = new QLineEdit(this);
|
||||
edit->insert(currentName.c_str());
|
||||
connect(edit, &QLineEdit::textChanged, this, &NameDialog::onNameUpdate);
|
||||
layout->addWidget(edit);
|
||||
setWindowTitle("Izmjeni ime");
|
||||
setLayout(layout);
|
||||
|
||||
auto buttonLayout = new QHBoxLayout(this);
|
||||
|
||||
button = new QPushButton("Ažuriraj");
|
||||
auto cancelButton = new QPushButton("Odustani", this);
|
||||
|
||||
connect(button, &QPushButton::clicked, this, &NameDialog::onNameChange);
|
||||
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
|
||||
|
||||
buttonLayout->addWidget(button);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
layout->addLayout(buttonLayout);
|
||||
}
|
||||
|
||||
void display::NameDialog::onNameUpdate(const QString &text) {
|
||||
if(usedNames.find(text.toStdString()) == usedNames.end()) {
|
||||
button->setDisabled(false);
|
||||
} else {
|
||||
button->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void display::NameDialog::onNameChange() {
|
||||
currentName = edit->text().toStdString();
|
||||
close();
|
||||
}
|
||||
|
||||
std::string display::NameDialog::getName() {
|
||||
return currentName;
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
#include "component_display.h"
|
||||
#include "schema_display.h"
|
||||
#include "application.h"
|
||||
#include "attribute_dialog.h"
|
||||
#include "single_automatic_dialog.h"
|
||||
#include "comdel/display/dialog/attribute_dialog.h"
|
||||
#include "comdel/display/dialog/single_automatic_dialog.h"
|
||||
#include "comdel/display/dialog/memory_dialog.h"
|
||||
|
||||
#include <QDrag>
|
||||
#include <QDragEnterEvent>
|
||||
|
@ -275,13 +276,13 @@ namespace display {
|
|||
domain::InstanceAttribute attribute(attr.getName(), attr.getDefault(), attr);
|
||||
if(attr.getPopup().has_value() && attr.getPopup()->getType() == domain::Popup::AUTOMATIC) {
|
||||
if(attr.getDefault().isType(domain::Value::MEMORY_REFERENCE)) {
|
||||
auto dialog = new MemoryDialog(&attribute, schema->componentInstances, false);
|
||||
auto dialog = new MemoryDialog("Postavi memoriju", "Postavi", &attribute, schema->componentInstances);
|
||||
if(dialog->exec() == QDialog::Rejected) {
|
||||
// if any dialog isn't set, whole creation is rejected
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
auto dialog = new AttributeDialog(&attribute, false);
|
||||
auto dialog = new AttributeDialog("Postavi " + attribute.name, "Postavi", &attribute);
|
||||
if(dialog->exec() == QDialog::Rejected) {
|
||||
// if any dialog isn't set, whole creation is rejected
|
||||
return {};
|
||||
|
@ -300,7 +301,7 @@ namespace display {
|
|||
instanceAttributes.emplace_back(attr.getName(), attr.getDefault(), attr);
|
||||
}
|
||||
|
||||
auto dialog = new display::SingleAutomaticDialog(instanceAttributes, false);
|
||||
auto dialog = new display::SingleAutomaticDialog("Postavi sabirnicu", "Postavi", instanceAttributes);
|
||||
if(dialog->exec() == QDialog::Rejected) {
|
||||
// if dialog is rejected, whole creation is rejected
|
||||
return {};
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace domain {
|
|||
errors.emplace_back(Action::ERROR, message);
|
||||
} else if (count > bus.getCount().second) {
|
||||
auto message = populateMessage(
|
||||
"Previše instanci sabirnice '{busName}' dozvoljeno najviše {max}, pronašeno {count}", context);
|
||||
"Previše instanci sabirnice '{busName}' dozvoljeno najviše {max}, pronađeno {count}", context);
|
||||
errors.emplace_back(Action::ERROR, message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,4 +197,31 @@ namespace domain {
|
|||
return val;
|
||||
}
|
||||
|
||||
bool Value::equals(Value value) {
|
||||
if (value.getType() == type) {
|
||||
switch (type) {
|
||||
case INT:
|
||||
return value.asInt() == intValue;
|
||||
case STRING:
|
||||
return value.asString() == stringValue;
|
||||
case NIL:
|
||||
case UNDEFINED:
|
||||
return true;
|
||||
case WIRE_REFERENCE:
|
||||
case ATTRIBUTE_REFERENCE:
|
||||
case ADDRESS_SPACE_REFERENCE:
|
||||
return value.asReference() == reference;
|
||||
case MEMORY_REFERENCE:
|
||||
return value.asMemoryReference() == memoryReference;
|
||||
case MEMORY:
|
||||
return value.asMemory() == memory;
|
||||
case BOOL:
|
||||
return value.asBool() == boolValue;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace domain
|
||||
|
|
|
@ -43,32 +43,7 @@ namespace domain {
|
|||
|
||||
Value() = default;
|
||||
|
||||
bool equals(Value value) {
|
||||
if (value.getType() == type) {
|
||||
switch (type) {
|
||||
case INT:
|
||||
return value.asInt() == intValue;
|
||||
case STRING:
|
||||
return value.asString() == stringValue;
|
||||
case NIL:
|
||||
case UNDEFINED:
|
||||
return true;
|
||||
case WIRE_REFERENCE:
|
||||
case ATTRIBUTE_REFERENCE:
|
||||
case ADDRESS_SPACE_REFERENCE:
|
||||
return value.asReference() == reference;
|
||||
case MEMORY_REFERENCE:
|
||||
return value.asMemoryReference() == memoryReference;
|
||||
case MEMORY:
|
||||
return value.asMemory() == memory;
|
||||
case BOOL:
|
||||
return value.asBool() == boolValue;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool equals(Value value);
|
||||
|
||||
std::string string();
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Version 0.0.1
|
||||
#include "libraries\frisc\vjezba1\FRISC.cdl"
|
||||
#include "libraries\frisc\vjezba1\dma.cdl"
|
||||
#include "libraries\frisc\vjezba1\memory.cdl"
|
||||
|
||||
|
||||
|
@ -23,31 +24,43 @@ component System
|
|||
wire --BACK;
|
||||
|
||||
|
||||
//PIOSabirnica
|
||||
wire<8> PIO_DATA;
|
||||
wire READY;
|
||||
wire STROBE;
|
||||
|
||||
|
||||
//directRam
|
||||
wire INT;
|
||||
|
||||
|
||||
// components --------------------------------------------
|
||||
subcomponent Memorija memorija<false, 1, 65536, 8, 0>(ADR, DATA, READ, WRITE, SIZE, WAIT, *, *, *, INT);
|
||||
subcomponent Memorija memorija<false, 1, 1024, 8, 0>(ADR, DATA, READ, WRITE, SIZE, WAIT, INT, *, *, *);
|
||||
subcomponent FRISC procesor(ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, INT1, INT2, INT3, --IACK, 1, *, INT, *, *, *);
|
||||
subcomponent DMA dma<1024>(ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, --BREQ, --BACK, 0, 0, *, *);
|
||||
|
||||
display {
|
||||
component { x: -377; y: -302; ref: "procesor"; }
|
||||
component { x: -56; y: -80; ref: "memorija"; }
|
||||
component { x: -104; y: -102; ref: "procesor"; }
|
||||
component { x: 39; y: 199; ref: "memorija"; }
|
||||
component { x: -352; y: 13; ref: "dma"; }
|
||||
|
||||
// glavnaSabirnica bus
|
||||
|
||||
rectangle {
|
||||
x: -377; y: -106;
|
||||
x: -106; y: 80;
|
||||
w: 100; h: 20;
|
||||
}
|
||||
|
||||
|
||||
// PIOSabirnica bus
|
||||
|
||||
|
||||
// directRam bus
|
||||
|
||||
|
||||
line {x1:-6; y1:-96; x2:-326; y2:-95;}
|
||||
line {x1:-327; y1:-186; x2:-326; y2:-95;}
|
||||
line {x1:-72; y1:-52; x2:-261; y2:-252;}
|
||||
line {x1:-54; y1:14; x2:-55; y2:90;}
|
||||
line {x1:89; y1:183; x2:-55; y2:90;}
|
||||
line {x1:-236; y1:51; x2:-55; y2:90;}
|
||||
line {x1:23; y1:227; x2:12; y2:-52;}
|
||||
}
|
||||
}
|
|
@ -2,15 +2,48 @@
|
|||
|
||||
@schema {
|
||||
@instance procesor FRISC {
|
||||
@position (-543, -304)
|
||||
@position (-104, -102)
|
||||
@attribute _memory null
|
||||
}
|
||||
|
||||
@instance memorija Memorija {
|
||||
@position (39, 199)
|
||||
@attribute sinkroniziran false
|
||||
@attribute brzina 1
|
||||
@attribute kapacitet 1024
|
||||
@attribute size 8
|
||||
@attribute pocetnaAdresa 0
|
||||
}
|
||||
|
||||
@instance dma DMA {
|
||||
@position (-352, 13)
|
||||
@attribute pocetnaAdresa 1024
|
||||
}
|
||||
|
||||
@instance glavnaSabirnica glavnaSabirnica {
|
||||
@position (-544, -91)
|
||||
@position (-106, 80)
|
||||
@size 100
|
||||
}
|
||||
|
||||
@instance PIOSabirnica PIOSabirnica {
|
||||
@position (0, 0)
|
||||
@size -1
|
||||
}
|
||||
|
||||
@instance directRam directRam {
|
||||
@position (0, 0)
|
||||
@size -1
|
||||
}
|
||||
|
||||
@connection (procesor.glavniPin, glavnaSabirnica) {
|
||||
}
|
||||
@connection (memorija.glavniPin, glavnaSabirnica) {
|
||||
}
|
||||
@connection (dma.glavniPin, glavnaSabirnica) {
|
||||
@attribute interupt INT0
|
||||
}
|
||||
@connection (memorija.memDirect, directRam, procesor.memDirect) {
|
||||
@attribute procConn "INT"
|
||||
@attribute memConn "INT"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "application.h"
|
||||
#include "comdel/display/dialog/error_dialog.h"
|
||||
#include "comdel/display/dialog/success_dialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#include <comdel/parser/parse_context.h>
|
||||
#include <comdel/parser/parser_util.h>
|
||||
#include <comdel/domain/schema_creator.h>
|
||||
#include <comdel/domain/comdel_validator.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <QPlainTextEdit>
|
||||
#include <comdel/domain/comdel_validator.h>
|
||||
#include <fstream>
|
||||
#include <comdel/domain/comdel_generator.h>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
|
@ -55,11 +53,6 @@ void MainWindow::setupUi()
|
|||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(libraryDisplay);
|
||||
layout->addWidget(schemaParent, 1);
|
||||
|
||||
log = new QPlainTextEdit();
|
||||
log->setFont(QFont("Courier"));
|
||||
log->setReadOnly(false);
|
||||
schemaLayout->addWidget(log);
|
||||
}
|
||||
|
||||
void MainWindow::onLoadLibrary() {
|
||||
|
@ -67,13 +60,13 @@ void MainWindow::onLoadLibrary() {
|
|||
tr("Otvori biblioteku"), "", tr("Comdel biblioteka (*.csl)"));
|
||||
if(!filename.isEmpty()) {
|
||||
std::ostringstream output;
|
||||
log->clear();
|
||||
|
||||
auto librarySource = filename.toStdString();
|
||||
|
||||
auto instance = Application::instance();
|
||||
if(!instance->loadLibrary(librarySource, output)) {
|
||||
log->appendPlainText(QString::fromStdString(output.str()));
|
||||
auto dialog = new display::ErrorDialog(output);
|
||||
dialog->exec();
|
||||
}
|
||||
|
||||
libraryDisplay->refreshContent();
|
||||
|
@ -86,7 +79,6 @@ void MainWindow::onLoadSchema() {
|
|||
tr("Otvori shemu"), "", tr("Comdel shema (*.csl)"));
|
||||
if(!filename.isEmpty()) {
|
||||
std::ostringstream output;
|
||||
log->clear();
|
||||
|
||||
auto schemaSource = filename.toStdString();
|
||||
|
||||
|
@ -94,7 +86,8 @@ void MainWindow::onLoadSchema() {
|
|||
auto result = instance->loadSchema(schemaSource, output);
|
||||
if(!result.first){
|
||||
formatErrors(result.second, output);
|
||||
log->appendPlainText(QString::fromStdString(output.str()));
|
||||
auto dialog = new display::ErrorDialog(output);
|
||||
dialog->exec();
|
||||
}
|
||||
|
||||
libraryDisplay->refreshContent();
|
||||
|
@ -106,8 +99,6 @@ void MainWindow::onStoreScheme() {
|
|||
auto filename = QFileDialog::getSaveFileName(this,
|
||||
tr("Spremi shemu"), "", tr("Comdel shema (*.csl)"));
|
||||
if(!filename.isEmpty()) {
|
||||
log->clear();
|
||||
|
||||
std::ostringstream output;
|
||||
|
||||
if(Application::instance()->generateSchema(output)) {
|
||||
|
@ -115,9 +106,11 @@ void MainWindow::onStoreScheme() {
|
|||
out<<output.str();
|
||||
out.close();
|
||||
|
||||
log->appendPlainText("Uspješno spremljena shema\n");
|
||||
auto dialog = new display::SuccessDialog("Uspješno spremljena shema");
|
||||
dialog->exec();
|
||||
} else {
|
||||
log->appendPlainText("Greška tijekom spremanja sheme\n");
|
||||
auto dialog = new display::ErrorDialog(output);
|
||||
dialog->exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,24 +120,23 @@ void MainWindow::onGenerateComdel() {
|
|||
auto filename = QFileDialog::getSaveFileName(this,
|
||||
tr("Spremi shemu"), "", tr("Comdel sustav (*.system)"));
|
||||
if(!filename.isEmpty()) {
|
||||
log->clear();
|
||||
|
||||
std::ostringstream output;
|
||||
|
||||
auto validationErrors = Application::instance()->generateComdel(output);
|
||||
|
||||
std::ostringstream buff;
|
||||
formatErrors(validationErrors, buff);
|
||||
log->appendPlainText(QString::fromStdString(buff.str()));
|
||||
|
||||
if(!Application::hasErrors(validationErrors)) {
|
||||
std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary);
|
||||
out<<output.str();
|
||||
out.close();
|
||||
|
||||
log->appendPlainText("Uspješno generiranje comdel modela\n");
|
||||
auto dialog = new display::SuccessDialog("Uspješno generiran comdel model");
|
||||
dialog->exec();
|
||||
} else {
|
||||
log->appendPlainText("Neuspješno generiranje comdel modela\n");
|
||||
auto dialog = new display::ErrorDialog(output);
|
||||
dialog->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,15 +144,17 @@ void MainWindow::onGenerateComdel() {
|
|||
|
||||
void MainWindow::onValidateSchema(bool /*toggled*/) {
|
||||
|
||||
log->clear();
|
||||
|
||||
auto errors = Application::instance()->validateSchema();
|
||||
|
||||
std::ostringstream buff;
|
||||
formatErrors(errors, buff);
|
||||
|
||||
log->appendPlainText(QString::fromStdString(buff.str()));
|
||||
|
||||
if(Application::hasErrors(errors)) {
|
||||
std::ostringstream buff;
|
||||
formatErrors(errors, buff);
|
||||
auto dialog = new display::ErrorDialog(buff);
|
||||
dialog->exec();
|
||||
} else {
|
||||
auto dialog = new display::SuccessDialog("Nema validacijskih greški");
|
||||
dialog->exec();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::formatErrors(std::vector<domain::ValidationError>& errors, std::ostream& output) {
|
||||
|
|
|
@ -40,7 +40,6 @@ private:
|
|||
display::Library *libraryDisplay;
|
||||
display::Schema *schemaDisplay;
|
||||
Ui::MainWindow *ui;
|
||||
QPlainTextEdit *log;
|
||||
|
||||
static void formatErrors(std::vector<domain::ValidationError>& errors, std::ostream& output);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue