Compare commits
3 Commits
eaa115d115
...
9129a4bf43
Author | SHA1 | Date |
---|---|---|
Borna Rajković | 9129a4bf43 | |
Borna Rajković | 350aa95da5 | |
Borna Rajković | d2fc849cc2 |
|
@ -37,5 +37,5 @@ add_executable(SchemeEditor
|
||||||
comdel/parser/comdel_lexer.cpp
|
comdel/parser/comdel_lexer.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
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)
|
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 message_source.cpp message_source.h)
|
||||||
target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets)
|
target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||||
|
|
|
@ -9,13 +9,18 @@ CONFIG += c++17
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
comdel/display/attribute_dialog.cpp \
|
comdel/display/dialog/attribute_dialog.cpp \
|
||||||
|
comdel/display/dialog/error_dialog.cpp \
|
||||||
|
comdel/display/dialog/generic_dialog.cpp \
|
||||||
|
comdel/display/dialog/memory_dialog.cpp \
|
||||||
|
comdel/display/dialog/name_dialog.cpp \
|
||||||
|
comdel/display/dialog/single_automatic_dialog.cpp \
|
||||||
|
comdel/display/dialog/success_dialog.cpp \
|
||||||
|
comdel/display/dialog/warning_dialog.cpp \
|
||||||
comdel/display/component_display.cpp \
|
comdel/display/component_display.cpp \
|
||||||
comdel/display/library_display.cpp \
|
comdel/display/library_display.cpp \
|
||||||
comdel/display/library_list.cpp \
|
comdel/display/library_list.cpp \
|
||||||
comdel/display/name_dialog.cpp \
|
|
||||||
comdel/display/schema_display.cpp \
|
comdel/display/schema_display.cpp \
|
||||||
comdel/display/single_automatic_dialog.cpp \
|
|
||||||
comdel/domain/address_space.cpp \
|
comdel/domain/address_space.cpp \
|
||||||
comdel/domain/attribute.cpp \
|
comdel/domain/attribute.cpp \
|
||||||
comdel/domain/bus.cpp \
|
comdel/domain/bus.cpp \
|
||||||
|
@ -44,16 +49,22 @@ SOURCES += \
|
||||||
comdel/parser/tokens_type.cpp \
|
comdel/parser/tokens_type.cpp \
|
||||||
application.cpp \
|
application.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
|
message_source.cpp \
|
||||||
mainwindow.cpp
|
mainwindow.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
comdel/display/attribute_dialog.h \
|
comdel/display/dialog/attribute_dialog.h \
|
||||||
|
comdel/display/dialog/error_dialog.h \
|
||||||
|
comdel/display/dialog/generic_dialog.h \
|
||||||
|
comdel/display/dialog/memory_dialog.h \
|
||||||
|
comdel/display/dialog/name_dialog.h \
|
||||||
|
comdel/display/dialog/single_automatic_dialog.h \
|
||||||
|
comdel/display/dialog/success_dialog.h \
|
||||||
|
comdel/display/dialog/warning_dialog.h \
|
||||||
comdel/display/component_display.h \
|
comdel/display/component_display.h \
|
||||||
comdel/display/library_display.h \
|
comdel/display/library_display.h \
|
||||||
comdel/display/library_list.h \
|
comdel/display/library_list.h \
|
||||||
comdel/display/name_dialog.h \
|
|
||||||
comdel/display/schema_display.h \
|
comdel/display/schema_display.h \
|
||||||
comdel/display/single_automatic_dialog.h \
|
|
||||||
comdel/domain/address_space.h \
|
comdel/domain/address_space.h \
|
||||||
comdel/domain/attribute.h \
|
comdel/domain/attribute.h \
|
||||||
comdel/domain/bus.h \
|
comdel/domain/bus.h \
|
||||||
|
@ -83,6 +94,7 @@ HEADERS += \
|
||||||
comdel/parser/source_error.h \
|
comdel/parser/source_error.h \
|
||||||
comdel/parser/token.h \
|
comdel/parser/token.h \
|
||||||
comdel/parser/tokens_type.h \
|
comdel/parser/tokens_type.h \
|
||||||
|
message_source.h \
|
||||||
mainwindow.h
|
mainwindow.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "comdel/display/dialog/single_automatic_dialog.h"
|
#include "comdel/display/dialog/single_automatic_dialog.h"
|
||||||
#include "comdel/display/dialog/memory_dialog.h"
|
#include "comdel/display/dialog/memory_dialog.h"
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QLine>
|
#include <QLine>
|
||||||
|
@ -25,7 +26,7 @@ namespace display {
|
||||||
|
|
||||||
void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
menu.addAction("Izmjeni ime", [this]() {
|
menu.addAction(QMESSAGE("msg_dialog_name_update"), [this]() {
|
||||||
std::set<std::string> names;
|
std::set<std::string> names;
|
||||||
for(const auto &component: Application::instance()->getSchema()->componentInstances) {
|
for(const auto &component: Application::instance()->getSchema()->componentInstances) {
|
||||||
names.insert(component->name);
|
names.insert(component->name);
|
||||||
|
@ -45,22 +46,29 @@ namespace display {
|
||||||
bool enabled = attr->attribute.getPopup().has_value();
|
bool enabled = attr->attribute.getPopup().has_value();
|
||||||
|
|
||||||
if(attr->value.getType() == domain::Value::MEMORY_REFERENCE) {
|
if(attr->value.getType() == domain::Value::MEMORY_REFERENCE) {
|
||||||
menu.addAction("Izmjeni memoriju", [attr]() {
|
menu.addAction(QMESSAGE("msg_dialog_memory_update"), [attr]() {
|
||||||
auto dialog = new MemoryDialog("Izmjeni memoriju", "Izmjeni", attr,
|
auto dialog = new MemoryDialog(MESSAGE("msg_dialog_memory_update"),
|
||||||
|
MESSAGE("msg_dialog_actions_update"),
|
||||||
|
attr,
|
||||||
Application::instance()->getSchema()->componentInstances);
|
Application::instance()->getSchema()->componentInstances);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
auto action = menu.addAction(QString::fromStdString("Izmjeni '" + attr->attribute.getDisplayName() + "'"),
|
std::map<std::string, std::string> params = {{"attribute", attr->attribute.getDisplayName()}};
|
||||||
|
auto action = menu.addAction(QMESSAGE_PARAM("msg_dialog_attribute_update", params),
|
||||||
[attr]() {
|
[attr]() {
|
||||||
auto dialog = new AttributeDialog("Izmjeni " + attr->attribute.getDisplayName(), "Izmjeni", attr);
|
std::map<std::string, std::string> params = {{"attribute", attr->attribute.getDisplayName()}};
|
||||||
|
auto dialog = new AttributeDialog(MESSAGE_PARAM("msg_dialog_attribute_update", params),
|
||||||
|
"msg_dialog_actions_update",
|
||||||
|
attr);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
});
|
});
|
||||||
action->setEnabled(enabled);
|
action->setEnabled(enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
menu.addAction(QString::fromStdString("Ukloni " + this->instance->name), [this]() {
|
std::map<std::string, std::string> params = {{"name", instance->name}};
|
||||||
|
menu.addAction(QMESSAGE_PARAM("msg_dialog_actions_remove_named", params), [this]() {
|
||||||
Application::instance()->removeComponent(this->instance->name);
|
Application::instance()->removeComponent(this->instance->name);
|
||||||
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
||||||
view->refreshContent();
|
view->refreshContent();
|
||||||
|
@ -75,19 +83,28 @@ namespace display {
|
||||||
auto pinConnections = Application::instance()->getSchema()->getConnections(componentInstance->name, pin.getName());
|
auto pinConnections = Application::instance()->getSchema()->getConnections(componentInstance->name, pin.getName());
|
||||||
|
|
||||||
if(isSingleAutomatic(pinConnections)) {
|
if(isSingleAutomatic(pinConnections)) {
|
||||||
auto *update = menu.addMenu("Izmjeni");
|
auto *update = menu.addMenu(QMESSAGE("msg_pin_update"));
|
||||||
auto *remove = menu.addMenu("Ukloni");
|
auto *remove = menu.addMenu(QMESSAGE("msg_pin_remove"));
|
||||||
for (auto pinConnection: pinConnections) {
|
for (auto pinConnection: pinConnections) {
|
||||||
// this always must be true as only directConnections can be connected multiple times
|
// this always must be true as only directConnections can be connected multiple times
|
||||||
if (auto directConnection = dynamic_cast<domain::DirectConnectionInstance *>(pinConnection)) {
|
if (auto directConnection = dynamic_cast<domain::DirectConnectionInstance *>(pinConnection)) {
|
||||||
if (directConnection->bus->bus.getType() == domain::Bus::SINGLE_AUTOMATIC) {
|
if (directConnection->bus->bus.getType() == domain::Bus::SINGLE_AUTOMATIC) {
|
||||||
auto connectionName = directConnection->attributes[0].value.stringify() + "-" +
|
auto params = MessageSource::instance()->map(
|
||||||
directConnection->attributes[1].value.stringify();
|
{{"wire1", directConnection->attributes[0].value},
|
||||||
update->addAction(QString::fromStdString("Izmjeni " + connectionName), [directConnection]() {
|
{"wire2", directConnection->attributes[1].value}}
|
||||||
auto dialog = new SingleAutomaticDialog("Izmjeni sabirnicu", "Izmjeni", directConnection->attributes);
|
);
|
||||||
|
update->addAction(QMESSAGE_PARAM("msg_sa_pin_update_title", params),
|
||||||
|
[directConnection]() {
|
||||||
|
auto params = MessageSource::instance()->map(
|
||||||
|
{{"wire1", directConnection->attributes[0].value},
|
||||||
|
{"wire2", directConnection->attributes[1].value}}
|
||||||
|
);
|
||||||
|
auto dialog = new SingleAutomaticDialog(MESSAGE_PARAM("msg_sa_pin_update_title", params),
|
||||||
|
MESSAGE("msg_pin_update_action"),
|
||||||
|
directConnection->attributes);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
});
|
});
|
||||||
remove->addAction(QString::fromStdString("Ukloni " + connectionName),
|
remove->addAction(QMESSAGE_PARAM("msg_sa_pin_remove_title", params),
|
||||||
[this, directConnection]() {
|
[this, directConnection]() {
|
||||||
Application::instance()->removeConnection(directConnection);
|
Application::instance()->removeConnection(directConnection);
|
||||||
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
||||||
|
@ -109,12 +126,15 @@ namespace display {
|
||||||
}
|
}
|
||||||
for (int i = 0; i < pinConnection->attributes.size(); i++) {
|
for (int i = 0; i < pinConnection->attributes.size(); i++) {
|
||||||
auto *attr = &pinConnection->attributes[i];
|
auto *attr = &pinConnection->attributes[i];
|
||||||
menu.addAction(QString::fromStdString("Izmjeni '" + attr->attribute.getDisplayName() + "'"),[attr]() {
|
std::map<std::string, std::string> params = {{"name", attr->attribute.getDisplayName()}};
|
||||||
auto dialog = new AttributeDialog("Izmjeni '" + attr->attribute.getDisplayName() + "'", "Izmjeni", attr);
|
menu.addAction(QMESSAGE_PARAM("msg_dialog_actions_update_named", params),
|
||||||
|
[attr]() {
|
||||||
|
std::map<std::string, std::string> params = {{"name", attr->attribute.getDisplayName()}};
|
||||||
|
auto dialog = new AttributeDialog(MESSAGE_PARAM("msg_dialog_actions_update_named", params), "msg_pin_update_action", attr);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
menu.addAction("Ukloni poveznicu", [this, pinConnection]() {
|
menu.addAction(QMESSAGE("msg_pin_remove_action"), [this, pinConnection]() {
|
||||||
Application::instance()->removeConnection(pinConnection);
|
Application::instance()->removeConnection(pinConnection);
|
||||||
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
||||||
view->refreshContent();
|
view->refreshContent();
|
||||||
|
@ -186,7 +206,7 @@ namespace display {
|
||||||
|
|
||||||
void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
menu.addAction("Izmjeni ime", [this]() {
|
menu.addAction(QMESSAGE("msg_dialog_name_update"), [this]() {
|
||||||
std::set<std::string> names;
|
std::set<std::string> names;
|
||||||
for(const auto &component: Application::instance()->getSchema()->busInstances) {
|
for(const auto &component: Application::instance()->getSchema()->busInstances) {
|
||||||
names.insert(component->name);
|
names.insert(component->name);
|
||||||
|
@ -201,7 +221,9 @@ namespace display {
|
||||||
setToolTip(QString::fromStdString(busInstance->name + "::" + busInstance->bus.getDisplayName()));
|
setToolTip(QString::fromStdString(busInstance->name + "::" + busInstance->bus.getDisplayName()));
|
||||||
});
|
});
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
menu.addAction(QString::fromStdString("Ukloni " + this->busInstance->name), [this]() {
|
|
||||||
|
std::map<std::string, std::string> params = {{"name", busInstance->name}};
|
||||||
|
menu.addAction(QMESSAGE_PARAM("msg_dialog_actions_remove_named", params), [this]() {
|
||||||
Application::instance()->removeBus(this->busInstance->name);
|
Application::instance()->removeBus(this->busInstance->name);
|
||||||
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
||||||
view->refreshContent();
|
view->refreshContent();
|
||||||
|
@ -306,11 +328,20 @@ namespace display {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectConnection::updateConnection() {
|
void DirectConnection::updateConnection() {
|
||||||
auto pin1 = connection->instance->component.getPin(
|
domain::ui::Pin pin1, pin2;
|
||||||
|
if(connection->connection.getComponent().component == connection->instance->component.getName()) {
|
||||||
|
pin1 = connection->instance->component.getPin(
|
||||||
connection->connection.getComponent().pin).getDisplayPin();
|
connection->connection.getComponent().pin).getDisplayPin();
|
||||||
auto pin2 = connection->secondInstance->component.getPin(
|
pin2 = connection->secondInstance->component.getPin(
|
||||||
connection->connection.getSecondComponent()->pin).getDisplayPin();
|
connection->connection.getSecondComponent()->pin).getDisplayPin();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pin1 = connection->instance->component.getPin(
|
||||||
|
connection->connection.getSecondComponent()->pin).getDisplayPin();
|
||||||
|
pin2 = connection->secondInstance->component.getPin(
|
||||||
|
connection->connection.getComponent().pin).getDisplayPin();
|
||||||
|
}
|
||||||
|
|
||||||
setLine(connection->instance->position.first + pin1.getConnectionX(),
|
setLine(connection->instance->position.first + pin1.getConnectionX(),
|
||||||
connection->instance->position.second + pin1.getConnectionY(),
|
connection->instance->position.second + pin1.getConnectionY(),
|
||||||
connection->secondInstance->position.first + pin2.getConnectionX(),
|
connection->secondInstance->position.first + pin2.getConnectionX(),
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "error_dialog.h"
|
#include "error_dialog.h"
|
||||||
#include "warning_dialog.h"
|
#include "warning_dialog.h"
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
|
@ -140,11 +141,11 @@ namespace display {
|
||||||
auto *radioLayout = new QHBoxLayout(group);
|
auto *radioLayout = new QHBoxLayout(group);
|
||||||
group->setLayout(radioLayout);
|
group->setLayout(radioLayout);
|
||||||
|
|
||||||
auto isTrue = new QRadioButton("da", group);
|
auto isTrue = new QRadioButton(QMESSAGE("msg_boolean_true"), group);
|
||||||
connect(isTrue, &QRadioButton::clicked, [this]() {
|
connect(isTrue, &QRadioButton::clicked, [this]() {
|
||||||
this->value = domain::Value::fromBool(true);
|
this->value = domain::Value::fromBool(true);
|
||||||
});
|
});
|
||||||
auto isFalse = new QRadioButton("ne", group);
|
auto isFalse = new QRadioButton(QMESSAGE("msg_boolean_false"), group);
|
||||||
connect(isFalse, &QRadioButton::clicked, [this]() {
|
connect(isFalse, &QRadioButton::clicked, [this]() {
|
||||||
this->value = domain::Value::fromBool(false);
|
this->value = domain::Value::fromBool(false);
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
ErrorDialog::ErrorDialog(std::vector<domain::ValidationError> errors)
|
ErrorDialog::ErrorDialog(std::vector<domain::ValidationError> errors)
|
||||||
: GenericDialog("Greške", "") {
|
: GenericDialog("msg_dialog_error_title", std::nullopt, "msg_dialog_error_close") {
|
||||||
|
|
||||||
auto contentLayout = new QVBoxLayout();
|
auto contentLayout = new QVBoxLayout();
|
||||||
content->setLayout(contentLayout);
|
content->setLayout(contentLayout);
|
||||||
|
@ -17,7 +17,7 @@ namespace display {
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorDialog::ErrorDialog(std::ostringstream& errorStream)
|
ErrorDialog::ErrorDialog(std::ostringstream& errorStream)
|
||||||
: GenericDialog("Greške", "") {
|
: GenericDialog("msg_dialog_error_title", std::nullopt, "msg_dialog_error_close") {
|
||||||
|
|
||||||
auto contentLayout = new QVBoxLayout();
|
auto contentLayout = new QVBoxLayout();
|
||||||
content->setLayout(contentLayout);
|
content->setLayout(contentLayout);
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include "generic_dialog.h"
|
#include "generic_dialog.h"
|
||||||
|
|
||||||
display::GenericDialog::GenericDialog(std::string title, std::string action) {
|
#include "message_source.h"
|
||||||
|
|
||||||
|
display::GenericDialog::GenericDialog(std::string title, std::optional<std::string> action, std::string cancel) {
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
setWindowTitle(QString::fromStdString(title));
|
setWindowTitle(QMESSAGE(title));
|
||||||
|
|
||||||
setLayout(new QVBoxLayout());
|
setLayout(new QVBoxLayout());
|
||||||
content = new QWidget(this);
|
content = new QWidget(this);
|
||||||
|
@ -14,12 +16,16 @@ display::GenericDialog::GenericDialog(std::string title, std::string action) {
|
||||||
layout()->addWidget(actionWidget);
|
layout()->addWidget(actionWidget);
|
||||||
|
|
||||||
// if action isn't defined only close button is offered
|
// if action isn't defined only close button is offered
|
||||||
if(!action.empty()) {
|
if(action.has_value()) {
|
||||||
okButton = new QPushButton(QString::fromStdString(action), this);
|
okButton = new QPushButton(QMESSAGE(*action), this);
|
||||||
connect(okButton, &QPushButton::clicked, this, [this](){if(this->onUpdate()) this->accept();});
|
connect(okButton, &QPushButton::clicked, this, [this](){
|
||||||
|
if(this->onUpdate()) {
|
||||||
|
this->accept();
|
||||||
|
}
|
||||||
|
});
|
||||||
actionBar->addWidget(okButton);
|
actionBar->addWidget(okButton);
|
||||||
}
|
}
|
||||||
cancelButton = new QPushButton("Odustani", this);
|
cancelButton = new QPushButton(QMESSAGE(cancel), this);
|
||||||
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
|
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
|
||||||
actionBar->addWidget(cancelButton);
|
actionBar->addWidget(cancelButton);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,16 @@
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
class GenericDialog: public QDialog {
|
class GenericDialog: public QDialog {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GenericDialog(std::string title, std::string action = "Ažuriraj");
|
explicit GenericDialog(std::string title,
|
||||||
|
std::optional<std::string> action = "msg_dialog_actions_update",
|
||||||
|
std::string cancel = "msg_dialog_actions_cancel");
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setOkButtonDisabled(bool disabled);
|
void setOkButtonDisabled(bool disabled);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include "memory_dialog.h"
|
#include "memory_dialog.h"
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ namespace display {
|
||||||
for (const auto& entry: memoryInstances) {
|
for (const auto& entry: memoryInstances) {
|
||||||
combo->addItem(QString::fromStdString(entry));
|
combo->addItem(QString::fromStdString(entry));
|
||||||
}
|
}
|
||||||
combo->addItem("null");
|
combo->addItem(QMESSAGE("msg_dialog_memory_default"));
|
||||||
|
|
||||||
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||||
if(index == memoryInstances.size()) {
|
if(index == memoryInstances.size()) {
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "name_dialog.h"
|
#include "name_dialog.h"
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
NameDialog::NameDialog(std::string currentName, std::set<std::string> &names)
|
NameDialog::NameDialog(std::string currentName, std::set<std::string> &names)
|
||||||
: GenericDialog("Izmjeni ime", "Izmjeni"), currentName(currentName), usedNames(names) {
|
: GenericDialog("msg_dialog_name_update"), currentName(currentName), usedNames(names) {
|
||||||
|
|
||||||
usedNames.erase(currentName);
|
usedNames.erase(currentName);
|
||||||
|
|
||||||
auto *contentLayout = new QVBoxLayout();
|
auto *contentLayout = new QVBoxLayout();
|
||||||
contentLayout->addWidget(new QLabel("Izmjeni ime", this));
|
contentLayout->addWidget(new QLabel(QMESSAGE("msg_dialog_name_update"), this));
|
||||||
|
|
||||||
edit = new QLineEdit(this);
|
edit = new QLineEdit(this);
|
||||||
edit->insert(currentName.c_str());
|
edit->insert(currentName.c_str());
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include "success_dialog.h"
|
#include "success_dialog.h"
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
SuccessDialog::SuccessDialog(std::string message, std::string action) {
|
SuccessDialog::SuccessDialog(std::string message) {
|
||||||
setLayout(new QVBoxLayout());
|
setLayout(new QVBoxLayout());
|
||||||
|
setWindowTitle(QMESSAGE("msg_dialog_success_title"));
|
||||||
layout()->addWidget(new QLabel(QString::fromStdString(message)));
|
layout()->addWidget(new QLabel(QString::fromStdString(message)));
|
||||||
|
|
||||||
auto button = new QPushButton(QString::fromStdString(action));
|
auto button = new QPushButton(QMESSAGE("msg_dialog_actions_ok"));
|
||||||
connect(button, &QPushButton::clicked, [this]() {accept();});
|
connect(button, &QPushButton::clicked, [this]() {accept();});
|
||||||
layout()->addWidget(button);
|
layout()->addWidget(button);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace display {
|
||||||
|
|
||||||
class SuccessDialog: public QDialog {
|
class SuccessDialog: public QDialog {
|
||||||
public:
|
public:
|
||||||
explicit SuccessDialog(std::string message, std::string action = "Ok");
|
explicit SuccessDialog(std::string message);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // display
|
} // display
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
WarningDialog::WarningDialog(domain::ValidationError error)
|
WarningDialog::WarningDialog(domain::ValidationError error)
|
||||||
: GenericDialog("Upozorenje", "U redu") {
|
: GenericDialog("msg_dialog_warning_title", "msg_dialog_actions_ok") {
|
||||||
|
|
||||||
auto contentLayout = new QVBoxLayout();
|
auto contentLayout = new QVBoxLayout();
|
||||||
content->setLayout(contentLayout);
|
content->setLayout(contentLayout);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "library_display.h"
|
#include "library_display.h"
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QListWidget>
|
#include <QListWidget>
|
||||||
|
@ -15,16 +16,23 @@ namespace display {
|
||||||
busList = new LibraryList(this);
|
busList = new LibraryList(this);
|
||||||
|
|
||||||
layout->setContentsMargins(4, 4, 4, 4);
|
layout->setContentsMargins(4, 4, 4, 4);
|
||||||
layout->addWidget(new QLabel("Komponente:"));
|
|
||||||
|
componentsLabel = new QLabel(QMESSAGE("msg_sidebar_components"));
|
||||||
|
busLabel = new QLabel(QMESSAGE("msg_sidebar_busses"));
|
||||||
|
|
||||||
|
layout->addWidget(componentsLabel);
|
||||||
layout->addWidget(componentList, 1);
|
layout->addWidget(componentList, 1);
|
||||||
layout->addSpacing(8);
|
layout->addSpacing(8);
|
||||||
layout->addWidget(new QLabel("Sabirnice:"));
|
layout->addWidget(busLabel);
|
||||||
layout->addWidget(busList, 1);
|
layout->addWidget(busList, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Library::refreshContent() {
|
void Library::refreshContent() {
|
||||||
library = Application::instance()->getLibrary();
|
library = Application::instance()->getLibrary();
|
||||||
|
|
||||||
|
componentsLabel->setText(QMESSAGE("msg_sidebar_components"));
|
||||||
|
busLabel->setText(QMESSAGE("msg_sidebar_busses"));
|
||||||
|
|
||||||
componentList->clear();
|
componentList->clear();
|
||||||
busList->clear();
|
busList->clear();
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include <comdel/domain/library.h>
|
#include <comdel/domain/library.h>
|
||||||
|
#include <QLabel>
|
||||||
#include "library_list.h"
|
#include "library_list.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
@ -21,6 +22,8 @@ namespace display {
|
||||||
LibraryList *componentList;
|
LibraryList *componentList;
|
||||||
LibraryList *busList;
|
LibraryList *busList;
|
||||||
|
|
||||||
|
QLabel *componentsLabel;
|
||||||
|
QLabel *busLabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace display
|
} // namespace display
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include <QDrag>
|
#include <QDrag>
|
||||||
#include <QDragEnterEvent>
|
#include <QDragEnterEvent>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
|
@ -183,7 +185,7 @@ namespace display {
|
||||||
|
|
||||||
if (rect.contains(endPoint)) {
|
if (rect.contains(endPoint)) {
|
||||||
auto name = components[pinInstance.component]->getComponentInstance()->component.getName();
|
auto name = components[pinInstance.component]->getComponentInstance()->component.getName();
|
||||||
auto con = library->getConnection({instance->component.getName(), connection.pin.value().getName()},
|
auto con = library->getConnection({instance->component.getName(), context.pin->getPin().getName()},
|
||||||
{name, pinInstance.pin});
|
{name, pinInstance.pin});
|
||||||
if (con.has_value()) {
|
if (con.has_value()) {
|
||||||
auto busInstance = Application::instance()->addBus(library->getBus(con->getBus()), 0, 0);
|
auto busInstance = Application::instance()->addBus(library->getBus(con->getBus()), 0, 0);
|
||||||
|
@ -199,12 +201,22 @@ namespace display {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto conInstance = std::make_shared<domain::DirectConnectionInstance>(instance,
|
std::shared_ptr<domain::DirectConnectionInstance> conInstance = nullptr;
|
||||||
|
if(con->getComponent() == domain::ConnectionComponent{instance->component.getName(), context.pin->getPin().getName()}) {
|
||||||
|
conInstance = std::make_shared<domain::DirectConnectionInstance>(instance,
|
||||||
components[pinInstance.component]->getComponentInstance().get(),
|
components[pinInstance.component]->getComponentInstance().get(),
|
||||||
attributes, busInstance.get(),
|
attributes, busInstance.get(),
|
||||||
*con);
|
*con);
|
||||||
|
} else {
|
||||||
|
conInstance = std::make_shared<domain::DirectConnectionInstance>(components[pinInstance.component]->getComponentInstance().get(),
|
||||||
|
instance,
|
||||||
|
attributes, busInstance.get(),
|
||||||
|
*con);
|
||||||
|
}
|
||||||
|
|
||||||
schema->connections.push_back(conInstance);
|
schema->connections.push_back(conInstance);
|
||||||
|
|
||||||
|
|
||||||
if (conInstance != nullptr) {
|
if (conInstance != nullptr) {
|
||||||
auto c = new display::DirectConnection(conInstance.get(),
|
auto c = new display::DirectConnection(conInstance.get(),
|
||||||
components[conInstance->instance->name],
|
components[conInstance->instance->name],
|
||||||
|
@ -276,13 +288,14 @@ namespace display {
|
||||||
domain::InstanceAttribute attribute(attr.getName(), attr.getDefault(), attr);
|
domain::InstanceAttribute attribute(attr.getName(), attr.getDefault(), attr);
|
||||||
if(attr.getPopup().has_value() && attr.getPopup()->getType() == domain::Popup::AUTOMATIC) {
|
if(attr.getPopup().has_value() && attr.getPopup()->getType() == domain::Popup::AUTOMATIC) {
|
||||||
if(attr.getDefault().isType(domain::Value::MEMORY_REFERENCE)) {
|
if(attr.getDefault().isType(domain::Value::MEMORY_REFERENCE)) {
|
||||||
auto dialog = new MemoryDialog("Postavi memoriju", "Postavi", &attribute, schema->componentInstances);
|
auto dialog = new MemoryDialog("msg_dialog_memory_set", "msg_dialog_actions_set", &attribute, schema->componentInstances);
|
||||||
if(dialog->exec() == QDialog::Rejected) {
|
if(dialog->exec() == QDialog::Rejected) {
|
||||||
// if any dialog isn't set, whole creation is rejected
|
// if any dialog isn't set, whole creation is rejected
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto dialog = new AttributeDialog("Postavi " + attribute.attribute.getDisplayName(), "Postavi", &attribute);
|
std::map<std::string, std::string> params = {{"attribute", attribute.attribute.getDisplayName()}};
|
||||||
|
auto dialog = new AttributeDialog(MESSAGE_PARAM("msg_dialog_attribute_set", params), "msg_dialog_actions_set", &attribute);
|
||||||
if(dialog->exec() == QDialog::Rejected) {
|
if(dialog->exec() == QDialog::Rejected) {
|
||||||
// if any dialog isn't set, whole creation is rejected
|
// if any dialog isn't set, whole creation is rejected
|
||||||
return {};
|
return {};
|
||||||
|
@ -301,7 +314,7 @@ namespace display {
|
||||||
instanceAttributes.emplace_back(attr.getName(), attr.getDefault(), attr);
|
instanceAttributes.emplace_back(attr.getName(), attr.getDefault(), attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dialog = new display::SingleAutomaticDialog("Postavi sabirnicu", "Postavi", instanceAttributes);
|
auto dialog = new display::SingleAutomaticDialog("msg_dialog_sa_pin_set", "msg_dialog_actions_set", instanceAttributes);
|
||||||
if(dialog->exec() == QDialog::Rejected) {
|
if(dialog->exec() == QDialog::Rejected) {
|
||||||
// if dialog is rejected, whole creation is rejected
|
// if dialog is rejected, whole creation is rejected
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <QLayout>
|
||||||
#include "comdel_generator.h"
|
#include "comdel_generator.h"
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
@ -148,12 +149,9 @@ namespace domain {
|
||||||
for (auto &bus: schema->busInstances) {
|
for (auto &bus: schema->busInstances) {
|
||||||
buffer << "\t//" << bus->name << std::endl;
|
buffer << "\t//" << bus->name << std::endl;
|
||||||
for (auto &wire: bus->bus.getWires()) {
|
for (auto &wire: bus->bus.getWires()) {
|
||||||
std::string name = wire.getName();
|
auto name = (wire.isHidden() ? "--" : "") + wire.getName();
|
||||||
if (usedNames.count(wire.getName()) > 0) {
|
if (usedNames.count(name) > 0) {
|
||||||
name = bus->name + "__" + wire.getName();
|
name = (wire.isHidden() ? "--" : "") + bus->name + "__" + wire.getName();
|
||||||
}
|
|
||||||
if (wire.isHidden()) {
|
|
||||||
name = "--" + name;
|
|
||||||
}
|
}
|
||||||
usedNames.insert(name);
|
usedNames.insert(name);
|
||||||
usedMappings.insert(std::make_pair(bus->name + "." + wire.getName(), name));
|
usedMappings.insert(std::make_pair(bus->name + "." + wire.getName(), name));
|
||||||
|
@ -203,6 +201,9 @@ namespace domain {
|
||||||
map<string, string> &wireNames,
|
map<string, string> &wireNames,
|
||||||
stringstream &buffer);
|
stringstream &buffer);
|
||||||
|
|
||||||
|
void generateSingleAutomaticPin(std::vector<ConnectionInstance*> connections, ComponentInstance *instance, string pin,
|
||||||
|
map<string, string> &wireNames, stringstream &buffer);
|
||||||
|
|
||||||
void generateComponent(Schema *schema, map<string, string> &wires, ostream &buffer,
|
void generateComponent(Schema *schema, map<string, string> &wires, ostream &buffer,
|
||||||
shared_ptr<ComponentInstance> &component);
|
shared_ptr<ComponentInstance> &component);
|
||||||
|
|
||||||
|
@ -250,7 +251,9 @@ namespace domain {
|
||||||
|
|
||||||
for (auto &pin: component->component.getPins()) {
|
for (auto &pin: component->component.getPins()) {
|
||||||
if (schema->hasConnection(component->name, pin.getName())) {
|
if (schema->hasConnection(component->name, pin.getName())) {
|
||||||
auto conn = schema->getConnection(component->name, pin.getName());
|
auto connections = schema->getConnections(component->name, pin.getName());
|
||||||
|
if(connections.size() == 1) {
|
||||||
|
auto conn = connections[0];
|
||||||
auto busConn = dynamic_cast<BusConnectionInstance *>(conn);
|
auto busConn = dynamic_cast<BusConnectionInstance *>(conn);
|
||||||
if (busConn != nullptr) {
|
if (busConn != nullptr) {
|
||||||
for (auto wire: busConn->connection.getWires()) {
|
for (auto wire: busConn->connection.getWires()) {
|
||||||
|
@ -282,6 +285,9 @@ namespace domain {
|
||||||
generateSingleAutomaticPin(dirConn, component->name, pin.getName(), wires, tempOutput);
|
generateSingleAutomaticPin(dirConn, component->name, pin.getName(), wires, tempOutput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
generateSingleAutomaticPin(connections, component.get(), pin.getName(), wires, tempOutput);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// if no connection exists than defaults must exist
|
// if no connection exists than defaults must exist
|
||||||
for (auto &wire: *pin.getWires()) {
|
for (auto &wire: *pin.getWires()) {
|
||||||
|
@ -341,8 +347,30 @@ namespace domain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void generateSingleAutomaticPin(std::vector<ConnectionInstance*> connections, ComponentInstance *instance, string pin,
|
||||||
generateAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map<string, string> wireNames,
|
map<string, string> &wireNames, stringstream &buffer) {
|
||||||
|
std::map<int, BusInstance*> selectedValues;
|
||||||
|
for(auto conn: connections) {
|
||||||
|
auto dirConn = dynamic_cast<DirectConnectionInstance*>(conn);
|
||||||
|
auto index = dirConn->getSelected(ConnectionComponent{instance->name, pin});
|
||||||
|
selectedValues.insert(std::make_pair(index, dirConn->bus));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Value> defaultWires = instance->component.getPin(pin).getWires().value();
|
||||||
|
|
||||||
|
for (int i=0; i<defaultWires.size(); i++) {
|
||||||
|
if(selectedValues.count(i) > 0) {
|
||||||
|
auto wireName = selectedValues[i]->name + "." + selectedValues[i]->bus.getWires()[0].getName();
|
||||||
|
buffer << wireNames[wireName] << ", ";
|
||||||
|
} else if(defaultWires[i].isType(Value::NIL)) {
|
||||||
|
buffer << "*, ";
|
||||||
|
} else {
|
||||||
|
buffer << defaultWires[i].stringify() << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map<string, string> wireNames,
|
||||||
stringstream &buffer) {
|
stringstream &buffer) {
|
||||||
std::vector<Value> wires;
|
std::vector<Value> wires;
|
||||||
if (connection->instance->name == name && connection->connection.getComponent().pin == pin) {
|
if (connection->instance->name == name && connection->connection.getComponent().pin == pin) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "comdel_validator.h"
|
#include "comdel_validator.h"
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
|
@ -30,24 +31,20 @@ namespace domain {
|
||||||
for (auto comp: library.getComponents()) {
|
for (auto comp: library.getComponents()) {
|
||||||
int count = instanceMap[comp.getName()];
|
int count = instanceMap[comp.getName()];
|
||||||
|
|
||||||
context.attributes["componentName"] = Value::fromString(comp.getName());
|
context.attributes["componentName"] = Value::fromString(comp.getDisplayName());
|
||||||
context.attributes["min"] = Value::fromInt(comp.getCount().first);
|
context.attributes["min"] = Value::fromInt(comp.getCount().first);
|
||||||
context.attributes["max"] = Value::fromInt(comp.getCount().second);
|
context.attributes["max"] = Value::fromInt(comp.getCount().second);
|
||||||
context.attributes["count"] = Value::fromInt(count);
|
context.attributes["count"] = Value::fromInt(count);
|
||||||
|
|
||||||
if (count < comp.getCount().first) {
|
if (count < comp.getCount().first) {
|
||||||
auto message = populateMessage(
|
auto message = MESSAGE_PARAM("msg_validators_component_min_count", context.map());
|
||||||
"Nedovoljno instanci komponente '{componentName}' potrebno barem {min}, pronađeno {count}",
|
|
||||||
context);
|
|
||||||
errors.emplace_back(Action::ERROR, message);
|
errors.emplace_back(Action::ERROR, message);
|
||||||
} else if (count > comp.getCount().second) {
|
} else if (count > comp.getCount().second) {
|
||||||
auto message = populateMessage(
|
auto message = MESSAGE_PARAM("msg_validators_component_max_count", context.map());
|
||||||
"Previše insanci komponente '{componentName}' dozvoljeno najviše {max}, pronađeno {count}", context);
|
|
||||||
errors.emplace_back(Action::ERROR, message);
|
errors.emplace_back(Action::ERROR, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// validate bus instance count
|
// validate bus instance count
|
||||||
std::map<std::string, int> busInstanceMap;
|
std::map<std::string, int> busInstanceMap;
|
||||||
for (auto &inst: schema.busInstances) {
|
for (auto &inst: schema.busInstances) {
|
||||||
|
@ -57,18 +54,16 @@ namespace domain {
|
||||||
for (auto bus: library.getBuses()) {
|
for (auto bus: library.getBuses()) {
|
||||||
int count = busInstanceMap[bus.getName()];
|
int count = busInstanceMap[bus.getName()];
|
||||||
|
|
||||||
context.attributes["busName"] = Value::fromString(bus.getName());
|
context.attributes["busName"] = Value::fromString(bus.getDisplayName());
|
||||||
context.attributes["min"] = Value::fromInt(bus.getCount().first);
|
context.attributes["min"] = Value::fromInt(bus.getCount().first);
|
||||||
context.attributes["max"] = Value::fromInt(bus.getCount().second);
|
context.attributes["max"] = Value::fromInt(bus.getCount().second);
|
||||||
context.attributes["count"] = Value::fromInt(count);
|
context.attributes["count"] = Value::fromInt(count);
|
||||||
|
|
||||||
if (count < bus.getCount().first) {
|
if (count < bus.getCount().first) {
|
||||||
auto message = populateMessage(
|
auto message = MESSAGE_PARAM("msg_validators_bus_min_count", context.map());
|
||||||
"Nedovoljno instanci sabirnice '{busName}' potrebna barem jedna {min}, pronađeno {count}", context);
|
|
||||||
errors.emplace_back(Action::ERROR, message);
|
errors.emplace_back(Action::ERROR, message);
|
||||||
} else if (count > bus.getCount().second) {
|
} else if (count > bus.getCount().second) {
|
||||||
auto message = populateMessage(
|
auto message = MESSAGE_PARAM("msg_validators_bus_max_count", context.map());
|
||||||
"Previše instanci sabirnice '{busName}' dozvoljeno najviše {max}, pronađeno {count}", context);
|
|
||||||
errors.emplace_back(Action::ERROR, message);
|
errors.emplace_back(Action::ERROR, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,9 +80,8 @@ namespace domain {
|
||||||
if (pin.getConnection().has_value()) {
|
if (pin.getConnection().has_value()) {
|
||||||
if (!connectionExists(schema, inst, pin)) {
|
if (!connectionExists(schema, inst, pin)) {
|
||||||
context.instance = inst.get();
|
context.instance = inst.get();
|
||||||
context.attributes["instanceName"] = Value::fromString(inst->name);
|
auto message = MESSAGE_PARAM(pin.getConnection().value(), context.map());
|
||||||
auto message = populateMessage(pin.getConnection().value(), context);
|
errors.emplace_back(context.instance, nullptr, Action::ERROR, message);
|
||||||
errors.emplace_back(Action::ERROR, message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +141,7 @@ namespace domain {
|
||||||
ruleContext.function = validators;
|
ruleContext.function = validators;
|
||||||
auto action = rule.evaluate(ruleContext);
|
auto action = rule.evaluate(ruleContext);
|
||||||
if (action) {
|
if (action) {
|
||||||
std::string message = this->populateMessage(action->getMessage(), context);
|
auto message = MESSAGE_PARAM(action->getMessage(), context.map());
|
||||||
return ValidationError{context.instance, context.attribute, action->getType(), message};
|
return ValidationError{context.instance, context.attribute, action->getType(), message};
|
||||||
}
|
}
|
||||||
return nullopt;
|
return nullopt;
|
||||||
|
@ -172,7 +166,7 @@ namespace domain {
|
||||||
if(memoryReference != nullopt) {
|
if(memoryReference != nullopt) {
|
||||||
if(memoryInstances.count(*memoryReference) == 0) {
|
if(memoryInstances.count(*memoryReference) == 0) {
|
||||||
context.attributes["memoryReference"] = domain::Value::fromString(memoryReference.value());
|
context.attributes["memoryReference"] = domain::Value::fromString(memoryReference.value());
|
||||||
auto message = populateMessage("Ne postoji memorijska komponenta '{memoryReference}'", context);
|
auto message = MESSAGE_PARAM("msg_validators_memory_not_found", context.map());
|
||||||
errors.emplace_back(component.get(), nullptr, Action::ERROR, message);
|
errors.emplace_back(component.get(), nullptr, Action::ERROR, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,9 +185,8 @@ namespace domain {
|
||||||
|
|
||||||
for(auto& component: schema.componentInstances) {
|
for(auto& component: schema.componentInstances) {
|
||||||
if(names.find(component->name) != names.end()) {
|
if(names.find(component->name) != names.end()) {
|
||||||
context.attributes["componentName"] = Value::fromString(component->name);
|
context.instance = component.get();
|
||||||
auto message = populateMessage(
|
auto message = MESSAGE_PARAM("msg_validators_duplicates_found", context.map());
|
||||||
"Pronađeno više instanci sa imenom '{componentName}'", context);
|
|
||||||
errors.emplace_back(Action::ERROR, message);
|
errors.emplace_back(Action::ERROR, message);
|
||||||
}
|
}
|
||||||
names.insert(component->name);
|
names.insert(component->name);
|
||||||
|
@ -201,26 +194,6 @@ namespace domain {
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string ComdelValidator::populateMessage(string source, ValidationContext context) {
|
|
||||||
for (auto &[key, value]: context.attributes) {
|
|
||||||
source = replacePlaceholder(source, key, value);
|
|
||||||
}
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
string ComdelValidator::replacePlaceholder(string source, string key, Value value) {
|
|
||||||
key = "{" + key + "}";
|
|
||||||
auto placeholderValue = value.string();
|
|
||||||
|
|
||||||
auto found = source.find(key);
|
|
||||||
while (found != string::npos) {
|
|
||||||
source.replace(found, key.length(), placeholderValue);
|
|
||||||
found = source.find(key);
|
|
||||||
}
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ComdelValidator::connectionExists(Schema &schema, shared_ptr<ComponentInstance> &component, Pin &pin) {
|
bool ComdelValidator::connectionExists(Schema &schema, shared_ptr<ComponentInstance> &component, Pin &pin) {
|
||||||
for (auto conn: schema.connections) {
|
for (auto conn: schema.connections) {
|
||||||
auto busConnection = dynamic_cast<BusConnectionInstance *>(conn.get());
|
auto busConnection = dynamic_cast<BusConnectionInstance *>(conn.get());
|
||||||
|
@ -233,13 +206,9 @@ namespace domain {
|
||||||
|
|
||||||
auto directConnection = dynamic_cast<DirectConnectionInstance *>(conn.get());
|
auto directConnection = dynamic_cast<DirectConnectionInstance *>(conn.get());
|
||||||
if (directConnection != nullptr) {
|
if (directConnection != nullptr) {
|
||||||
if (directConnection->instance->name == component->name &&
|
if ((directConnection->instance->name == component->name && directConnection->connection.getComponent().pin == pin.getName()) ||
|
||||||
directConnection->connection.getComponent().pin == pin.getName()) {
|
(directConnection->secondInstance->name == component->name) && directConnection->connection.getSecondComponent()->pin == pin.getName()) {
|
||||||
return true;
|
return directConnection->connection.isConnecting({component->component.getName(), pin.getName()});
|
||||||
}
|
|
||||||
if (directConnection->secondInstance->name == component->name &&
|
|
||||||
directConnection->connection.getSecondComponent()->pin == pin.getName()) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,4 +221,20 @@ namespace domain {
|
||||||
this->validators.insert(std::make_pair(validator->getName(), validator));
|
this->validators.insert(std::make_pair(validator->getName(), validator));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> ValidationContext::map() {
|
||||||
|
std::map<std::string, std::string> parametars;
|
||||||
|
if(instance != nullptr) {
|
||||||
|
parametars["instanceName"] = instance->name;
|
||||||
|
parametars["componentName"] = instance->component.getDisplayName();
|
||||||
|
}
|
||||||
|
if(attribute != nullptr) {
|
||||||
|
parametars["attributeName"] = attribute->name;
|
||||||
|
parametars["attribute"] = attribute->value.string();
|
||||||
|
}
|
||||||
|
for(auto [key, value]: attributes) {
|
||||||
|
parametars[key] = value.string();
|
||||||
|
}
|
||||||
|
return parametars;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -23,6 +23,8 @@ namespace domain {
|
||||||
InstanceAttribute *attribute;
|
InstanceAttribute *attribute;
|
||||||
std::map<std::string, AddressSpace> addressSpaces;
|
std::map<std::string, AddressSpace> addressSpaces;
|
||||||
std::map<std::string, Value> attributes;
|
std::map<std::string, Value> attributes;
|
||||||
|
|
||||||
|
std::map<std::string, std::string> map();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComdelValidator {
|
class ComdelValidator {
|
||||||
|
@ -41,18 +43,13 @@ namespace domain {
|
||||||
|
|
||||||
std::vector<ValidationError> validateInstanceCount(Schema &schema, Library &library, ValidationContext context);
|
std::vector<ValidationError> validateInstanceCount(Schema &schema, Library &library, ValidationContext context);
|
||||||
|
|
||||||
std::vector<ValidationError>
|
std::vector<ValidationError> validatePinConnections(Schema &schema, Library &library, ValidationContext context);
|
||||||
validatePinConnections(Schema &schema, Library &library, ValidationContext context);
|
|
||||||
|
|
||||||
ComdelValidator(std::vector<FunctionValidator *> validators);
|
ComdelValidator(std::vector<FunctionValidator *> validators);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, FunctionValidator *> validators;
|
std::map<std::string, FunctionValidator *> validators;
|
||||||
|
|
||||||
std::string populateMessage(string message, ValidationContext context);
|
|
||||||
|
|
||||||
string replacePlaceholder(string message, const string name, Value value);
|
|
||||||
|
|
||||||
bool connectionExists(Schema &schema, shared_ptr<ComponentInstance> &component, Pin &pin);
|
bool connectionExists(Schema &schema, shared_ptr<ComponentInstance> &component, Pin &pin);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,4 +26,23 @@ namespace domain {
|
||||||
Connection connection)
|
Connection connection)
|
||||||
: ConnectionInstance(instance, attributes, connection), secondInstance(secondInstance), bus(bus) {}
|
: ConnectionInstance(instance, attributes, connection), secondInstance(secondInstance), bus(bus) {}
|
||||||
|
|
||||||
|
int DirectConnectionInstance::getSelected(ConnectionComponent conn) {
|
||||||
|
if(this->instance->name == conn.component) {
|
||||||
|
auto selected = attributes[0].value.asString();
|
||||||
|
for(int i=0; i<connection.getWires().size(); i++) {
|
||||||
|
if(connection.getWires()[i].isType(Value::STRING) && connection.getWires()[i].asString() == selected) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto selected = attributes[1].value.asString();
|
||||||
|
for(int i=0; i<connection.getSecondWires()->size(); i++) {
|
||||||
|
if(connection.getSecondWires().value()[i].isType(Value::STRING) && connection.getSecondWires().value()[i].asString() == selected) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -41,6 +41,8 @@ namespace domain {
|
||||||
|
|
||||||
DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondsInstance,
|
DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondsInstance,
|
||||||
std::vector<InstanceAttribute> attributes, BusInstance *bus, Connection connection);
|
std::vector<InstanceAttribute> attributes, BusInstance *bus, Connection connection);
|
||||||
|
|
||||||
|
int getSelected(ConnectionComponent connection);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,21 @@ namespace domain {
|
||||||
buffer << "\t\t}\n\n";
|
buffer << "\t\t}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ui::Ellipse::render(QGraphicsItemGroup *group) {
|
||||||
|
auto ellipse = new QGraphicsEllipseItem(x, y, w, h);
|
||||||
|
ellipse->setPen(QPen(config.lineColor));
|
||||||
|
ellipse->setBrush(QBrush(config.fillColor));
|
||||||
|
group->addToGroup(ellipse);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Ellipse::comdel(std::ostream &buffer, int x, int y) {
|
||||||
|
buffer << "\t\tellipse {\n";
|
||||||
|
buffer << "\t\t\tx: " << (this->x + x) << "; y: " << (this->y + y) << ";\n";
|
||||||
|
buffer << "\t\t\tw: " << w << "; h: " << h << ";\n";
|
||||||
|
buffer << "\t\t}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ui::Line::render(QGraphicsItemGroup *group) {
|
void ui::Line::render(QGraphicsItemGroup *group) {
|
||||||
auto line = new QGraphicsLineItem(x1, y1, x2, y2);
|
auto line = new QGraphicsLineItem(x1, y1, x2, y2);
|
||||||
line->setPen(QPen(config.lineColor));
|
line->setPen(QPen(config.lineColor));
|
||||||
|
@ -205,6 +220,7 @@ namespace domain {
|
||||||
if (pin) pin->render(group);
|
if (pin) pin->render(group);
|
||||||
if (bus) bus->render(group, size);
|
if (bus) bus->render(group, size);
|
||||||
if (text) text->render(group, context);
|
if (text) text->render(group, context);
|
||||||
|
if (ellipse) ellipse->render(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui::Item::comdel(std::ostream &buffer, int x, int y, int size) {
|
void ui::Item::comdel(std::ostream &buffer, int x, int y, int size) {
|
||||||
|
|
|
@ -58,6 +58,19 @@ namespace domain {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Ellipse {
|
||||||
|
public:
|
||||||
|
int x, y, w, h;
|
||||||
|
DisplayConfig config;
|
||||||
|
|
||||||
|
Ellipse(int x, int y, int w, int h, DisplayConfig config) : x(x), y(y), w(w), h(h), config(config) {}
|
||||||
|
|
||||||
|
void render(QGraphicsItemGroup *group);
|
||||||
|
|
||||||
|
void comdel(std::ostream &buffer, int x, int y);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class Line {
|
class Line {
|
||||||
public:
|
public:
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
|
@ -108,6 +121,8 @@ namespace domain {
|
||||||
Pin(int x, int y, int w, int h, PinOrientation orientation, PinType pinType, DisplayConfig config)
|
Pin(int x, int y, int w, int h, PinOrientation orientation, PinType pinType, DisplayConfig config)
|
||||||
: x(x), y(y), w(w), h(h), orientation(orientation), pinType(pinType), config(config) {}
|
: x(x), y(y), w(w), h(h), orientation(orientation), pinType(pinType), config(config) {}
|
||||||
|
|
||||||
|
Pin(): config(DisplayConfig(Color(), Color())) {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void render(QGraphicsItemGroup *group);
|
void render(QGraphicsItemGroup *group);
|
||||||
|
|
||||||
|
@ -130,6 +145,7 @@ namespace domain {
|
||||||
std::optional<Pin> pin = std::nullopt;
|
std::optional<Pin> pin = std::nullopt;
|
||||||
std::optional<Bus> bus = std::nullopt;
|
std::optional<Bus> bus = std::nullopt;
|
||||||
std::optional<Text> text = std::nullopt;
|
std::optional<Text> text = std::nullopt;
|
||||||
|
std::optional<Ellipse> ellipse = std::nullopt;
|
||||||
|
|
||||||
void render(QGraphicsItemGroup *group, ui::DisplayContext context, int size = 0);
|
void render(QGraphicsItemGroup *group, ui::DisplayContext context, int size = 0);
|
||||||
void comdel(std::ostream &buffer, int x, int y, int size = 0);
|
void comdel(std::ostream &buffer, int x, int y, int size = 0);
|
||||||
|
|
|
@ -57,12 +57,10 @@ namespace domain {
|
||||||
ConnectionComponent connectionComponent{instance->component.getName(), pinName};
|
ConnectionComponent connectionComponent{instance->component.getName(), pinName};
|
||||||
for(auto &conn: library.getConnections()) {
|
for(auto &conn: library.getConnections()) {
|
||||||
if(conn.isConnecting(connectionComponent)) {
|
if(conn.isConnecting(connectionComponent)) {
|
||||||
// if bus connection
|
|
||||||
if(library.getBus(conn.getBus()).getType() == Bus::REGULAR) {
|
if(library.getBus(conn.getBus()).getType() == Bus::REGULAR) {
|
||||||
for(auto& bus: busInstances) {
|
for(auto& bus: busInstances) {
|
||||||
if(bus->bus.getName() == conn.getBus()) {
|
if(bus->bus.getName() == conn.getBus()) {
|
||||||
ConnectionEntry entry{ConnectionEntry::BUS, bus.get(), nullopt, nullopt, conn};
|
entries.push_back({ConnectionEntry::BUS, bus.get(), nullopt, nullopt, conn});
|
||||||
entries.emplace_back(entry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,19 +90,16 @@ namespace domain {
|
||||||
for(auto& conn: this->connections) {
|
for(auto& conn: this->connections) {
|
||||||
if(conn->connection == entry.connection) {
|
if(conn->connection == entry.connection) {
|
||||||
if(bus.getType() == Bus::REGULAR) {
|
if(bus.getType() == Bus::REGULAR) {
|
||||||
if(entry.busInstance.value()->bus.getName() == conn->connection.getBus()) {
|
auto busConnection = dynamic_cast<BusConnectionInstance*>(conn.get());
|
||||||
|
if(busConnection->instance == instance && busConnection->bus == entry.busInstance.value()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto *directInstance = dynamic_cast<DirectConnectionInstance*>(conn.get());
|
auto directConnection = dynamic_cast<DirectConnectionInstance*>(conn.get());
|
||||||
ComponentInstance* secondInstance;
|
if(directConnection->instance == instance && directConnection->secondInstance == entry.componentInstance.value() ||
|
||||||
if(directInstance->instance == instance) {
|
directConnection->secondInstance == instance && directConnection->instance == entry.componentInstance.value()) {
|
||||||
secondInstance = directInstance->secondInstance;
|
return true;
|
||||||
} else {
|
|
||||||
secondInstance = directInstance->instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry.componentInstance == secondInstance;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,8 +108,8 @@ namespace domain {
|
||||||
entries.end()
|
entries.end()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entries;
|
return entries;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -345,10 +345,12 @@ namespace domain {
|
||||||
|
|
||||||
if (!node.second.has_value()) {
|
if (!node.second.has_value()) {
|
||||||
errors.emplace_back(node.span, "missing second component");
|
errors.emplace_back(node.span, "missing second component");
|
||||||
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionComponent second{node.second->component.value, node.second->pin.value};
|
ConnectionComponent second{node.second->component.value, node.second->pin.value};
|
||||||
|
|
||||||
|
|
||||||
auto firstComponentInstance = getComponentPin(first.component, first.pin);
|
auto firstComponentInstance = getComponentPin(first.component, first.pin);
|
||||||
if (!firstComponentInstance) {
|
if (!firstComponentInstance) {
|
||||||
errors.emplace_back(node.span, "pin does not exist");
|
errors.emplace_back(node.span, "pin does not exist");
|
||||||
|
@ -405,7 +407,10 @@ namespace domain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(node.secondWires->empty()) {
|
||||||
|
errors.emplace_back(node.span, "missing second @wires definition");
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
std::vector<Value> secondWires;
|
std::vector<Value> secondWires;
|
||||||
for (auto &secondWire: *node.secondWires) {
|
for (auto &secondWire: *node.secondWires) {
|
||||||
if (secondWire.is(ValueNode::NIL)) {
|
if (secondWire.is(ValueNode::NIL)) {
|
||||||
|
@ -654,6 +659,13 @@ namespace domain {
|
||||||
h = readInt(errors, item, "h");
|
h = readInt(errors, item, "h");
|
||||||
text = readString(errors, item, "text");
|
text = readString(errors, item, "text");
|
||||||
displayItem.text = ui::Text(x, y, w, h, text, color);
|
displayItem.text = ui::Text(x, y, w, h, text, color);
|
||||||
|
} else if (type == "ellipse") {
|
||||||
|
long long int x, y, w, h;
|
||||||
|
x = readInt(errors, item, "x");
|
||||||
|
y = readInt(errors, item, "y");
|
||||||
|
w = readInt(errors, item, "w");
|
||||||
|
h = readInt(errors, item, "h");
|
||||||
|
displayItem.ellipse = ui::Ellipse(x, y, w, h, {lineColor, fillColor});
|
||||||
} else if (type == "rect") {
|
} else if (type == "rect") {
|
||||||
long long int x, y, w, h;
|
long long int x, y, w, h;
|
||||||
x = readInt(errors, item, "x");
|
x = readInt(errors, item, "x");
|
||||||
|
|
|
@ -92,30 +92,34 @@ namespace domain {
|
||||||
void Value::setInt(long long value) {
|
void Value::setInt(long long value) {
|
||||||
if (isType(Value::INT)) {
|
if (isType(Value::INT)) {
|
||||||
this->intValue = value;
|
this->intValue = value;
|
||||||
}
|
} else {
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Value::setString(std::string value) {
|
void Value::setString(std::string value) {
|
||||||
if (isType(Value::STRING)) {
|
if (isType(Value::STRING)) {
|
||||||
this->stringValue = value;
|
this->stringValue = value;
|
||||||
}
|
} else {
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Value::setBool(bool value) {
|
void Value::setBool(bool value) {
|
||||||
if (isType(Value::BOOL)) {
|
if (isType(Value::BOOL)) {
|
||||||
this->boolValue = value;
|
this->boolValue = value;
|
||||||
}
|
} else {
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Value::setReference(std::string value) {
|
void Value::setReference(std::string value) {
|
||||||
if (isType(Value::WIRE_REFERENCE)) {
|
if (isType(Value::WIRE_REFERENCE)) {
|
||||||
this->reference = value;
|
this->reference = value;
|
||||||
}
|
} else {
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Value Value::fromInt(long long value) {
|
Value Value::fromInt(long long value) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,233 @@
|
||||||
|
@source "arm_library.csl"
|
||||||
|
|
||||||
|
@schema {
|
||||||
|
@instance bridge Bridge {
|
||||||
|
@position (-263, -97)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance arm ARM7tdmi {
|
||||||
|
@position (-473, -283)
|
||||||
|
@attribute _memory memorija
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance memorija Memory64KiB {
|
||||||
|
@position (-545, 37)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance decoder Decoder {
|
||||||
|
@position (-541, -212)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance rtc RTC_IO {
|
||||||
|
@position (-63, -190)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio GPIO {
|
||||||
|
@position (32, 11)
|
||||||
|
@attribute title "GPIO 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance temperature Temperature {
|
||||||
|
@position (144, -25)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance led LED {
|
||||||
|
@position (159, 138)
|
||||||
|
@attribute onColor "green"
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance led_000 LED {
|
||||||
|
@position (182, 139)
|
||||||
|
@attribute onColor "yellow"
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance led_001 LED {
|
||||||
|
@position (202, 140)
|
||||||
|
@attribute onColor "red"
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance interruptSelector interrupt_selector {
|
||||||
|
@position (-235, -134)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance signal signal {
|
||||||
|
@position (63, -44)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance interruptSelector_000 interrupt_selector {
|
||||||
|
@position (-238, -160)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance lcd lcd8 {
|
||||||
|
@position (181, -199)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_000 GPIO {
|
||||||
|
@position (53, -222)
|
||||||
|
@attribute title "GPIO 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance push_button pushbutton {
|
||||||
|
@position (260, -98)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance toggle_button togglebutton {
|
||||||
|
@position (205, -70)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance dmac DMAC_simple {
|
||||||
|
@position (-445, 12)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance ui_unit UI_UNIT {
|
||||||
|
@position (-200, 24)
|
||||||
|
@attribute type 0
|
||||||
|
@attribute name "Izlaz"
|
||||||
|
@attribute width 8
|
||||||
|
@attribute duration 40
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance ui_unit_000 UI_UNIT {
|
||||||
|
@position (-118, 63)
|
||||||
|
@attribute type 1
|
||||||
|
@attribute name "Ulaz"
|
||||||
|
@attribute width 8
|
||||||
|
@attribute duration 40
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance ahb AHB {
|
||||||
|
@position (-514, -86)
|
||||||
|
@size 249
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance apb APB {
|
||||||
|
@position (-201, -87)
|
||||||
|
@size 329
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_port gpio_port {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_port_000 gpio_port {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_sa gpio_sa {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_sa_000 gpio_sa {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_sa_001 gpio_sa {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_sa_002 gpio_sa {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_port_001 gpio_port {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_sa_003 gpio_sa {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance gpio_sa_004 gpio_sa {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance arm_dmac dmac_io {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance arm_dmac_000 dmac_io {
|
||||||
|
@position (0, 0)
|
||||||
|
@size -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@connection (bridge.ahbPin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (bridge.apbPin, apb) {
|
||||||
|
}
|
||||||
|
@connection (memorija.ahbPin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (arm.ahbPin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (decoder.ahbPin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (rtc.apbPin, apb) {
|
||||||
|
}
|
||||||
|
@connection (gpio.apbPin, apb) {
|
||||||
|
@attribute gpioSelect sel_gpio_1
|
||||||
|
}
|
||||||
|
@connection (gpio.portA, gpio_port_000, temperature.gpioPin) {
|
||||||
|
}
|
||||||
|
@connection (gpio.portB, gpio_sa, led.gpioPin) {
|
||||||
|
@attribute gpioPortB "XP0"
|
||||||
|
@attribute ledGpioPin "Ulaz"
|
||||||
|
}
|
||||||
|
@connection (gpio.portB, gpio_sa_000, led_000.gpioPin) {
|
||||||
|
@attribute gpioPortB "XP4"
|
||||||
|
@attribute ledGpioPin "Ulaz"
|
||||||
|
}
|
||||||
|
@connection (gpio.portB, gpio_sa_001, led_001.gpioPin) {
|
||||||
|
@attribute gpioPortB "XP6"
|
||||||
|
@attribute ledGpioPin "Ulaz"
|
||||||
|
}
|
||||||
|
@connection (interruptSelector.ahbPin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (interruptSelector.apbPin, apb) {
|
||||||
|
@attribute interrupt rtc_int
|
||||||
|
}
|
||||||
|
@connection (signal.apbPin, apb) {
|
||||||
|
}
|
||||||
|
@connection (interruptSelector_000.ahbPin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (interruptSelector_000.apbPin, apb) {
|
||||||
|
@attribute interrupt dmac_int
|
||||||
|
}
|
||||||
|
@connection (gpio_000.apbPin, apb) {
|
||||||
|
@attribute gpioSelect sel_gpio_2
|
||||||
|
}
|
||||||
|
@connection (gpio_000.portA, gpio_port_001, lcd.gpioPin) {
|
||||||
|
}
|
||||||
|
@connection (gpio_000.portB, gpio_sa_003, push_button.gpioPin) {
|
||||||
|
@attribute gpioPortB "XP0"
|
||||||
|
@attribute buttonGpioPin "Izlaz"
|
||||||
|
}
|
||||||
|
@connection (gpio_000.portB, gpio_sa_004, toggle_button.gpioPin) {
|
||||||
|
@attribute gpioPortB "XP1"
|
||||||
|
@attribute buttonGpioPin "Izlaz"
|
||||||
|
}
|
||||||
|
@connection (dmac.apbPin, apb) {
|
||||||
|
}
|
||||||
|
@connection (dmac.ahbMasterPin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (dmac.ahbSlavePin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (ui_unit_000.dmacPin, arm_dmac, dmac.dev3) {
|
||||||
|
}
|
||||||
|
@connection (ui_unit.dmacPin, arm_dmac_000, dmac.dev2) {
|
||||||
|
}
|
||||||
|
@connection (ui_unit.apbPin, apb) {
|
||||||
|
@attribute intSelect sel_ui_in
|
||||||
|
}
|
||||||
|
@connection (ui_unit_000.apbPin, apb) {
|
||||||
|
@attribute intSelect sel_ui_out
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,248 @@
|
||||||
|
|
||||||
|
\\ Version 0.0.1
|
||||||
|
set load_performs_init;
|
||||||
|
|
||||||
|
#include ".\arm7tdmi.comdel"
|
||||||
|
#include ".\bridge.comdel"
|
||||||
|
#include ".\decoder.comdel"
|
||||||
|
#include ".\dmac.comdel"
|
||||||
|
#include ".\gpio.comdel"
|
||||||
|
#include ".\interrupt_selector.comdel"
|
||||||
|
#include ".\lcd8.comdel"
|
||||||
|
#include ".\led.comdel"
|
||||||
|
#include ".\memory.comdel"
|
||||||
|
#include ".\pushbutton.comdel"
|
||||||
|
#include ".\rtc.comdel"
|
||||||
|
#include ".\signal.comdel"
|
||||||
|
#include ".\temperature.comdel"
|
||||||
|
#include ".\togglebutton.comdel"
|
||||||
|
#include ".\ui_unit.comdel"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
component System
|
||||||
|
{
|
||||||
|
clock 100MHz;
|
||||||
|
//ahb
|
||||||
|
wire<32> addr;
|
||||||
|
wire<32> rdata;
|
||||||
|
wire<32> wdata;
|
||||||
|
wire<3> size;
|
||||||
|
wire write;
|
||||||
|
wired_or ready;
|
||||||
|
wired_or irq;
|
||||||
|
wired_or fiq;
|
||||||
|
wired_and nmreq;
|
||||||
|
wire --sel_mem;
|
||||||
|
wire sel_bridge;
|
||||||
|
wire sel_dmac;
|
||||||
|
wire busreq;
|
||||||
|
wire grant;
|
||||||
|
|
||||||
|
|
||||||
|
//apb
|
||||||
|
wire<32> apb__addr;
|
||||||
|
wire<32> apb__rdata;
|
||||||
|
wire<32> apb__wdata;
|
||||||
|
wire<3> --size;
|
||||||
|
wire enable;
|
||||||
|
wire apb__write;
|
||||||
|
wire sel_gpio_1;
|
||||||
|
wire sel_gpio_2;
|
||||||
|
wire sel_ui_in;
|
||||||
|
wire sel_rtc;
|
||||||
|
wire sel_ui_out;
|
||||||
|
wire --rtc_int;
|
||||||
|
wire --dmac_int;
|
||||||
|
wire --impulse;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_port
|
||||||
|
wire --xp0;
|
||||||
|
wire --xp1;
|
||||||
|
wire --xp2;
|
||||||
|
wire --xp3;
|
||||||
|
wire --xp4;
|
||||||
|
wire --xp5;
|
||||||
|
wire --xp6;
|
||||||
|
wire --xp7;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_port_000
|
||||||
|
wire --gpio_port_000__xp0;
|
||||||
|
wire --gpio_port_000__xp1;
|
||||||
|
wire --gpio_port_000__xp2;
|
||||||
|
wire --gpio_port_000__xp3;
|
||||||
|
wire --gpio_port_000__xp4;
|
||||||
|
wire --gpio_port_000__xp5;
|
||||||
|
wire --gpio_port_000__xp6;
|
||||||
|
wire --gpio_port_000__xp7;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_sa
|
||||||
|
wire --xp;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_sa_000
|
||||||
|
wire --gpio_sa_000__xp;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_sa_001
|
||||||
|
wire --gpio_sa_001__xp;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_sa_002
|
||||||
|
wire --gpio_sa_002__xp;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_port_001
|
||||||
|
wire --gpio_port_001__xp0;
|
||||||
|
wire --gpio_port_001__xp1;
|
||||||
|
wire --gpio_port_001__xp2;
|
||||||
|
wire --gpio_port_001__xp3;
|
||||||
|
wire --gpio_port_001__xp4;
|
||||||
|
wire --gpio_port_001__xp5;
|
||||||
|
wire --gpio_port_001__xp6;
|
||||||
|
wire --gpio_port_001__xp7;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_sa_003
|
||||||
|
wire --gpio_sa_003__xp;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_sa_004
|
||||||
|
wire --gpio_sa_004__xp;
|
||||||
|
|
||||||
|
|
||||||
|
//arm_dmac
|
||||||
|
wire --dmareq;
|
||||||
|
wire --dmaack;
|
||||||
|
|
||||||
|
|
||||||
|
//arm_dmac_000
|
||||||
|
wire --arm_dmac_000__dmareq;
|
||||||
|
wire --arm_dmac_000__dmaack;
|
||||||
|
|
||||||
|
|
||||||
|
// components --------------------------------------------
|
||||||
|
subcomponent Memory64KiB memorija(addr, rdata, wdata, size, write, ready, --sel_mem);
|
||||||
|
subcomponent Bridge bridge(addr, rdata, wdata, size, write, ready, sel_bridge, apb__addr, apb__rdata, apb__wdata, --size, enable, apb__write, sel_gpio_1, sel_gpio_2, sel_rtc, sel_ui_in, sel_ui_out, 1, 1, 1, 1, 1);
|
||||||
|
subcomponent ARM7tdmi arm(addr, rdata, wdata, size, write, ready, irq, fiq, nmreq, busreq, grant, *, *) uses memorija;
|
||||||
|
subcomponent Decoder decoder(addr, nmreq, --sel_mem, sel_bridge, sel_dmac, 1, 1);
|
||||||
|
subcomponent RTC_IO rtc(apb__addr, apb__rdata, apb__wdata, --size, enable, apb__write, sel_rtc, --rtc_int, --impulse);
|
||||||
|
subcomponent GPIO gpio<"GPIO 1">(apb__addr, apb__rdata, apb__wdata, enable, apb__write, sel_gpio_1, --gpio_port_000__xp0, --gpio_port_000__xp1, --gpio_port_000__xp2, --gpio_port_000__xp3, --gpio_port_000__xp4, --gpio_port_000__xp5, --gpio_port_000__xp6, --gpio_port_000__xp7, --xp, *, *, *, --gpio_sa_000__xp, *, --gpio_sa_001__xp, *);
|
||||||
|
subcomponent Temperature temperature(--gpio_port_000__xp0, --gpio_port_000__xp1, --gpio_port_000__xp2, --gpio_port_000__xp3, --gpio_port_000__xp4, --gpio_port_000__xp5, --gpio_port_000__xp6, --gpio_port_000__xp7);
|
||||||
|
subcomponent LED led<"green">(--xp);
|
||||||
|
subcomponent LED led_000<"yellow">(--gpio_sa_000__xp);
|
||||||
|
subcomponent LED led_001<"red">(--gpio_sa_001__xp);
|
||||||
|
subcomponent interrupt_selector interruptSelector(rtc_int, irq, fiq);
|
||||||
|
subcomponent signal signal(--impulse);
|
||||||
|
subcomponent interrupt_selector interruptSelector_000(dmac_int, irq, fiq);
|
||||||
|
subcomponent lcd8 lcd(--gpio_port_001__xp0, --gpio_port_001__xp1, --gpio_port_001__xp2, --gpio_port_001__xp3, --gpio_port_001__xp4, --gpio_port_001__xp5, --gpio_port_001__xp6, --gpio_port_001__xp7);
|
||||||
|
subcomponent GPIO gpio_000<"GPIO 2">(apb__addr, apb__rdata, apb__wdata, enable, apb__write, sel_gpio_2, --gpio_port_001__xp0, --gpio_port_001__xp1, --gpio_port_001__xp2, --gpio_port_001__xp3, --gpio_port_001__xp4, --gpio_port_001__xp5, --gpio_port_001__xp6, --gpio_port_001__xp7, --gpio_sa_003__xp, --gpio_sa_004__xp, *, *, *, *, *, *);
|
||||||
|
subcomponent pushbutton push_button(--gpio_sa_003__xp);
|
||||||
|
subcomponent togglebutton toggle_button(--gpio_sa_004__xp);
|
||||||
|
subcomponent DMAC_simple dmac(addr, rdata, wdata, size, write, ready, sel_dmac, addr, rdata, wdata, size, write, ready, nmreq, busreq, grant, --dmac_int, 0, *, 0, *, --arm_dmac_000__dmareq, --arm_dmac_000__dmaack, --dmareq, --dmaack);
|
||||||
|
subcomponent UI_UNIT ui_unit<0, "Izlaz", 8, 40>(apb__addr, apb__rdata, apb__wdata, --size, enable, apb__write, sel_ui_in, --arm_dmac_000__dmareq, --arm_dmac_000__dmaack);
|
||||||
|
subcomponent UI_UNIT ui_unit_000<1, "Ulaz", 8, 40>(apb__addr, apb__rdata, apb__wdata, --size, enable, apb__write, sel_ui_out, --dmareq, --dmaack);
|
||||||
|
|
||||||
|
display {
|
||||||
|
component { x: -263; y: -97; ref: "bridge"; }
|
||||||
|
component { x: -473; y: -283; ref: "arm"; }
|
||||||
|
component { x: -545; y: 37; ref: "memorija"; }
|
||||||
|
component { x: -541; y: -212; ref: "decoder"; }
|
||||||
|
component { x: -63; y: -190; ref: "rtc"; }
|
||||||
|
component { x: 32; y: 11; ref: "gpio"; }
|
||||||
|
component { x: 144; y: -25; ref: "temperature"; }
|
||||||
|
component { x: 159; y: 138; ref: "led"; }
|
||||||
|
component { x: 182; y: 139; ref: "led_000"; }
|
||||||
|
component { x: 202; y: 140; ref: "led_001"; }
|
||||||
|
component { x: -235; y: -134; ref: "interruptSelector"; }
|
||||||
|
component { x: 63; y: -44; ref: "signal"; }
|
||||||
|
component { x: -238; y: -160; ref: "interruptSelector_000"; }
|
||||||
|
component { x: 181; y: -199; ref: "lcd"; }
|
||||||
|
component { x: 53; y: -222; ref: "gpio_000"; }
|
||||||
|
component { x: 260; y: -98; ref: "push_button"; }
|
||||||
|
component { x: 205; y: -70; ref: "toggle_button"; }
|
||||||
|
component { x: -445; y: 12; ref: "dmac"; }
|
||||||
|
component { x: -189; y: 25; ref: "ui_unit"; }
|
||||||
|
component { x: -118; y: 63; ref: "ui_unit_000"; }
|
||||||
|
|
||||||
|
// ahb bus
|
||||||
|
|
||||||
|
rectangle {
|
||||||
|
x: -514; y: -86;
|
||||||
|
w: 249; h: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// apb bus
|
||||||
|
|
||||||
|
rectangle {
|
||||||
|
x: -201; y: -87;
|
||||||
|
w: 329; h: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_port bus
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_port_000 bus
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_sa bus
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_sa_000 bus
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_sa_001 bus
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_sa_002 bus
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_port_001 bus
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_sa_003 bus
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_sa_004 bus
|
||||||
|
|
||||||
|
|
||||||
|
// arm_dmac bus
|
||||||
|
|
||||||
|
|
||||||
|
// arm_dmac_000 bus
|
||||||
|
|
||||||
|
|
||||||
|
line {x1:-263; y1:-77; x2:-389; y2:-75;}
|
||||||
|
line {x1:-203; y1:-77; x2:-36; y2:-76;}
|
||||||
|
line {x1:-540; y1:37; x2:-389; y2:-75;}
|
||||||
|
line {x1:-418; y1:-152; x2:-389; y2:-75;}
|
||||||
|
line {x1:-521; y1:-182; x2:-389; y2:-75;}
|
||||||
|
line {x1:-43; y1:-150; x2:-36; y2:-76;}
|
||||||
|
line {x1:32; y1:56; x2:-36; y2:-76;}
|
||||||
|
line {x1:112; y1:32; x2:164; y2:15;}
|
||||||
|
line {x1:112; y1:91; x2:164; y2:138;}
|
||||||
|
line {x1:112; y1:91; x2:187; y2:139;}
|
||||||
|
line {x1:112; y1:91; x2:207; y2:140;}
|
||||||
|
line {x1:-245; y1:-129; x2:-389; y2:-75;}
|
||||||
|
line {x1:-215; y1:-129; x2:-36; y2:-76;}
|
||||||
|
line {x1:68; y1:-44; x2:-36; y2:-76;}
|
||||||
|
line {x1:-248; y1:-155; x2:-389; y2:-75;}
|
||||||
|
line {x1:-218; y1:-155; x2:-36; y2:-76;}
|
||||||
|
line {x1:53; y1:-177; x2:-36; y2:-76;}
|
||||||
|
line {x1:133; y1:-201; x2:171; y2:-172;}
|
||||||
|
line {x1:133; y1:-142; x2:277; y2:-108;}
|
||||||
|
line {x1:133; y1:-142; x2:222; y2:-80;}
|
||||||
|
line {x1:-340; y1:32; x2:-36; y2:-76;}
|
||||||
|
line {x1:-370; y1:12; x2:-389; y2:-75;}
|
||||||
|
line {x1:-410; y1:12; x2:-389; y2:-75;}
|
||||||
|
line {x1:-118; y1:93; x2:-325; y2:92;}
|
||||||
|
line {x1:-189; y1:55; x2:-325; y2:77;}
|
||||||
|
line {x1:-159; y1:25; x2:-36; y2:-76;}
|
||||||
|
line {x1:-88; y1:63; x2:-36; y2:-76;}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
\\ Version 0.0.1
|
||||||
|
set load_performs_init;
|
||||||
|
|
||||||
|
#include ".\arm7tdmi.comdel"
|
||||||
|
#include ".\decoder.comdel"
|
||||||
|
#include ".\memory.comdel"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
component System
|
||||||
|
{
|
||||||
|
clock 100MHz;
|
||||||
|
//ahb
|
||||||
|
wire<32> addr;
|
||||||
|
wire<32> rdata;
|
||||||
|
wire<32> wdata;
|
||||||
|
wire<3> size;
|
||||||
|
wire write;
|
||||||
|
wired_or ready;
|
||||||
|
wired_or irq;
|
||||||
|
wired_or fiq;
|
||||||
|
wired_and nmreq;
|
||||||
|
wire --sel_mem;
|
||||||
|
wire sel_bridge;
|
||||||
|
wire sel_dmac;
|
||||||
|
wire busreq;
|
||||||
|
wire grant;
|
||||||
|
|
||||||
|
|
||||||
|
//gpio_port
|
||||||
|
wire --xp0;
|
||||||
|
wire --xp1;
|
||||||
|
wire --xp2;
|
||||||
|
wire --xp3;
|
||||||
|
wire --xp4;
|
||||||
|
wire --xp5;
|
||||||
|
wire --xp6;
|
||||||
|
wire --xp7;
|
||||||
|
|
||||||
|
|
||||||
|
// components --------------------------------------------
|
||||||
|
subcomponent Memory64KiB memorija(addr, rdata, wdata, size, write, ready, --sel_mem);
|
||||||
|
subcomponent ARM7tdmi arm(addr, rdata, wdata, size, write, ready, irq, fiq, nmreq, busreq, grant, *, *) uses memorija;
|
||||||
|
subcomponent Decoder decoder(addr, nmreq, --sel_mem, sel_bridge, sel_dmac, 1, 1);
|
||||||
|
|
||||||
|
display {
|
||||||
|
component { x: -473; y: -283; ref: "arm"; }
|
||||||
|
component { x: -433; y: 6; ref: "memorija"; }
|
||||||
|
component { x: -537; y: -202; ref: "decoder"; }
|
||||||
|
|
||||||
|
// ahb bus
|
||||||
|
|
||||||
|
rectangle {
|
||||||
|
x: -514; y: -86;
|
||||||
|
w: 249; h: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// gpio_port bus
|
||||||
|
|
||||||
|
|
||||||
|
line {x1:-428; y1:6; x2:-389; y2:-75;}
|
||||||
|
line {x1:-418; y1:-152; x2:-389; y2:-75;}
|
||||||
|
line {x1:-517; y1:-172; x2:-389; y2:-75;}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
@source "arm_library.csl"
|
||||||
|
|
||||||
|
@schema {
|
||||||
|
@instance arm ARM7tdmi {
|
||||||
|
@position (-473, -283)
|
||||||
|
@attribute _memory memorija
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance memorija Memory64KiB {
|
||||||
|
@position (-433, 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance decoder Decoder {
|
||||||
|
@position (-537, -202)
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance ahb AHB {
|
||||||
|
@position (-514, -86)
|
||||||
|
@size 249
|
||||||
|
}
|
||||||
|
|
||||||
|
@connection (memorija.ahbPin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (arm.ahbPin, ahb) {
|
||||||
|
}
|
||||||
|
@connection (decoder.ahbPin, ahb) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
@source "/home/bbr/Documents/Personal/FER/schema_editor/examples/simplified FRISC model/frisc_library.csl"
|
|
||||||
|
|
||||||
@schema {
|
|
||||||
@instance procesor FRISC {
|
|
||||||
@position (-177, -122)
|
|
||||||
@attribute _memory memorija2
|
|
||||||
}
|
|
||||||
|
|
||||||
@instance procesor FRISC {
|
|
||||||
@position (49, -97)
|
|
||||||
@attribute _memory null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
@source "/home/bbr/Documents/Personal/FER/schema_editor/examples/simplified FRISC model/frisc_library.csl"
|
|
||||||
|
|
||||||
@schema {
|
|
||||||
@instance procesor FRISC {
|
|
||||||
@position (-464, -314)
|
|
||||||
@attribute _memory null
|
|
||||||
}
|
|
||||||
|
|
||||||
@instance dma DMA {
|
|
||||||
@position (-269, 46)
|
|
||||||
@attribute pocetnaAdresa 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@instance glavnaSabirnica glavnaSabirnica {
|
|
||||||
@position (-579, -160)
|
|
||||||
@size 100
|
|
||||||
}
|
|
||||||
|
|
||||||
@instance PIOSabirnica PIOSabirnica {
|
|
||||||
@position (0, 0)
|
|
||||||
@size 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@connection (dma.glavniPin, glavnaSabirnica) {
|
|
||||||
@attribute interupt INT2
|
|
||||||
}
|
|
||||||
@connection (dma.glavniPin, PIOSabirnica, procesor.glavniPin) {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
@source "/home/bbr/Documents/Personal/FER/schema_editor/examples/simplified FRISC model/frisc_library.csl"
|
|
||||||
|
|
||||||
@schema {
|
|
||||||
@instance procesor FRISC {
|
|
||||||
@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 (-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,4 +1,4 @@
|
||||||
@source "/home/bbr/Documents/Personal/FER/schema_editor/examples/simplified FRISC model/frisc_library.csl"
|
@source "frisc_library.csl"
|
||||||
|
|
||||||
@schema {
|
@schema {
|
||||||
@instance procesor FRISC {
|
@instance procesor FRISC {
|
|
@ -3,6 +3,7 @@
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "comdel/display/dialog/error_dialog.h"
|
#include "comdel/display/dialog/error_dialog.h"
|
||||||
#include "comdel/display/dialog/success_dialog.h"
|
#include "comdel/display/dialog/success_dialog.h"
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
@ -30,10 +31,12 @@ void MainWindow::setupUi()
|
||||||
ui->centralwidget->setLayout(layout);
|
ui->centralwidget->setLayout(layout);
|
||||||
|
|
||||||
// setup toolbar
|
// setup toolbar
|
||||||
ui->toolBar->addAction("Učitaj bibiloteku", this, &MainWindow::onLoadLibrary);
|
loadLibrary = ui->toolBar->addAction(QMESSAGE("msg_toolbar_load_library"), this, &MainWindow::onLoadLibrary);
|
||||||
ui->toolBar->addAction("Učitaj shemu", this, &MainWindow::onLoadSchema);
|
loadSchema = ui->toolBar->addAction(QMESSAGE("msg_toolbar_load_schema"), this, &MainWindow::onLoadSchema);
|
||||||
ui->toolBar->addAction("Spremi shemu", this, &MainWindow::onStoreScheme);
|
saveSchema = ui->toolBar->addAction(QMESSAGE("msg_toolbar_save_schema"), this, &MainWindow::onStoreScheme);
|
||||||
ui->toolBar->addAction("Generiraj comdel", this, &MainWindow::onGenerateComdel);
|
generateComdel = ui->toolBar->addAction(QMESSAGE("msg_toolbar_generate_comdel"), this, &MainWindow::onGenerateComdel);
|
||||||
|
|
||||||
|
updateTranslations();
|
||||||
|
|
||||||
connect(ui->actionSave_schema, &QAction::triggered, this, &MainWindow::onStoreScheme);
|
connect(ui->actionSave_schema, &QAction::triggered, this, &MainWindow::onStoreScheme);
|
||||||
connect(ui->actionExport_schema, &QAction::triggered, this, &MainWindow::onGenerateComdel);
|
connect(ui->actionExport_schema, &QAction::triggered, this, &MainWindow::onGenerateComdel);
|
||||||
|
@ -57,7 +60,9 @@ void MainWindow::setupUi()
|
||||||
|
|
||||||
void MainWindow::onLoadLibrary() {
|
void MainWindow::onLoadLibrary() {
|
||||||
auto filename = QFileDialog::getOpenFileName(this,
|
auto filename = QFileDialog::getOpenFileName(this,
|
||||||
tr("Otvori biblioteku"), "", tr("Comdel biblioteka (*.csl)"));
|
QMESSAGE("msg_files_load_library"),
|
||||||
|
"",
|
||||||
|
QMESSAGE("msg_files_load_library_format"));
|
||||||
if(!filename.isEmpty()) {
|
if(!filename.isEmpty()) {
|
||||||
std::ostringstream output;
|
std::ostringstream output;
|
||||||
|
|
||||||
|
@ -67,6 +72,9 @@ void MainWindow::onLoadLibrary() {
|
||||||
if(!instance->loadLibrary(librarySource, output)) {
|
if(!instance->loadLibrary(librarySource, output)) {
|
||||||
auto dialog = new display::ErrorDialog(output);
|
auto dialog = new display::ErrorDialog(output);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
|
} else {
|
||||||
|
MessageSource::instance()->load(Application::instance()->getLibrary()->getMessages());
|
||||||
|
updateTranslations();
|
||||||
}
|
}
|
||||||
|
|
||||||
libraryDisplay->refreshContent();
|
libraryDisplay->refreshContent();
|
||||||
|
@ -76,7 +84,9 @@ void MainWindow::onLoadLibrary() {
|
||||||
|
|
||||||
void MainWindow::onLoadSchema() {
|
void MainWindow::onLoadSchema() {
|
||||||
auto filename = QFileDialog::getOpenFileName(this,
|
auto filename = QFileDialog::getOpenFileName(this,
|
||||||
tr("Otvori shemu"), "", tr("Comdel shema (*.csl)"));
|
QMESSAGE("msg_files_load_schema"),
|
||||||
|
"",
|
||||||
|
QMESSAGE("msg_files_load_schema_format"));
|
||||||
if(!filename.isEmpty()) {
|
if(!filename.isEmpty()) {
|
||||||
std::ostringstream output;
|
std::ostringstream output;
|
||||||
|
|
||||||
|
@ -88,6 +98,9 @@ void MainWindow::onLoadSchema() {
|
||||||
formatErrors(result.second, output);
|
formatErrors(result.second, output);
|
||||||
auto dialog = new display::ErrorDialog(output);
|
auto dialog = new display::ErrorDialog(output);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
|
} else {
|
||||||
|
MessageSource::instance()->load(Application::instance()->getLibrary()->getMessages());
|
||||||
|
updateTranslations();
|
||||||
}
|
}
|
||||||
|
|
||||||
libraryDisplay->refreshContent();
|
libraryDisplay->refreshContent();
|
||||||
|
@ -97,7 +110,9 @@ void MainWindow::onLoadSchema() {
|
||||||
|
|
||||||
void MainWindow::onStoreScheme() {
|
void MainWindow::onStoreScheme() {
|
||||||
auto filename = QFileDialog::getSaveFileName(this,
|
auto filename = QFileDialog::getSaveFileName(this,
|
||||||
tr("Spremi shemu"), "", tr("Comdel shema (*.csl)"));
|
QMESSAGE("msg_files_store_schema"),
|
||||||
|
"",
|
||||||
|
QMESSAGE("msg_files_store_schema_format"));
|
||||||
if(!filename.isEmpty()) {
|
if(!filename.isEmpty()) {
|
||||||
std::ostringstream output;
|
std::ostringstream output;
|
||||||
|
|
||||||
|
@ -106,7 +121,7 @@ void MainWindow::onStoreScheme() {
|
||||||
out<<output.str();
|
out<<output.str();
|
||||||
out.close();
|
out.close();
|
||||||
|
|
||||||
auto dialog = new display::SuccessDialog("Uspješno spremljena shema");
|
auto dialog = new display::SuccessDialog(MESSAGE("msg_dialog_success_save_schema"));
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
} else {
|
} else {
|
||||||
auto dialog = new display::ErrorDialog(output);
|
auto dialog = new display::ErrorDialog(output);
|
||||||
|
@ -118,24 +133,26 @@ void MainWindow::onStoreScheme() {
|
||||||
|
|
||||||
void MainWindow::onGenerateComdel() {
|
void MainWindow::onGenerateComdel() {
|
||||||
auto filename = QFileDialog::getSaveFileName(this,
|
auto filename = QFileDialog::getSaveFileName(this,
|
||||||
tr("Spremi shemu"), "", tr("Comdel sustav (*.system)"));
|
QMESSAGE("msg_files_store_comdel"),
|
||||||
|
"",
|
||||||
|
QMESSAGE("msg_files_store_comdel_format"));
|
||||||
if(!filename.isEmpty()) {
|
if(!filename.isEmpty()) {
|
||||||
std::ostringstream output;
|
std::ostringstream output;
|
||||||
|
|
||||||
auto validationErrors = Application::instance()->generateComdel(output);
|
auto validationErrors = Application::instance()->generateComdel(output);
|
||||||
|
|
||||||
std::ostringstream buff;
|
std::ostringstream errorOutput;
|
||||||
formatErrors(validationErrors, buff);
|
formatErrors(validationErrors, errorOutput);
|
||||||
|
|
||||||
if(!Application::hasErrors(validationErrors)) {
|
if(!Application::hasErrors(validationErrors)) {
|
||||||
std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary);
|
std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary);
|
||||||
out<<output.str();
|
out<<output.str();
|
||||||
out.close();
|
out.close();
|
||||||
|
|
||||||
auto dialog = new display::SuccessDialog("Uspješno generiran comdel model");
|
auto dialog = new display::SuccessDialog(MESSAGE("msg_dialog_success_comdel_generation"));
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
} else {
|
} else {
|
||||||
auto dialog = new display::ErrorDialog(output);
|
auto dialog = new display::ErrorDialog(errorOutput);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +169,7 @@ void MainWindow::onValidateSchema(bool /*toggled*/) {
|
||||||
auto dialog = new display::ErrorDialog(buff);
|
auto dialog = new display::ErrorDialog(buff);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
} else {
|
} else {
|
||||||
auto dialog = new display::SuccessDialog("Nema validacijskih greški");
|
auto dialog = new display::SuccessDialog(MESSAGE("msg_dialog_success_validation"));
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,3 +195,10 @@ MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateTranslations() {
|
||||||
|
loadLibrary->setText(QMESSAGE("msg_toolbar_load_library"));
|
||||||
|
loadSchema->setText(QMESSAGE("msg_toolbar_load_schema"));
|
||||||
|
saveSchema->setText(QMESSAGE("msg_toolbar_save_schema"));
|
||||||
|
generateComdel->setText(QMESSAGE("msg_toolbar_generate_comdel"));
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,13 @@ private:
|
||||||
display::Schema *schemaDisplay;
|
display::Schema *schemaDisplay;
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
|
QAction* loadLibrary;
|
||||||
|
QAction* loadSchema;
|
||||||
|
QAction* saveSchema;
|
||||||
|
QAction* generateComdel;
|
||||||
|
|
||||||
static void formatErrors(std::vector<domain::ValidationError>& errors, std::ostream& output);
|
static void formatErrors(std::vector<domain::ValidationError>& errors, std::ostream& output);
|
||||||
|
|
||||||
|
void updateTranslations();
|
||||||
};
|
};
|
||||||
#endif // MAIN_WINDOW_H
|
#endif // MAIN_WINDOW_H
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
//
|
||||||
|
// Created by bbr on 14.06.22..
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "message_source.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
// static instance of application
|
||||||
|
static MessageSource *messageSource = nullptr;
|
||||||
|
|
||||||
|
MessageSource *MessageSource::instance() {
|
||||||
|
if (messageSource == nullptr) {
|
||||||
|
messageSource = new MessageSource();
|
||||||
|
}
|
||||||
|
return messageSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageSource::loadDefaults() {
|
||||||
|
messages.clear();
|
||||||
|
|
||||||
|
// TOOLBAR
|
||||||
|
add("msg_toolbar_load_library", "Load library");
|
||||||
|
add("msg_toolbar_load_schema", "Load schema");
|
||||||
|
add("msg_toolbar_save_schema", "Save schema");
|
||||||
|
add("msg_toolbar_generate_comdel", "Generate comdel");
|
||||||
|
|
||||||
|
// SIDEBAR
|
||||||
|
add("msg_sidebar_components", "Components:");
|
||||||
|
add("msg_sidebar_busses", "Busses:");
|
||||||
|
|
||||||
|
// VALUES
|
||||||
|
add("msg_boolean_true", "True");
|
||||||
|
add("msg_boolean_false", "False");
|
||||||
|
|
||||||
|
// SUCCESS MESSAGES
|
||||||
|
add("msg_dialog_success_title", "Success");
|
||||||
|
add("msg_dialog_success_validation", "No validation errors found!");
|
||||||
|
add("msg_dialog_success_comdel_generation", "Successfully generate COMDEL model!");
|
||||||
|
add("msg_dialog_success_save_schema", "Successfully saved schema");
|
||||||
|
|
||||||
|
// DEFAULT ACTIONS
|
||||||
|
add("msg_dialog_actions_ok", "Ok");
|
||||||
|
add("msg_dialog_actions_cancel", "Cancel");
|
||||||
|
add("msg_dialog_actions_set", "Set");
|
||||||
|
add("msg_dialog_actions_update", "Update");
|
||||||
|
add("msg_dialog_actions_update_named", "Update {name}");
|
||||||
|
add("msg_dialog_actions_remove_named", "Remove {name}");
|
||||||
|
// PIN DIALOG
|
||||||
|
add("msg_pin_update", "Update");
|
||||||
|
add("msg_pin_remove", "Remove");
|
||||||
|
add("msg_sa_pin_update_title", "Update {wire1} - {wire2}");
|
||||||
|
add("msg_sa_pin_remove_title", "Remove {wire1} - {wire2}");
|
||||||
|
add("msg_pin_update_action", "Update connection");
|
||||||
|
add("msg_pin_remove_action", "Remove connection");
|
||||||
|
// ERROR DIALOG
|
||||||
|
add("msg_dialog_error_title", "Error");
|
||||||
|
add("msg_dialog_error_close", "Close");
|
||||||
|
// WARNING DIALOG
|
||||||
|
add("msg_dialog_warning_title", "Warning");
|
||||||
|
// ATTRIBUTE DIALOG/ACTION
|
||||||
|
add("msg_dialog_attribute_update", "Update {attribute}");
|
||||||
|
add("msg_dialog_attribute_set", "Set {attribute}");
|
||||||
|
// NAME DIALOG
|
||||||
|
add("msg_dialog_name_update", "Update name");
|
||||||
|
// MEMORY DIALOG/ACTION
|
||||||
|
add("msg_dialog_memory_update", "Update memory");
|
||||||
|
add("msg_dialog_memory_set", "Set memory");
|
||||||
|
add("msg_dialog_memory_default", "No memory selected");
|
||||||
|
// CONNECTION
|
||||||
|
add("msg_dialog_sa_pin_set", "Set wire");
|
||||||
|
// VALIDATORS
|
||||||
|
add("msg_validators_component_min_count", "Missing instances of component {componentName}. Required at least {min}, found {count}!");
|
||||||
|
add("msg_validators_component_max_count", "Too many instances of component {componentname}. Expected at most {max}, found {count}!");
|
||||||
|
add("msg_validators_bus_min_count", "Missing instances of bus {busName}. Required at least {min}, found {count}!");
|
||||||
|
add("msg_validators_bus_max_count", "Too many instances of bus {busName}. Expected at most {max}, found {count}!");
|
||||||
|
add("msg_validators_memory_not_found", "Cannot find memory instance {memoryReference}");
|
||||||
|
add("msg_validators_duplicates_found", "Found multiple instances with name {instanceName}");
|
||||||
|
|
||||||
|
// LOADING/SAVING DIALOGS
|
||||||
|
add("msg_files_load_library", "Open library");
|
||||||
|
add("msg_files_load_library_format", "COMDEL library (*.csl)");
|
||||||
|
add("msg_files_load_schema", "Open schema");
|
||||||
|
add("msg_files_load_schema_format", "COMDEL schema (*.csch)");
|
||||||
|
add("msg_files_store_schema", "Store schema");
|
||||||
|
add("msg_files_store_schema_format", "COMDEL schema (*.csch)");
|
||||||
|
add("msg_files_store_comdel", "Store COMDEL system");
|
||||||
|
add("msg_files_store_comdel_format", "COMDEL system (*.system)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageSource::add(const std::string& key, std::string message) {
|
||||||
|
messages[key] = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MessageSource::get(const std::string& key, std::map<std::string, std::string> parametars) {
|
||||||
|
std::string message;
|
||||||
|
if(messages.count(key) == 1) {
|
||||||
|
// if key not found in translations use key as message
|
||||||
|
message = messages[key];
|
||||||
|
} else {
|
||||||
|
message = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
message = populateMessage(message, parametars);
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MessageSource::get(const std::string &key) {
|
||||||
|
return get(key, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MessageSource::populateMessage(std::string message, std::map<std::string, std::string> parametars) {
|
||||||
|
for (auto &[key, value]: parametars) {
|
||||||
|
message = replacePlaceholder(message, key, value);
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MessageSource::replacePlaceholder(std::string message, const std::string key, std::string value) {
|
||||||
|
auto wholeKey = "{" + key + "}";
|
||||||
|
|
||||||
|
auto found = message.find(wholeKey);
|
||||||
|
while (found != std::string::npos) {
|
||||||
|
message.replace(found, wholeKey.length(), value);
|
||||||
|
found = message.find(key);
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageSource::load(std::map<std::string, std::string> _messages) {
|
||||||
|
loadDefaults();
|
||||||
|
for (auto &[key, value]: _messages) {
|
||||||
|
messages[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> MessageSource::map(std::map<std::string, domain::Value> values) {
|
||||||
|
std::map<std::string, std::string> parametars;
|
||||||
|
for (auto &[key, value]: values) {
|
||||||
|
parametars[key] = value.string();
|
||||||
|
}
|
||||||
|
return parametars;
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// Created by bbr on 14.06.22..
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SCHEMEEDITOR_MESSAGE_SOURCE_H
|
||||||
|
#define SCHEMEEDITOR_MESSAGE_SOURCE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include "comdel/domain/value.h"
|
||||||
|
|
||||||
|
class MessageSource {
|
||||||
|
private:
|
||||||
|
MessageSource() {
|
||||||
|
loadDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(const std::string& key, std::string message);
|
||||||
|
std::string populateMessage(std::string message, std::map<std::string, std::string> parametars);
|
||||||
|
std::string replacePlaceholder(std::string message, std::string key, std::string value);
|
||||||
|
|
||||||
|
std::map<std::string, std::string> messages;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static MessageSource *instance();
|
||||||
|
static std::map<std::string, std::string> map(std::map<std::string, domain::Value> values);
|
||||||
|
|
||||||
|
std::string get(const std::string& key);
|
||||||
|
std::string get(const std::string& key, std::map<std::string, std::string> parametars);
|
||||||
|
|
||||||
|
void loadDefaults();
|
||||||
|
void load(std::map<std::string, std::string> messages);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MESSAGE_PARAM(key, params) MessageSource::instance()->get(key, params)
|
||||||
|
#define MESSAGE(key) MessageSource::instance()->get(key)
|
||||||
|
#define MESSAGE_MAP(value) MessageSource::instance()->map(value)
|
||||||
|
|
||||||
|
#define QMESSAGE_PARAM(key, params) QString::fromStdString(MessageSource::instance()->get(key, params))
|
||||||
|
#define QMESSAGE(key) QString::fromStdString(MessageSource::instance()->get(key))
|
||||||
|
|
||||||
|
#endif //SCHEMEEDITOR_MESSAGE_SOURCE_H
|
Loading…
Reference in New Issue