#include "mainwindow.h" #include "./ui_mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "xlsxcellrange.h" #include "xlsxchart.h" #include "xlsxchartsheet.h" #include "xlsxdocument.h" #include "xlsxrichstring.h" #include "xlsxworkbook.h" using namespace QXlsx; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); setWindowTitle("XNSim IDL Generator"); setWindowIcon(QIcon(":/icon/XNIDLGen.png")); //菜单栏 QMenu *fileMenu = menuBar()->addMenu(tr("&File")); QAction *openAction = new QAction(tr("&Open"), this); QAction *closeAction = new QAction(tr("&Close"), this); fileMenu->addAction(openAction); fileMenu->addAction(closeAction); QMenu *operationMenu = menuBar()->addMenu(tr("&Operation")); QAction *generateAction = new QAction(tr("Generate &IDL"), this); QAction *generatePrjAction = new QAction(tr("Generate &DDS Project"), this); operationMenu->addAction(generateAction); operationMenu->addAction(generatePrjAction); connect(openAction, &QAction::triggered, this, &MainWindow::openFile); connect(closeAction, &QAction::triggered, this, &MainWindow::closeFile); connect(generateAction, &QAction::triggered, this, &MainWindow::generate); connect(generatePrjAction, &QAction::triggered, this, &MainWindow::generatePrj); //主界面 QGroupBox *namespaceGroupBox = new QGroupBox(tr("Namespace"), this); QGridLayout *namespaceGroupBoxLayout = new QGridLayout(); namespaceGroupBox->setLayout(namespaceGroupBoxLayout); QLabel *firstNamespaceLabel = new QLabel(tr("First Namespace:"), namespaceGroupBox); QLabel *secondNamespaceLabel = new QLabel(tr("Second Namespace:"), namespaceGroupBox); QLabel *thirdNamespaceLabel = new QLabel(tr("Third Namespace:"), namespaceGroupBox); QLabel *modelNameLabel = new QLabel(tr("Model Name:"), namespaceGroupBox); QLineEdit *firstNamespaceLineEdit = new QLineEdit(namespaceGroupBox); firstNamespaceLineEdit->setText("XNSim"); firstNamespaceLineEdit->setReadOnly(true); firstNamespaceLineEdit->setObjectName("firstNamespaceLineEdit"); QLineEdit *secondNamespaceLineEdit = new QLineEdit(namespaceGroupBox); secondNamespaceLineEdit->setObjectName("secondNamespaceLineEdit"); QLineEdit *thirdNamespaceLineEdit = new QLineEdit(namespaceGroupBox); thirdNamespaceLineEdit->setObjectName("thirdNamespaceLineEdit"); QLineEdit *modelNameLineEdit = new QLineEdit(namespaceGroupBox); modelNameLineEdit->setObjectName("modelNameLineEdit"); namespaceGroupBoxLayout->addWidget(firstNamespaceLabel, 0, 0); namespaceGroupBoxLayout->addWidget(firstNamespaceLineEdit, 0, 1); namespaceGroupBoxLayout->addWidget(secondNamespaceLabel, 0, 2); namespaceGroupBoxLayout->addWidget(secondNamespaceLineEdit, 0, 3); namespaceGroupBoxLayout->addWidget(thirdNamespaceLabel, 1, 0); namespaceGroupBoxLayout->addWidget(thirdNamespaceLineEdit, 1, 1); namespaceGroupBoxLayout->addWidget(modelNameLabel, 1, 2); namespaceGroupBoxLayout->addWidget(modelNameLineEdit, 1, 3); QGroupBox *groupBox = new QGroupBox(tr("File Preview"), this); groupBox->setObjectName("groupBox"); QTabWidget *tabWidget = new QTabWidget(groupBox); tabWidget->setObjectName("tabWidget"); QWidget *tab1 = new QWidget(); QTableWidget *table1 = new QTableWidget(10, 3, tab1); // 10 rows, 5 columns table1->setObjectName("table1"); QStringList headers; headers << "name" << "type" << "size"; table1->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); table1->setHorizontalHeaderLabels(headers); QVBoxLayout *tab1Layout = new QVBoxLayout(); tab1Layout->addWidget(table1); tab1->setLayout(tab1Layout); QWidget *tab2 = new QWidget(); QTableWidget *table2 = new QTableWidget(10, 3, tab2); // 10 rows, 5 columns table2->setObjectName("table2"); table2->setHorizontalHeaderLabels(headers); table2->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); QVBoxLayout *tab2Layout = new QVBoxLayout(); tab2Layout->addWidget(table2); tab2->setLayout(tab2Layout); tabWidget->addTab(tab1, tr("Inputs")); tabWidget->addTab(tab2, tr("Outputs")); QVBoxLayout *groupBoxLayout = new QVBoxLayout(); groupBoxLayout->addWidget(tabWidget); groupBox->setLayout(groupBoxLayout); QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->setContentsMargins( 10, 10, 10, 10); // Add margins to create space between the menu bar and central widget mainLayout->addWidget(namespaceGroupBox); mainLayout->addWidget(groupBox); centralWidget()->setLayout(mainLayout); centralWidget()->setEnabled(false); } MainWindow::~MainWindow() { delete ui; } void MainWindow::openFile() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("ICD file (*.xlsx)")); if (fileName.isEmpty()) return; QXlsx::Document xlsx(fileName); if (xlsx.load()) { setWindowTitle("XNSim IDL Generator - " + fileName); QStringList sheetNames = xlsx.sheetNames(); for (const QString &sheetName : sheetNames) { if (sheetName == "Inputs") { xlsx.selectSheet(sheetName); QTableWidget *table1 = findChild("table1"); table1->setRowCount(xlsx.dimension().rowCount() - 1); for (int col = 1; col <= xlsx.dimension().columnCount(); ++col) { QString columnName = xlsx.read(1, col).toString(); if (columnName == "SACSC name" || columnName == "SACSC Name" || columnName == "NameSACSC") { for (int row = 2; row <= xlsx.dimension().rowCount(); ++row) { QString value = xlsx.read(row, col).toString(); if (value.isEmpty()) { continue; } value = value.toLower(); table1->setItem(row - 2, 0, new QTableWidgetItem(value)); } } else if (columnName == "Variable Type") { for (int row = 2; row <= xlsx.dimension().rowCount(); ++row) { QString value = xlsx.read(row, col).toString(); if (value.isEmpty()) { continue; } table1->setItem(row - 2, 1, new QTableWidgetItem(value)); } } else if (columnName == "Variable Dimensions") { for (int row = 2; row <= xlsx.dimension().rowCount(); ++row) { QString value = xlsx.read(row, col).toString(); if (value.isEmpty()) { continue; } if (!value.contains("[") && value.toInt() > 1) { value = "[" + value + "]"; } table1->setItem(row - 2, 2, new QTableWidgetItem(value)); } } else { continue; } } } else if (sheetName == "Outputs") { xlsx.selectSheet(sheetName); QTableWidget *table2 = findChild("table2"); table2->setRowCount(xlsx.dimension().rowCount() - 1); for (int col = 1; col <= xlsx.dimension().columnCount(); ++col) { QString columnName = xlsx.read(1, col).toString(); if (columnName == "SACSC name" || columnName == "SACSC Name" || columnName == "NameSACSC") { for (int row = 2; row <= xlsx.dimension().rowCount(); ++row) { QString value = xlsx.read(row, col).toString(); if (value.isEmpty()) { continue; } value = value.toLower(); table2->setItem(row - 2, 0, new QTableWidgetItem(value)); } } else if (columnName == "Variable Type") { for (int row = 2; row <= xlsx.dimension().rowCount(); ++row) { QString value = xlsx.read(row, col).toString(); if (value.isEmpty()) { continue; } table2->setItem(row - 2, 1, new QTableWidgetItem(value)); } } else if (columnName == "Variable Dimensions") { for (int row = 2; row <= xlsx.dimension().rowCount(); ++row) { QString value = xlsx.read(row, col).toString(); if (value.isEmpty()) { continue; } if (!value.contains("[") && value.toInt() > 1) { value = "[" + value + "]"; } table2->setItem(row - 2, 2, new QTableWidgetItem(value)); } } else { continue; } } } else { continue; } } } centralWidget()->setEnabled(true); } void MainWindow::closeFile() { QTableWidget *table1 = findChild("table1"); QTableWidget *table2 = findChild("table2"); table1->clear(); table2->clear(); table1->setRowCount(0); table2->setRowCount(0); centralWidget()->setEnabled(false); } void MainWindow::generate() { QLineEdit *modelNameLineEdit = findChild("modelNameLineEdit"); if (!modelNameLineEdit || modelNameLineEdit->text().isEmpty()) { QMessageBox::warning(this, tr("Error"), tr("Model name is empty")); return; } QString modelName = modelNameLineEdit->text(); QString defaultFileName = modelName + ".idl"; QString filePath = QFileDialog::getSaveFileName(this, tr("Save File"), QDir::currentPath() + "/" + defaultFileName, tr("IDL Files (*.idl)")); if (filePath.isEmpty()) { return; } if (!filePath.endsWith(".idl", Qt::CaseInsensitive)) { filePath += ".idl"; } QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { return; } QTextStream out(&file); QLineEdit *firstNamespaceLineEdit = findChild("firstNamespaceLineEdit"); QLineEdit *secondNamespaceLineEdit = findChild("secondNamespaceLineEdit"); QLineEdit *thirdNamespaceLineEdit = findChild("thirdNamespaceLineEdit"); if (firstNamespaceLineEdit) { out << "module " << firstNamespaceLineEdit->text() << "\n"; out << "{\n"; if (secondNamespaceLineEdit && !secondNamespaceLineEdit->text().isEmpty()) { out << "\tmodule " << secondNamespaceLineEdit->text() << "\n"; out << "\t{\n"; if (thirdNamespaceLineEdit && !thirdNamespaceLineEdit->text().isEmpty()) { out << "\t\tmodule " << thirdNamespaceLineEdit->text() << "\n"; out << "\t\t{\n"; genInput(modelName, "\t\t\t", out); genOutput(modelName, "\t\t\t", out); out << "\t\t};\n"; } else { genInput(modelName, "\t\t", out); genOutput(modelName, "\t\t", out); } out << "\t};\n"; } else { genInput(modelName, "\t", out); genOutput(modelName, "\t", out); } out << "};\n"; } file.close(); } void MainWindow::generatePrj() { QFileDialog fileDialog(this); fileDialog.setNameFilter(tr("IDL Files (*.idl)")); fileDialog.setViewMode(QFileDialog::Detail); QString idlFilePath; if (fileDialog.exec()) { idlFilePath = fileDialog.selectedFiles().first(); } if (idlFilePath.isEmpty()) { return; } QString savePath = QFileDialog::getExistingDirectory(this, tr("Select Save Directory"), QString(), QFileDialog::ShowDirsOnly); if (savePath.isEmpty()) { return; } QDir dir(savePath); savePath = dir.absolutePath(); QProcess process; QStringList arguments = QStringList() << "-flat-output-dir" << "-replace" << "-d" << savePath << idlFilePath; process.start("fastddsgen", arguments); process.waitForFinished(); QString output = process.readAllStandardOutput(); QMessageBox::information(this, tr("Generate DDS Project Result"), output); //TODO 生成Interface头文件和源文件 } QString MainWindow::typeChange(QString type) { if (type == "char" || type == "unsigned char") { return "char"; } else if (type == "short" || type == "unsigned short" || type == "long" || type == "unsigned long" || type == "long long" || type == "unsigned long long" || type == "float" || type == "double" || type == "long double" || type == "string") { return type; } else if (type == "int") { return "long"; } else if (type == "unsigned int") { return "unsigned long"; } else if (type == "bool") { return "boolean"; } else if (type == "std::string") { return "string"; } return "error"; } void MainWindow::genInput(QString name, QString prefix, QTextStream &out) { out << prefix << "struct " << name << "_input" << "\n"; out << prefix << "{\n"; QTableWidget *table1 = findChild("table1"); if (table1) { for (int row = 0; row < table1->rowCount(); ++row) { QString name = table1->item(row, 0)->text(); QString type = table1->item(row, 1)->text(); QString size = table1->item(row, 2)->text(); if (typeChange(type) == "error") { QMessageBox::warning(this, tr("Error"), name + tr("is unknown type!")); return; } if (size.isEmpty() || size == "1") { out << prefix << "\t" << "@optional " << typeChange(type) << " " << name << ";\n"; } else { out << prefix << "\t" << "@optional " << typeChange(type) << " " << name << size << ";\n"; } } } out << prefix << "};\n"; } void MainWindow::genOutput(QString name, QString prefix, QTextStream &out) { out << prefix << "struct " << name << "_output" << "\n"; out << prefix << "{\n"; QTableWidget *table2 = findChild("table2"); if (table2) { for (int row = 0; row < table2->rowCount(); ++row) { QString name = table2->item(row, 0)->text(); QString type = table2->item(row, 1)->text(); QString size = table2->item(row, 2)->text(); if (typeChange(type) == "error") { QMessageBox::warning(this, tr("Error"), name + tr("is unknown type!")); return; } if (size.isEmpty() || size == "1") { out << prefix << "\t" << "@optional " << typeChange(type) << " " << name << ";\n"; } else { out << prefix << "\t" << "@optional " << typeChange(type) << " " << name << size << ";\n"; } } } out << prefix << "};\n"; }