From 7be3a1b5bc0076cc003962eceba7862ca52bbc89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Borna=20Rajkovi=C4=87?= Date: Tue, 14 Jun 2022 00:53:46 +0200 Subject: [PATCH] Refactored validation --- CMakeLists.txt | 2 +- comdel/display/attribute_dialog.cpp | 283 ------------------ comdel/display/attribute_dialog.h | 89 ------ comdel/display/component_display.cpp | 15 +- comdel/display/dialog/attribute_dialog.cpp | 180 +++++++++++ comdel/display/dialog/attribute_dialog.h | 47 +++ comdel/display/dialog/error_dialog.cpp | 34 +++ comdel/display/dialog/error_dialog.h | 22 ++ comdel/display/dialog/generic_dialog.cpp | 29 ++ comdel/display/dialog/generic_dialog.h | 29 ++ comdel/display/dialog/memory_dialog.cpp | 59 ++++ comdel/display/dialog/memory_dialog.h | 33 ++ comdel/display/dialog/name_dialog.cpp | 39 +++ comdel/display/{ => dialog}/name_dialog.h | 20 +- .../{ => dialog}/single_automatic_dialog.cpp | 37 +-- .../{ => dialog}/single_automatic_dialog.h | 15 +- comdel/display/dialog/success_dialog.cpp | 17 ++ comdel/display/dialog/success_dialog.h | 19 ++ comdel/display/dialog/warning_dialog.cpp | 16 + comdel/display/dialog/warning_dialog.h | 20 ++ comdel/display/name_dialog.cpp | 50 ---- comdel/display/schema_display.cpp | 11 +- comdel/domain/comdel_validator.cpp | 2 +- comdel/domain/value.cpp | 27 ++ comdel/domain/value.h | 27 +- examples/simplified FRISC model/comdel.system | 27 +- examples/simplified FRISC model/schema4.csl | 37 ++- mainwindow.cpp | 54 ++-- mainwindow.h | 1 - 29 files changed, 696 insertions(+), 545 deletions(-) delete mode 100644 comdel/display/attribute_dialog.cpp delete mode 100644 comdel/display/attribute_dialog.h create mode 100644 comdel/display/dialog/attribute_dialog.cpp create mode 100644 comdel/display/dialog/attribute_dialog.h create mode 100644 comdel/display/dialog/error_dialog.cpp create mode 100644 comdel/display/dialog/error_dialog.h create mode 100644 comdel/display/dialog/generic_dialog.cpp create mode 100644 comdel/display/dialog/generic_dialog.h create mode 100644 comdel/display/dialog/memory_dialog.cpp create mode 100644 comdel/display/dialog/memory_dialog.h create mode 100644 comdel/display/dialog/name_dialog.cpp rename comdel/display/{ => dialog}/name_dialog.h (74%) rename comdel/display/{ => dialog}/single_automatic_dialog.cpp (62%) rename comdel/display/{ => dialog}/single_automatic_dialog.h (70%) create mode 100644 comdel/display/dialog/success_dialog.cpp create mode 100644 comdel/display/dialog/success_dialog.h create mode 100644 comdel/display/dialog/warning_dialog.cpp create mode 100644 comdel/display/dialog/warning_dialog.h delete mode 100644 comdel/display/name_dialog.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d46ca2..a0aaa8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/comdel/display/attribute_dialog.cpp b/comdel/display/attribute_dialog.cpp deleted file mode 100644 index 372e822..0000000 --- a/comdel/display/attribute_dialog.cpp +++ /dev/null @@ -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::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 errors; - std::vector 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> instances, bool updating) { - memoryInstances = std::vector(); - - 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::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 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); - } -} \ No newline at end of file diff --git a/comdel/display/attribute_dialog.h b/comdel/display/attribute_dialog.h deleted file mode 100644 index 1f7df1e..0000000 --- a/comdel/display/attribute_dialog.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef ATTRIBUTE_DIALOG_H -#define ATTRIBUTE_DIALOG_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#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 memoryInstances; - - public: - MemoryDialog(domain::InstanceAttribute *attribute, - std::vector> instances, bool updating = true); - - public slots: - - void onMemoryChanged(int index); - - void onUpdate(); - - }; - - - class ErrorDialog : public QDialog { - public: - ErrorDialog(std::vector errors); - }; - - class WarningDialog : public QDialog { - public: - WarningDialog(domain::ValidationError error); - }; - -} - -#endif //ATTRIBUTE_DIALOG_H diff --git a/comdel/display/component_display.cpp b/comdel/display/component_display.cpp index 8e33321..cf393f8 100644 --- a/comdel/display/component_display.cpp +++ b/comdel/display/component_display.cpp @@ -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 #include @@ -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(); }); } diff --git a/comdel/display/dialog/attribute_dialog.cpp b/comdel/display/dialog/attribute_dialog.cpp new file mode 100644 index 0000000..1236c9b --- /dev/null +++ b/comdel/display/dialog/attribute_dialog.cpp @@ -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 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::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 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; + } + +} \ No newline at end of file diff --git a/comdel/display/dialog/attribute_dialog.h b/comdel/display/dialog/attribute_dialog.h new file mode 100644 index 0000000..9ab1c23 --- /dev/null +++ b/comdel/display/dialog/attribute_dialog.h @@ -0,0 +1,47 @@ +#ifndef ATTRIBUTE_DIALOG_H +#define ATTRIBUTE_DIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 validate(); + + domain::Value value; + domain::InstanceAttribute *attributeValue; + domain::Popup popup; + }; + +} + +#endif //ATTRIBUTE_DIALOG_H diff --git a/comdel/display/dialog/error_dialog.cpp b/comdel/display/dialog/error_dialog.cpp new file mode 100644 index 0000000..736042e --- /dev/null +++ b/comdel/display/dialog/error_dialog.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include "error_dialog.h" + +namespace display { + + ErrorDialog::ErrorDialog(std::vector 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 \ No newline at end of file diff --git a/comdel/display/dialog/error_dialog.h b/comdel/display/dialog/error_dialog.h new file mode 100644 index 0000000..4c53b5e --- /dev/null +++ b/comdel/display/dialog/error_dialog.h @@ -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 + + +namespace display { + + class ErrorDialog : public GenericDialog { + public: + ErrorDialog(std::vector errors); + ErrorDialog(std::ostringstream& errorStream); + + protected: + bool onUpdate() override { return true; } + }; + +} // display + +#endif //SCHEMEEDITOR_ERROR_DIALOG_H diff --git a/comdel/display/dialog/generic_dialog.cpp b/comdel/display/dialog/generic_dialog.cpp new file mode 100644 index 0000000..c8a2ce4 --- /dev/null +++ b/comdel/display/dialog/generic_dialog.cpp @@ -0,0 +1,29 @@ +#include +#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); +} diff --git a/comdel/display/dialog/generic_dialog.h b/comdel/display/dialog/generic_dialog.h new file mode 100644 index 0000000..d2f2ee4 --- /dev/null +++ b/comdel/display/dialog/generic_dialog.h @@ -0,0 +1,29 @@ +#ifndef SCHEMEEDITOR_GENERIC_DIALOG_H +#define SCHEMEEDITOR_GENERIC_DIALOG_H + +#include +#include +#include + +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 diff --git a/comdel/display/dialog/memory_dialog.cpp b/comdel/display/dialog/memory_dialog.cpp new file mode 100644 index 0000000..27e2ccd --- /dev/null +++ b/comdel/display/dialog/memory_dialog.cpp @@ -0,0 +1,59 @@ +#include +#include +#include "memory_dialog.h" + +namespace display { + + + MemoryDialog::MemoryDialog(std::string title, std::string action, domain::InstanceAttribute *attribute, + std::vector> 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::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 \ No newline at end of file diff --git a/comdel/display/dialog/memory_dialog.h b/comdel/display/dialog/memory_dialog.h new file mode 100644 index 0000000..e37aace --- /dev/null +++ b/comdel/display/dialog/memory_dialog.h @@ -0,0 +1,33 @@ +#ifndef SCHEMEEDITOR_MEMORY_DIALOG_H +#define SCHEMEEDITOR_MEMORY_DIALOG_H + +#include +#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> instances); + + protected: + bool onUpdate() override; + + private: + QComboBox *setupEnumeration(); + + domain::Value value; + domain::InstanceAttribute *attributeValue; + std::vector memoryInstances; + + domain::Popup popup; + }; + + +} // display + +#endif //SCHEMEEDITOR_MEMORY_DIALOG_H diff --git a/comdel/display/dialog/name_dialog.cpp b/comdel/display/dialog/name_dialog.cpp new file mode 100644 index 0000000..a77fbf7 --- /dev/null +++ b/comdel/display/dialog/name_dialog.cpp @@ -0,0 +1,39 @@ +#include +#include "name_dialog.h" + +namespace display { + + NameDialog::NameDialog(std::string currentName, std::set &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; + } + +} diff --git a/comdel/display/name_dialog.h b/comdel/display/dialog/name_dialog.h similarity index 74% rename from comdel/display/name_dialog.h rename to comdel/display/dialog/name_dialog.h index 8449c79..deeedfb 100644 --- a/comdel/display/name_dialog.h +++ b/comdel/display/dialog/name_dialog.h @@ -9,25 +9,29 @@ #include -#include +#include "comdel/domain/instance.h" +#include "generic_dialog.h" namespace display { - class NameDialog : public QDialog { - - std::set usedNames; - QLineEdit *edit = nullptr; - std::string currentName; - QPushButton *button; + class NameDialog : public GenericDialog { public: NameDialog(std::string currentName, std::set& names); std::string getName(); + protected: + bool onUpdate() override; + public slots: void onNameUpdate(const QString& text); - void onNameChange(); + + private: + std::set usedNames; + QLineEdit *edit = nullptr; + std::string currentName; + }; } diff --git a/comdel/display/single_automatic_dialog.cpp b/comdel/display/dialog/single_automatic_dialog.cpp similarity index 62% rename from comdel/display/single_automatic_dialog.cpp rename to comdel/display/dialog/single_automatic_dialog.cpp index fb1667c..a5ff039 100644 --- a/comdel/display/single_automatic_dialog.cpp +++ b/comdel/display/dialog/single_automatic_dialog.cpp @@ -1,7 +1,3 @@ -// -// Created by bbr on 05.06.22.. -// - #include "single_automatic_dialog.h" #include #include @@ -9,38 +5,23 @@ #include namespace display { - SingleAutomaticDialog::SingleAutomaticDialog(std::vector &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 &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 \ No newline at end of file diff --git a/comdel/display/single_automatic_dialog.h b/comdel/display/dialog/single_automatic_dialog.h similarity index 70% rename from comdel/display/single_automatic_dialog.h rename to comdel/display/dialog/single_automatic_dialog.h index 8689188..bf2946d 100644 --- a/comdel/display/single_automatic_dialog.h +++ b/comdel/display/dialog/single_automatic_dialog.h @@ -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 #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 &attributes; public: - explicit SingleAutomaticDialog(std::vector& values, bool updating = true); + explicit SingleAutomaticDialog( + std::string title, + std::string action, + std::vector& 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 diff --git a/comdel/display/dialog/success_dialog.cpp b/comdel/display/dialog/success_dialog.cpp new file mode 100644 index 0000000..bae5529 --- /dev/null +++ b/comdel/display/dialog/success_dialog.cpp @@ -0,0 +1,17 @@ +#include +#include +#include +#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 \ No newline at end of file diff --git a/comdel/display/dialog/success_dialog.h b/comdel/display/dialog/success_dialog.h new file mode 100644 index 0000000..0f12386 --- /dev/null +++ b/comdel/display/dialog/success_dialog.h @@ -0,0 +1,19 @@ +// +// Created by bbr on 14.06.22.. +// + +#ifndef SCHEMEEDITOR_SUCCESS_DIALOG_H +#define SCHEMEEDITOR_SUCCESS_DIALOG_H + +#include + +namespace display { + + class SuccessDialog: public QDialog { + public: + explicit SuccessDialog(std::string message, std::string action = "Ok"); + }; + +} // display + +#endif //SCHEMEEDITOR_SUCCESS_DIALOG_H diff --git a/comdel/display/dialog/warning_dialog.cpp b/comdel/display/dialog/warning_dialog.cpp new file mode 100644 index 0000000..4405d79 --- /dev/null +++ b/comdel/display/dialog/warning_dialog.cpp @@ -0,0 +1,16 @@ +#include +#include +#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 \ No newline at end of file diff --git a/comdel/display/dialog/warning_dialog.h b/comdel/display/dialog/warning_dialog.h new file mode 100644 index 0000000..4e73557 --- /dev/null +++ b/comdel/display/dialog/warning_dialog.h @@ -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 diff --git a/comdel/display/name_dialog.cpp b/comdel/display/name_dialog.cpp deleted file mode 100644 index 539e8e1..0000000 --- a/comdel/display/name_dialog.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// Created by bbr on 18. 04. 2022.. -// - -#include -#include "name_dialog.h" - -display::NameDialog::NameDialog(std::string currentName, std::set &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; -} diff --git a/comdel/display/schema_display.cpp b/comdel/display/schema_display.cpp index cd2db37..22af1c0 100644 --- a/comdel/display/schema_display.cpp +++ b/comdel/display/schema_display.cpp @@ -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 #include @@ -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 {}; diff --git a/comdel/domain/comdel_validator.cpp b/comdel/domain/comdel_validator.cpp index 66a7067..64dda6b 100644 --- a/comdel/domain/comdel_validator.cpp +++ b/comdel/domain/comdel_validator.cpp @@ -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); } } diff --git a/comdel/domain/value.cpp b/comdel/domain/value.cpp index c5d0914..ab18620 100644 --- a/comdel/domain/value.cpp +++ b/comdel/domain/value.cpp @@ -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 diff --git a/comdel/domain/value.h b/comdel/domain/value.h index 70f7807..f39b6d3 100644 --- a/comdel/domain/value.h +++ b/comdel/domain/value.h @@ -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(); diff --git a/examples/simplified FRISC model/comdel.system b/examples/simplified FRISC model/comdel.system index d057741..180bf1d 100644 --- a/examples/simplified FRISC model/comdel.system +++ b/examples/simplified FRISC model/comdel.system @@ -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(ADR, DATA, READ, WRITE, SIZE, WAIT, *, *, *, INT); + subcomponent Memorija memorija(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;} } } \ No newline at end of file diff --git a/examples/simplified FRISC model/schema4.csl b/examples/simplified FRISC model/schema4.csl index c2d32e3..f65fc46 100644 --- a/examples/simplified FRISC model/schema4.csl +++ b/examples/simplified FRISC model/schema4.csl @@ -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" + } } diff --git a/mainwindow.cpp b/mainwindow.cpp index 7c1ab3d..f6593c2 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -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 #include #include -#include -#include +#include #include -#include -#include #include -#include 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<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<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& errors, std::ostream& output) { diff --git a/mainwindow.h b/mainwindow.h index 44eba88..1f4ec20 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -40,7 +40,6 @@ private: display::Library *libraryDisplay; display::Schema *schemaDisplay; Ui::MainWindow *ui; - QPlainTextEdit *log; static void formatErrors(std::vector& errors, std::ostream& output); };