#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); setupUi(); // define allowed methods signatures = domain::getSupportedFunctions(); } void MainWindow::setupUi() { setWindowTitle("COMDEL schema editor"); auto layout = new QHBoxLayout(); ui->centralwidget->setLayout(layout); // setup toolbar ui->toolBar->addAction("Load library", this, &MainWindow::onLoadLibrary); ui->toolBar->addAction("Load schema", this, &MainWindow::onLoadSchema); ui->toolBar->addAction("Save schema", this, &MainWindow::onStoreScheme); connect(ui->actionValidate, &QAction::triggered, this, &MainWindow::onValidateSchema); // setup central content libraryDisplay = new display::Library(); auto schemaParent = new QWidget(); auto schemaLayout = new QVBoxLayout(); schemaParent->setLayout(schemaLayout); schemaDisplay = new display::Schema(); schemaLayout->setMargin(0); schemaLayout->addWidget(schemaDisplay, 1); layout->setMargin(0); layout->addWidget(libraryDisplay); layout->addWidget(schemaParent, 1); log = new QPlainTextEdit(); log->setFont(QFont("Courier")); log->setReadOnly(false); schemaLayout->addWidget(log); } void MainWindow::onLoadLibrary() { auto filename = QFileDialog::getOpenFileName(this, tr("Open library"), "/home", tr("Comdel library (*.csl)")); std::ostringstream buffer; log->clear(); if(!filename.isEmpty()) { librarySource = filename.toStdString(); clear(); ParseContext parseContext; auto libraryNode = loadLibraryFromFile(&parseContext, filename.toStdString().c_str(), buffer); if(libraryNode) { domain::SchemaCreator generator(signatures); library = generator.loadLibrary(*libraryNode); for (auto& error : generator.getErrors()) { parseContext.formatError(error, buffer, "ERROR: "); } if(generator.getErrors().empty()) { libraryDisplay->setLibrary(library); // on library load we create a new schema schema = new domain::Schema(); schemaDisplay->setSchema(schema); } } else { buffer<<"Failed loading library"<appendPlainText(QString::fromStdString(buffer.str())); } void MainWindow::onLoadSchema() { auto filename = QFileDialog::getOpenFileName(this, tr("Open schema"), "/home", tr("Comdel schema (*.csl)")); std::ostringstream buffer; log->clear(); if(!filename.isEmpty()) { clear(); ParseContext parseContext; auto schemaNode = loadSchemaFromFile(&parseContext, filename.toStdString().c_str(), buffer); if(schemaNode) { domain::SchemaCreator generator(signatures); library = generator.loadLibrary(*schemaNode->library); librarySource = schemaNode->source->value; for (auto& error : generator.getErrors()) { parseContext.formatError(error, buffer, "ERROR: "); } if(library) { schema = generator.loadSchema(*schemaNode, *library); for (auto& error : generator.getErrors()) { parseContext.formatError(error, buffer, "ERROR: "); } } if(generator.getErrors().empty()) { libraryDisplay->setLibrary(library); schemaDisplay->setSchema(schema); } } } log->appendPlainText(QString::fromStdString(buffer.str())); } void MainWindow::onStoreScheme() { if(schema == nullptr) { return; } auto filename = QFileDialog::getSaveFileName(this, tr("Save schema"), "/home", tr("Comdel schema (*.csl)")); std::ostringstream buffer; buffer << "@source " << this->librarySource << std::endl << std::endl; buffer << "@schema {" << std::endl; for(auto &instance: schema->instances) { auto componentInstance = dynamic_cast(instance); if(componentInstance != nullptr) { buffer << "\t" << "@instance " << componentInstance->name << " " << componentInstance->component.getName() << " {" << std::endl; buffer << "\t\t" << "@position (" << componentInstance->position.first << ", " << componentInstance->position.second << ")" << std::endl; for(auto &attribute: instance->attributes) { buffer << "\t\t" << "@attribute " << attribute->name << " " << attribute->value.stringify() << std::endl; } buffer << "\t}" << std::endl << std::endl; } auto busInstance = dynamic_cast(instance); if(busInstance != nullptr) { buffer << "\t" << "@instance " << busInstance->name << " " << busInstance->bus.getName() << " {" << std::endl; buffer << "\t\t" << "@position (" << busInstance->position.first << ", " << busInstance->position.second << ")" << std::endl; buffer << "\t\t" << "@size " << busInstance->size << std::endl; buffer << "\t}" << std::endl << std::endl; } } for(auto &wire: schema->wires) { buffer << "\t" << "@wire " << wire->name << " {" << std::endl; buffer << "\t\t" << "@position (" << wire->position.first << ", " << wire->position.second << ")" << std::endl; buffer << "\t\t" << "@display {}" << std::endl; buffer << "\t" << "}" << std::endl; } for(auto &conn: schema->connections) { auto busConn = dynamic_cast(conn); if(busConn) { buffer << "\t" << "@connection (" << busConn->instance->name << "." << busConn->connection.getComponent().pin << ", " << busConn->bus->name << ") {" << std::endl; buffer << "\t\t"<< "@wire " << busConn->wire->name << std::endl; buffer << "\t" << "}" << std::endl; } } buffer << "}" << std::endl; auto value = buffer.str(); std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary); out<validationErrors.clear(); std::map callbacks; auto functions = domain::getSupportedFunctions(); for(auto &func: functions) { callbacks[func.name] = func.callback; } domain::ComdelValidator validator{callbacks}; domain::ValidationContext context; context.instance = nullptr; context.attribute = nullptr; context.addressSpaces = {}; for(auto &lib: library->getAddressSpaces()) { context.addressSpaces.insert(std::make_pair(lib.getName(), lib)); } auto errors = validator.validateSchema(*schema, context); errors.erase(std::remove_if( errors.begin(), errors.end(), [](const domain::ValidationError& error) { return error.type == domain::Action::WARNING;}), errors.end()); std::ostringstream buff; for(auto err: errors) { if(err.instance != nullptr) { buff << err.instance->name; } if(err.attribute != nullptr) { buff << "::" << err.attribute->name; } if(err.type == domain::Action::ERROR) { buff << " [ERROR] "; } else { buff << " [WARNING] "; } buff << err.message << std::endl; } log->appendPlainText(QString::fromStdString(buff.str())); validationErrors = errors; } void MainWindow::clear() { validationErrors.clear(); schema = nullptr; library = std::nullopt; libraryDisplay->setLibrary(library); schemaDisplay->setSchema(schema); } MainWindow::~MainWindow() { delete ui; }